00001
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 "$Id: SCIOP_Transport.cpp 78931 2007-07-18 09:59:36Z johnnyw $")
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 : TAO_Transport (TAO_TAG_SCIOP_PROFILE,
00033 orb_core)
00034 , connection_handler_ (handler)
00035 , messaging_object_ (0)
00036 {
00037 ACE_NEW (this->messaging_object_,
00038 TAO_GIOP_Message_Base (orb_core, this));
00039 }
00040
00041 TAO_SCIOP_Transport::~TAO_SCIOP_Transport (void)
00042 {
00043 delete this->messaging_object_;
00044 }
00045
00046 ACE_Event_Handler *
00047 TAO_SCIOP_Transport::event_handler_i (void)
00048 {
00049 return this->connection_handler_;
00050 }
00051
00052 TAO_Connection_Handler *
00053 TAO_SCIOP_Transport::connection_handler_i (void)
00054 {
00055 return this->connection_handler_;
00056 }
00057
00058 TAO_Pluggable_Messaging *
00059 TAO_SCIOP_Transport::messaging_object (void)
00060 {
00061 return this->messaging_object_;
00062 }
00063
00064 ssize_t
00065 TAO_SCIOP_Transport::send (iovec *iov, int iovcnt,
00066 size_t &bytes_transferred,
00067 const ACE_Time_Value *max_wait_time)
00068 {
00069 ssize_t retval = this->connection_handler_->peer ().sendv (iov, iovcnt,
00070 max_wait_time);
00071 if (retval > 0)
00072 bytes_transferred = retval;
00073
00074 return retval;
00075 }
00076
00077 ssize_t
00078 TAO_SCIOP_Transport::recv (char *buf,
00079 size_t len,
00080 const ACE_Time_Value *max_wait_time)
00081 {
00082 ssize_t n = this->connection_handler_->peer ().recv (buf,
00083 len,
00084 max_wait_time);
00085
00086
00087
00088 if (n == -1 &&
00089 TAO_debug_level > 4 &&
00090 errno != ETIME)
00091 {
00092 ACE_DEBUG ((LM_DEBUG,
00093 ACE_TEXT ("TAO (%P|%t) - SCIOP_Transport[%d]::recv, ")
00094 ACE_TEXT ("read failure - %m\n"),
00095 this->id ()));
00096 }
00097
00098
00099 if (n == -1)
00100 {
00101 if (errno == EWOULDBLOCK)
00102 return 0;
00103
00104
00105 return -1;
00106 }
00107
00108
00109
00110
00111
00112 else if (n == 0)
00113 {
00114 return -1;
00115 }
00116
00117 return n;
00118 }
00119
00120 int
00121 TAO_SCIOP_Transport::send_request (TAO_Stub *stub,
00122 TAO_ORB_Core *orb_core,
00123 TAO_OutputCDR &stream,
00124 int message_semantics,
00125 ACE_Time_Value *max_wait_time)
00126 {
00127 if (this->ws_->sending_request (orb_core,
00128 message_semantics) == -1)
00129
00130 return -1;
00131
00132 if (this->send_message (stream,
00133 stub,
00134 message_semantics,
00135 max_wait_time) == -1)
00136 return -1;
00137
00138 this->first_request_sent();
00139
00140 return 0;
00141 }
00142
00143 int
00144 TAO_SCIOP_Transport::send_message (TAO_OutputCDR &stream,
00145 TAO_Stub *stub,
00146 int message_semantics,
00147 ACE_Time_Value *max_wait_time)
00148 {
00149
00150 if (this->messaging_object_->format_message (stream) != 0)
00151 return -1;
00152
00153
00154 ssize_t n = this->send_message_shared (stub,
00155 message_semantics,
00156 stream.begin (),
00157 max_wait_time);
00158
00159 if (n == -1)
00160 {
00161 if (TAO_debug_level)
00162 ACE_DEBUG ((LM_DEBUG,
00163 ACE_TEXT ("TAO (%P|%t) - SCIOP_Transport[%d]::send_message, ")
00164 ACE_TEXT (" write failure - %m\n"),
00165 this->id ()));
00166 return -1;
00167 }
00168
00169 return 1;
00170 }
00171
00172 int
00173 TAO_SCIOP_Transport::send_message_shared (TAO_Stub *stub,
00174 int message_semantics,
00175 const ACE_Message_Block *message_block,
00176 ACE_Time_Value *max_wait_time)
00177 {
00178 int r;
00179
00180 {
00181 ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->handler_lock_, -1);
00182
00183 r = this->send_message_shared_i (stub, message_semantics,
00184 message_block, max_wait_time);
00185 }
00186
00187 if (r == -1)
00188 {
00189 this->close_connection ();
00190 }
00191
00192 return r;
00193 }
00194
00195 int
00196 TAO_SCIOP_Transport::generate_request_header (TAO_Operation_Details &opdetails,
00197 TAO_Target_Specification &spec,
00198 TAO_OutputCDR &msg)
00199 {
00200
00201
00202
00203
00204 if (this->orb_core ()->bidir_giop_policy () &&
00205 this->messaging_object_->is_ready_for_bidirectional (msg) &&
00206 this->bidirectional_flag () < 0)
00207 {
00208 this->set_bidir_context_info (opdetails);
00209
00210
00211 this->bidirectional_flag (1);
00212
00213
00214
00215
00216
00217
00218 opdetails.request_id (this->tms ()->request_id ());
00219 }
00220
00221 return TAO_Transport::generate_request_header (opdetails,
00222 spec,
00223 msg);
00224 }
00225
00226 int
00227 TAO_SCIOP_Transport::messaging_init (CORBA::Octet major,
00228 CORBA::Octet minor)
00229 {
00230 this->messaging_object_->init (major, minor);
00231
00232 return 1;
00233 }
00234
00235 int
00236 TAO_SCIOP_Transport::tear_listen_point_list (TAO_InputCDR &cdr)
00237 {
00238 CORBA::Boolean byte_order;
00239 if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00240 return -1;
00241
00242 cdr.reset_byte_order (static_cast<int> (byte_order));
00243
00244 IIOP::ListenPointList listen_list;
00245 if ((cdr >> listen_list) == 0)
00246 return -1;
00247
00248
00249
00250 this->bidirectional_flag (0);
00251
00252 return this->connection_handler_->process_listen_point_list (listen_list);
00253 }
00254
00255 void
00256 TAO_SCIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
00257 {
00258
00259 TAO_Acceptor_Registry &ar =
00260 this->orb_core ()->lane_resources ().acceptor_registry ();
00261
00262
00263 TAO_AcceptorSetIterator acceptor = ar.begin ();
00264
00265 IIOP::ListenPointList listen_point_list;
00266
00267 for (;
00268 acceptor != ar.end ();
00269 acceptor++)
00270 {
00271
00272 if ((*acceptor)->tag () == TAO_TAG_SCIOP_PROFILE)
00273 {
00274 if (this->get_listen_point (listen_point_list,
00275 *acceptor) == -1)
00276 {
00277 ACE_ERROR ((LM_ERROR,
00278 "TAO (%P|%t) - SCIOP_Transport::set_bidir_info, "
00279 "error getting listen_point \n"));
00280
00281 return;
00282 }
00283 }
00284 }
00285
00286
00287
00288 TAO_OutputCDR cdr;
00289
00290
00291 if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00292 || (cdr << listen_point_list) == 0)
00293 return;
00294
00295
00296 opdetails.request_service_context ().set_context (IOP::BI_DIR_IIOP,
00297 cdr);
00298
00299 return;
00300 }
00301
00302 int
00303 TAO_SCIOP_Transport::get_listen_point (
00304 IIOP::ListenPointList &listen_point_list,
00305 TAO_Acceptor *acceptor)
00306 {
00307 TAO_SCIOP_Acceptor *sciop_acceptor =
00308 dynamic_cast<TAO_SCIOP_Acceptor *> (acceptor );
00309
00310
00311 const ACE_INET_Addr *endpoint_addr =
00312 sciop_acceptor->endpoints ();
00313
00314
00315 size_t count =
00316 sciop_acceptor->endpoint_count ();
00317
00318
00319 ACE_INET_Addr local_addr;
00320
00321 if (this->connection_handler_->peer ().get_local_addr (local_addr) == -1)
00322 {
00323 ACE_ERROR_RETURN ((LM_ERROR,
00324 ACE_TEXT ("(%P|%t) Could not resolve local ")
00325 ACE_TEXT ("host address in ")
00326 ACE_TEXT ("get_listen_point()\n")),
00327 -1);
00328 }
00329
00330
00331
00332
00333 CORBA::String_var local_interface;
00334
00335
00336 if (sciop_acceptor->hostname (this->orb_core_,
00337 local_addr,
00338 local_interface.out ()) == -1)
00339 {
00340 ACE_ERROR_RETURN ((LM_ERROR,
00341 ACE_TEXT ("(%P|%t) Could not resolve local host")
00342 ACE_TEXT (" name \n")),
00343 -1);
00344 }
00345
00346 for (size_t index = 0; index != count; index++)
00347 {
00348 if (local_addr.get_ip_address() == endpoint_addr[index].get_ip_address())
00349 {
00350
00351 CORBA::ULong const len = listen_point_list.length ();
00352
00353
00354 listen_point_list.length (len + 1);
00355
00356
00357
00358 IIOP::ListenPoint &point = listen_point_list[len];
00359 point.host = CORBA::string_dup (local_interface.in ());
00360 point.port = endpoint_addr[index].get_port_number ();
00361 }
00362 }
00363
00364 return 1;
00365 }
00366
00367 TAO_END_VERSIONED_NAMESPACE_DECL
00368
00369 #endif