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