SCIOP_Transport.cpp

Go to the documentation of this file.
00001 // SCIOP_Transport.cpp,v 1.15 2006/04/20 12:37:17 jwillemsen Exp
00002 
00003 #include "tao/Strategies/SCIOP_Transport.h"
00004 
00005 #if TAO_HAS_SCIOP == 1
00006 
00007 #include "tao/Strategies/SCIOP_Connection_Handler.h"
00008 #include "tao/Strategies/SCIOP_Acceptor.h"
00009 #include "tao/Strategies/SCIOP_Profile.h"
00010 #include "tao/Acceptor_Registry.h"
00011 #include "tao/Thread_Lane_Resources.h"
00012 #include "tao/operation_details.h"
00013 #include "tao/Timeprobe.h"
00014 #include "tao/CDR.h"
00015 #include "tao/Transport_Mux_Strategy.h"
00016 #include "tao/Wait_Strategy.h"
00017 #include "tao/Stub.h"
00018 #include "tao/ORB_Core.h"
00019 #include "tao/debug.h"
00020 #include "tao/GIOP_Message_Base.h"
00021 #include "tao/Protocols_Hooks.h"
00022 #include "tao/Adapter.h"
00023 
00024 ACE_RCSID (tao,
00025            SCIOP_Transport,
00026            "SCIOP_Transport.cpp,v 1.15 2006/04/20 12:37:17 jwillemsen Exp")
00027 
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029 
00030 TAO_SCIOP_Transport::TAO_SCIOP_Transport (TAO_SCIOP_Connection_Handler *handler,
00031                                         TAO_ORB_Core *orb_core,
00032                                         CORBA::Boolean )
00033   : TAO_Transport (TAO_TAG_SCIOP_PROFILE,
00034                    orb_core)
00035   , connection_handler_ (handler)
00036   , messaging_object_ (0)
00037 {
00038 #if 0
00039   // First step in deprecating this.
00040   if (flag)
00041     {
00042       // Use the lite version of the protocol
00043       ACE_NEW (this->messaging_object_,
00044                TAO_GIOP_Message_Lite (orb_core));
00045     }
00046   else
00047 #endif /*if 0*/
00048     {
00049       // Use the normal GIOP object
00050       ACE_NEW (this->messaging_object_,
00051                TAO_GIOP_Message_Base (orb_core, this));
00052     }
00053 }
00054 
00055 TAO_SCIOP_Transport::~TAO_SCIOP_Transport (void)
00056 {
00057   delete this->messaging_object_;
00058 }
00059 
00060 ACE_Event_Handler *
00061 TAO_SCIOP_Transport::event_handler_i (void)
00062 {
00063   return this->connection_handler_;
00064 }
00065 
00066 TAO_Connection_Handler *
00067 TAO_SCIOP_Transport::connection_handler_i (void)
00068 {
00069   return this->connection_handler_;
00070 }
00071 
00072 TAO_Pluggable_Messaging *
00073 TAO_SCIOP_Transport::messaging_object (void)
00074 {
00075   return this->messaging_object_;
00076 }
00077 
00078 ssize_t
00079 TAO_SCIOP_Transport::send (iovec *iov, int iovcnt,
00080                            size_t &bytes_transferred,
00081                            const ACE_Time_Value *max_wait_time)
00082 {
00083   ssize_t retval = this->connection_handler_->peer ().sendv (iov, iovcnt,
00084                                                              max_wait_time);
00085   if (retval > 0)
00086     bytes_transferred = retval;
00087 
00088   return retval;
00089 }
00090 
00091 ssize_t
00092 TAO_SCIOP_Transport::recv (char *buf,
00093                            size_t len,
00094                            const ACE_Time_Value *max_wait_time)
00095 {
00096   ssize_t n = this->connection_handler_->peer ().recv (buf,
00097                                                        len,
00098                                                        max_wait_time);
00099 
00100   // Do not print the error message if it is a timeout, which could
00101   // occur in thread-per-connection.
00102   if (n == -1 &&
00103       TAO_debug_level > 4 &&
00104       errno != ETIME)
00105     {
00106       ACE_DEBUG ((LM_DEBUG,
00107                   ACE_TEXT ("TAO (%P|%t) - SCIOP_Transport[%d]::recv, ")
00108                   ACE_TEXT ("read failure - %m\n"),
00109                   this->id ()));
00110     }
00111 
00112   // Error handling
00113   if (n == -1)
00114     {
00115       if (errno == EWOULDBLOCK)
00116         return 0;
00117 
00118 
00119       return -1;
00120     }
00121 
00122   // Most of the errors handling is common for
00123   // Now the message has been read
00124 
00125   // @@ What are the other error handling here??
00126   else if (n == 0)
00127     {
00128       return -1;
00129     }
00130 
00131   return n;
00132 }
00133 
00134 int
00135 TAO_SCIOP_Transport::send_request (TAO_Stub *stub,
00136                                   TAO_ORB_Core *orb_core,
00137                                   TAO_OutputCDR &stream,
00138                                   int message_semantics,
00139                                   ACE_Time_Value *max_wait_time)
00140 {
00141   if (this->ws_->sending_request (orb_core,
00142                                   message_semantics) == -1)
00143 
00144     return -1;
00145 
00146   if (this->send_message (stream,
00147                           stub,
00148                           message_semantics,
00149                           max_wait_time) == -1)
00150     return -1;
00151 
00152   this->first_request_sent();
00153 
00154   return 0;
00155 }
00156 
00157 int
00158 TAO_SCIOP_Transport::send_message (TAO_OutputCDR &stream,
00159                                   TAO_Stub *stub,
00160                                   int message_semantics,
00161                                   ACE_Time_Value *max_wait_time)
00162 {
00163   // Format the message in the stream first
00164   if (this->messaging_object_->format_message (stream) != 0)
00165     return -1;
00166 
00167   // This guarantees to send all data (bytes) or return an error.
00168   ssize_t n = this->send_message_shared (stub,
00169                                          message_semantics,
00170                                          stream.begin (),
00171                                          max_wait_time);
00172 
00173   if (n == -1)
00174     {
00175       if (TAO_debug_level)
00176         ACE_DEBUG ((LM_DEBUG,
00177                     ACE_TEXT ("TAO (%P|%t) - SCIOP_Transport[%d]::send_message, ")
00178                     ACE_TEXT (" write failure - %m\n"),
00179                     this->id ()));
00180       return -1;
00181     }
00182 
00183   return 1;
00184 }
00185 
00186 int
00187 TAO_SCIOP_Transport::send_message_shared (TAO_Stub *stub,
00188                                          int message_semantics,
00189                                          const ACE_Message_Block *message_block,
00190                                          ACE_Time_Value *max_wait_time)
00191 {
00192   int r;
00193 
00194   {
00195     ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->handler_lock_, -1);
00196 
00197     r = this->send_message_shared_i (stub, message_semantics,
00198                                      message_block, max_wait_time);
00199   }
00200 
00201   if (r == -1)
00202     {
00203       this->close_connection ();
00204     }
00205 
00206   return r;
00207 }
00208 
00209 int
00210 TAO_SCIOP_Transport::generate_request_header (TAO_Operation_Details &opdetails,
00211                                              TAO_Target_Specification &spec,
00212                                              TAO_OutputCDR &msg)
00213 {
00214   // Check whether we have a Bi Dir SCIOP policy set, whether the
00215   // messaging objects are ready to handle bidirectional connections
00216   // and also make sure that we have not recd. or sent any information
00217   // regarding this before...
00218   if (this->orb_core ()->bidir_giop_policy () &&
00219       this->messaging_object_->is_ready_for_bidirectional (msg) &&
00220       this->bidirectional_flag () < 0)
00221     {
00222       this->set_bidir_context_info (opdetails);
00223 
00224       // Set the flag to 1  (i.e., originating side)
00225       this->bidirectional_flag (1);
00226 
00227       // At the moment we enable BiDIR giop we have to get a new
00228       // request id to make sure that we follow the even/odd rule
00229       // for request id's. We only need to do this when enabled
00230       // it, after that the Transport Mux Strategy will make sure
00231       // that the rule is followed
00232       opdetails.request_id (this->tms ()->request_id ());
00233     }
00234 
00235   return TAO_Transport::generate_request_header (opdetails,
00236                                                  spec,
00237                                                  msg);
00238 }
00239 
00240 int
00241 TAO_SCIOP_Transport::messaging_init (CORBA::Octet major,
00242                                     CORBA::Octet minor)
00243 {
00244   this->messaging_object_->init (major, minor);
00245 
00246   return 1;
00247 }
00248 
00249 int
00250 TAO_SCIOP_Transport::tear_listen_point_list (TAO_InputCDR &cdr)
00251 {
00252   CORBA::Boolean byte_order;
00253   if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00254     return -1;
00255 
00256   cdr.reset_byte_order (static_cast<int> (byte_order));
00257 
00258   IIOP::ListenPointList listen_list;
00259   if ((cdr >> listen_list) == 0)
00260     return -1;
00261 
00262   // As we have received a bidirectional information, set the flag to
00263   // 1 (i.e., non-originating side)
00264   this->bidirectional_flag (0);
00265 
00266   return this->connection_handler_->process_listen_point_list (listen_list);
00267 }
00268 
00269 void
00270 TAO_SCIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
00271 {
00272   // Get a handle to the acceptor registry
00273   TAO_Acceptor_Registry &ar =
00274     this->orb_core ()->lane_resources ().acceptor_registry ();
00275 
00276   // Get the first acceptor in the registry
00277   TAO_AcceptorSetIterator acceptor = ar.begin ();
00278 
00279   IIOP::ListenPointList listen_point_list;
00280 
00281   for (;
00282        acceptor != ar.end ();
00283        acceptor++)
00284     {
00285       // Check whether it is a SCIOP acceptor
00286       if ((*acceptor)->tag () == TAO_TAG_SCIOP_PROFILE)
00287         {
00288           if (this->get_listen_point (listen_point_list,
00289                                       *acceptor) == -1)
00290             {
00291               ACE_ERROR ((LM_ERROR,
00292                           "TAO (%P|%t) - SCIOP_Transport::set_bidir_info, "
00293                           "error getting listen_point \n"));
00294 
00295               return;
00296             }
00297         }
00298     }
00299 
00300   // We have the ListenPointList at this point. Create a output CDR
00301   // stream at this point
00302   TAO_OutputCDR cdr;
00303 
00304   // Marshall the information into the stream
00305   if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00306       || (cdr << listen_point_list) == 0)
00307     return;
00308 
00309   // Add this info in to the svc_list
00310   opdetails.request_service_context ().set_context (IOP::BI_DIR_IIOP,
00311                                                     cdr);
00312 
00313   return;
00314 }
00315 
00316 int
00317 TAO_SCIOP_Transport::get_listen_point (
00318     IIOP::ListenPointList &listen_point_list,
00319     TAO_Acceptor *acceptor)
00320 {
00321   TAO_SCIOP_Acceptor *sciop_acceptor =
00322     dynamic_cast<TAO_SCIOP_Acceptor *> (acceptor );
00323 
00324   // Get the array of endpoints serviced by TAO_SCIOP_Acceptor
00325   const ACE_INET_Addr *endpoint_addr =
00326     sciop_acceptor->endpoints ();
00327 
00328   // Get the endpoint count
00329   size_t count =
00330     sciop_acceptor->endpoint_count ();
00331 
00332   // Get the local address of the connection
00333   ACE_INET_Addr local_addr;
00334 
00335   if (this->connection_handler_->peer ().get_local_addr (local_addr)
00336       == -1)
00337     {
00338       ACE_ERROR_RETURN ((LM_ERROR,
00339                          ACE_TEXT ("(%P|%t) Could not resolve local ")
00340                          ACE_TEXT ("host address in ")
00341                          ACE_TEXT ("get_listen_point()\n")),
00342                         -1);
00343     }
00344 
00345   // Note: Looks like there is no point in sending the list of
00346   // endpoints on interfaces on which this connection has not
00347   // been established. If this is wrong, please correct me.
00348   CORBA::String_var local_interface;
00349 
00350   // Get the hostname for the local address
00351   if (sciop_acceptor->hostname (this->orb_core_,
00352                                local_addr,
00353                                local_interface.out ()) == -1)
00354     {
00355       ACE_ERROR_RETURN ((LM_ERROR,
00356                          ACE_TEXT ("(%P|%t) Could not resolve local host")
00357                          ACE_TEXT (" name \n")),
00358                         -1);
00359     }
00360 
00361   for (size_t index = 0;
00362        index != count;
00363        index++)
00364     {
00365       if (local_addr.get_ip_address()
00366           == endpoint_addr[index].get_ip_address())
00367         {
00368           // Get the count of the number of elements
00369           CORBA::ULong len = listen_point_list.length ();
00370 
00371           // Increase the length by 1
00372           listen_point_list.length (len + 1);
00373 
00374           // We have the connection and the acceptor endpoint on the
00375           // same interface
00376           IIOP::ListenPoint &point = listen_point_list[len];
00377           point.host = CORBA::string_dup (local_interface.in ());
00378           point.port = endpoint_addr[index].get_port_number ();
00379         }
00380     }
00381 
00382   return 1;
00383 }
00384 
00385 TAO_END_VERSIONED_NAMESPACE_DECL
00386 
00387 #endif /* TAO_HAS_SCIOP == 1 */

Generated on Thu Nov 9 13:39:29 2006 for TAO_Strategies by doxygen 1.3.6