00001 #include "tao/Strategies/SCIOP_Connector.h"
00002 #include "tao/Strategies/SCIOP_Profile.h"
00003
00004 #if TAO_HAS_SCIOP == 1
00005
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Client_Strategy_Factory.h"
00009 #include "tao/SystemException.h"
00010 #include "tao/Base_Transport_Property.h"
00011 #include "tao/Protocols_Hooks.h"
00012 #include "tao/Transport_Cache_Manager.h"
00013 #include "tao/Connect_Strategy.h"
00014 #include "tao/Thread_Lane_Resources.h"
00015 #include "tao/Transport.h"
00016 #include "tao/Wait_Strategy.h"
00017 #include "tao/Profile_Transport_Resolver.h"
00018
00019 #include "ace/OS_NS_strings.h"
00020 #include "ace/Strategies_T.h"
00021
00022
00023 ACE_RCSID (TAO,
00024 SCIOP_Connector,
00025 "$Id: SCIOP_Connector.cpp 86593 2009-09-02 14:58:00Z vzykov $")
00026
00027
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029
00030 TAO_SCIOP_Connector::TAO_SCIOP_Connector (void)
00031 : TAO_Connector (TAO_TAG_SCIOP_PROFILE),
00032 connect_strategy_ (),
00033 base_connector_ ()
00034 {
00035 }
00036
00037 TAO_SCIOP_Connector::~TAO_SCIOP_Connector (void)
00038 {
00039 }
00040
00041 int
00042 TAO_SCIOP_Connector::open (TAO_ORB_Core *orb_core)
00043 {
00044
00045
00046
00047
00048
00049 this->orb_core (orb_core);
00050
00051
00052 if (this->create_connect_strategy () == -1)
00053 return -1;
00054
00055
00056 TAO_SCIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
00057
00058 ACE_NEW_RETURN (connect_creation_strategy,
00059 TAO_SCIOP_CONNECT_CREATION_STRATEGY
00060 (orb_core->thr_mgr (),
00061 orb_core),
00062 -1);
00063
00064
00065 TAO_SCIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
00066
00067 ACE_NEW_RETURN (concurrency_strategy,
00068 TAO_SCIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
00069 -1);
00070
00071 return this->base_connector_.open (this->orb_core ()->reactor (),
00072 connect_creation_strategy,
00073 &this->connect_strategy_,
00074 concurrency_strategy);
00075 }
00076
00077 int
00078 TAO_SCIOP_Connector::close (void)
00079 {
00080 delete this->base_connector_.concurrency_strategy ();
00081 delete this->base_connector_.creation_strategy ();
00082 return this->base_connector_.close ();
00083 }
00084
00085 int
00086 TAO_SCIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00087 {
00088 TAO_SCIOP_Endpoint *sciop_endpoint =
00089 this->remote_endpoint (endpoint);
00090
00091 if (sciop_endpoint == 0)
00092 return -1;
00093
00094 const ACE_INET_Addr &remote_address =
00095 sciop_endpoint->object_addr ();
00096
00097
00098
00099
00100 if (remote_address.get_type () != AF_INET)
00101 {
00102 if (TAO_debug_level > 0)
00103 {
00104 ACE_DEBUG ((LM_DEBUG,
00105 ACE_TEXT ("TAO (%P|%t) SCIOP connection failed.\n")
00106 ACE_TEXT ("TAO (%P|%t) This is most likely ")
00107 ACE_TEXT ("due to a hostname lookup ")
00108 ACE_TEXT ("failure.\n")));
00109 }
00110
00111 return -1;
00112 }
00113
00114 return 0;
00115 }
00116
00117 TAO_Transport *
00118 TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
00119 TAO_Transport_Descriptor_Interface &desc,
00120 ACE_Time_Value *timeout)
00121 {
00122 TAO_Endpoint *tao_endpoint = desc.endpoint ();
00123
00124 TAO_Transport *transport = 0;
00125
00126
00127
00128
00129 while (tao_endpoint != 0)
00130 {
00131 TAO_SCIOP_Endpoint *sciop_endpoint = this->remote_endpoint (tao_endpoint);
00132
00133 if (sciop_endpoint != 0)
00134 {
00135 transport =
00136 this->make_connection_i (r, desc, timeout, sciop_endpoint);
00137 if (transport)
00138 {
00139 break;
00140 }
00141 }
00142 tao_endpoint = tao_endpoint->next();
00143 }
00144
00145 return transport;
00146 }
00147
00148
00149 TAO_Transport *
00150 TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r,
00151 TAO_Transport_Descriptor_Interface &desc,
00152 ACE_Time_Value *timeout,
00153 TAO_SCIOP_Endpoint *sciop_endpoint)
00154 {
00155 const ACE_INET_Addr &remote_address =
00156 sciop_endpoint->object_addr ();
00157
00158 if (TAO_debug_level > 2)
00159 ACE_DEBUG ((LM_DEBUG,
00160 ACE_TEXT("TAO (%P|%t) - SCIOP_Connector::make_connection_i, ")
00161 ACE_TEXT("to <%C:%d> which should %s\n"),
00162 sciop_endpoint->host(),
00163 sciop_endpoint->port(),
00164 r->blocked_connect () ? ACE_TEXT("block") : ACE_TEXT("nonblock")));
00165
00166
00167 ACE_Synch_Options synch_options;
00168
00169 this->active_connect_strategy_->synch_options (timeout, synch_options);
00170
00171
00172
00173
00174
00175 TAO_SCIOP_Connection_Handler *svc_handler = 0;
00176
00177
00178 ACE_Multihomed_INET_Addr multihomed;
00179 if (multihomed.set(remote_address.get_port_number(),
00180 remote_address.get_ip_address()))
00181 return 0;
00182
00183 ACE_Multihomed_INET_Addr local_address;
00184
00185 bool pn =
00186 sciop_endpoint->is_preferred_network ();
00187
00188 if (pn)
00189 local_address.set ((u_short) 0,
00190 sciop_endpoint->preferred_network ());
00191
00192 int result =
00193 this->base_connector_.connect (svc_handler,
00194 multihomed,
00195 synch_options,
00196 local_address);
00197
00198
00199 ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
00200
00201 TAO_Transport *transport = svc_handler->transport ();
00202
00203 if (result == -1)
00204 {
00205
00206 if (errno == EWOULDBLOCK)
00207 {
00208
00209
00210
00211 if (!this->wait_for_connection_completion (r,
00212 desc,
00213 transport,
00214 timeout))
00215 {
00216 if (TAO_debug_level > 2)
00217 ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - SCIOP_Connector::"
00218 "make_connection_i, "
00219 "wait for completion failed\n"));
00220 }
00221 }
00222 else
00223 {
00224
00225 transport = 0;
00226 }
00227 }
00228
00229
00230 if (transport == 0)
00231 {
00232
00233 if (TAO_debug_level)
00234 {
00235 ACE_ERROR ((LM_ERROR,
00236 ACE_TEXT("TAO (%P|%t) - SCIOP_Connector::make_connection_i, ")
00237 ACE_TEXT("connection to <%C:%d> failed (%p)\n"),
00238 sciop_endpoint->host (), sciop_endpoint->port (),
00239 ACE_TEXT("errno")));
00240 }
00241
00242 return 0;
00243 }
00244
00245 if (svc_handler->keep_waiting ())
00246 {
00247 svc_handler->connection_pending ();
00248 }
00249
00250 if (svc_handler->error_detected ())
00251 {
00252 svc_handler->cancel_pending_connection ();
00253 return 0;
00254 }
00255
00256
00257
00258 if (TAO_debug_level > 2)
00259 ACE_DEBUG ((LM_DEBUG,
00260 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
00261 "new %C connection to <%C:%d> on Transport[%d]\n",
00262 transport->is_connected() ? "connected" : "not connected",
00263 sciop_endpoint->host (), sciop_endpoint->port (),
00264 svc_handler->peer ().get_handle ()));
00265
00266
00267 int retval =
00268 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
00269 transport);
00270
00271
00272 if (retval == -1)
00273 {
00274
00275 svc_handler->close ();
00276
00277 if (TAO_debug_level > 0)
00278 {
00279 ACE_ERROR ((LM_ERROR,
00280 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
00281 "could not add the new connection to cache\n"));
00282 }
00283
00284 return 0;
00285 }
00286
00287 if (svc_handler->error_detected ())
00288 {
00289 svc_handler->cancel_pending_connection ();
00290 transport->purge_entry();
00291 return 0;
00292 }
00293
00294 if (transport->is_connected () &&
00295 transport->wait_strategy ()->register_handler () != 0)
00296 {
00297
00298
00299
00300
00301 (void) transport->purge_entry ();
00302
00303
00304 (void) transport->close_connection ();
00305
00306 if (TAO_debug_level > 0)
00307 ACE_ERROR ((LM_ERROR,
00308 "TAO (%P|%t) - SCIOP_Connector [%d]::make_connection_i, "
00309 "could not register the transport "
00310 "in the reactor.\n",
00311 transport->id ()));
00312
00313 return 0;
00314 }
00315
00316 svc_handler_auto_ptr.release ();
00317 return transport;
00318 }
00319
00320 TAO_Profile *
00321 TAO_SCIOP_Connector::create_profile (TAO_InputCDR& cdr)
00322 {
00323 TAO_Profile *pfile = 0;
00324 ACE_NEW_RETURN (pfile,
00325 TAO_SCIOP_Profile (this->orb_core ()),
00326 0);
00327
00328 int const r = pfile->decode (cdr);
00329 if (r == -1)
00330 {
00331 pfile->_decr_refcnt ();
00332 pfile = 0;
00333 }
00334
00335 return pfile;
00336 }
00337
00338 TAO_Profile *
00339 TAO_SCIOP_Connector::make_profile (void)
00340 {
00341
00342
00343
00344
00345
00346 TAO_Profile *profile = 0;
00347 ACE_NEW_THROW_EX (profile,
00348 TAO_SCIOP_Profile (this->orb_core ()),
00349 CORBA::NO_MEMORY (
00350 CORBA::SystemException::_tao_minor_code (
00351 TAO::VMCID,
00352 ENOMEM),
00353 CORBA::COMPLETED_NO));
00354
00355 return profile;
00356 }
00357
00358 int
00359 TAO_SCIOP_Connector::check_prefix (const char *endpoint)
00360 {
00361
00362 if (!endpoint || !*endpoint)
00363 return -1;
00364
00365 const char *protocol[] = { "sciop", "scioploc" };
00366
00367 size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00368
00369 size_t len0 = ACE_OS::strlen (protocol[0]);
00370 size_t len1 = ACE_OS::strlen (protocol[1]);
00371
00372
00373
00374 if (slot == len0
00375 && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
00376 return 0;
00377 else if (slot == len1
00378 && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
00379 return 0;
00380
00381 return -1;
00382
00383
00384 }
00385
00386 char
00387 TAO_SCIOP_Connector::object_key_delimiter (void) const
00388 {
00389 return TAO_SCIOP_Profile::object_key_delimiter_;
00390 }
00391
00392 TAO_SCIOP_Endpoint *
00393 TAO_SCIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00394 {
00395 if (endpoint->tag () != TAO_TAG_SCIOP_PROFILE)
00396 return 0;
00397
00398 TAO_SCIOP_Endpoint *sciop_endpoint =
00399 dynamic_cast<TAO_SCIOP_Endpoint *> (endpoint );
00400 if (sciop_endpoint == 0)
00401 return 0;
00402
00403 return sciop_endpoint;
00404 }
00405
00406 int
00407 TAO_SCIOP_Connector::cancel_svc_handler (
00408 TAO_Connection_Handler * svc_handler)
00409 {
00410 TAO_SCIOP_Connection_Handler* handler=
00411 dynamic_cast<TAO_SCIOP_Connection_Handler*>(svc_handler);
00412
00413 if (handler)
00414
00415 return this->base_connector_.cancel (handler);
00416
00417 return -1;
00418 }
00419
00420 TAO_END_VERSIONED_NAMESPACE_DECL
00421
00422 #endif