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