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/SystemException.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 "$Id: UIOP_Connector.cpp 79388 2007-08-17 16:05:00Z wilsond $")
00023
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025
00026 TAO_UIOP_Connector::TAO_UIOP_Connector (void)
00027 : TAO_Connector (TAO_TAG_UIOP_PROFILE),
00028 connect_strategy_ (),
00029 base_connector_ ()
00030 {
00031 }
00032
00033 TAO_UIOP_Connector::~TAO_UIOP_Connector (void)
00034 {
00035 }
00036
00037 int
00038 TAO_UIOP_Connector::open (TAO_ORB_Core *orb_core)
00039 {
00040 this->orb_core (orb_core);
00041
00042
00043 if (this->create_connect_strategy () == -1)
00044 return -1;
00045
00046
00047 TAO_UIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
00048
00049 ACE_NEW_RETURN (connect_creation_strategy,
00050 TAO_UIOP_CONNECT_CREATION_STRATEGY
00051 (orb_core->thr_mgr (),
00052 orb_core),
00053 -1);
00054
00055
00056 TAO_UIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
00057
00058 ACE_NEW_RETURN (concurrency_strategy,
00059 TAO_UIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
00060 -1);
00061
00062 return this->base_connector_.open (this->orb_core ()->reactor (),
00063 connect_creation_strategy,
00064 &this->connect_strategy_,
00065 concurrency_strategy);
00066 }
00067
00068 int
00069 TAO_UIOP_Connector::close (void)
00070 {
00071
00072 delete this->base_connector_.creation_strategy ();
00073 delete this->base_connector_.concurrency_strategy ();
00074
00075 return this->base_connector_.close ();
00076 }
00077
00078 TAO_Profile *
00079 TAO_UIOP_Connector::corbaloc_scan (const char *str, size_t &len
00080 )
00081 {
00082 if (this->check_prefix (str) != 0)
00083 return 0;
00084
00085 const char *separator = ACE_OS::strchr (str,'|');
00086 if (separator == 0)
00087 {
00088 if (TAO_debug_level)
00089 ACE_DEBUG ((LM_DEBUG,
00090 "(%P|%t) TAO_UIOP_CONNECTOR::corbaloc_scan error: "
00091 "explicit terminating charactor '|' is missing from <%s>",
00092 str));
00093 return 0;
00094 }
00095 len = (separator - str) + 1;
00096 return this->make_profile ();
00097 }
00098
00099
00100 int
00101 TAO_UIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00102 {
00103 TAO_UIOP_Endpoint *uiop_endpoint = this->remote_endpoint (endpoint);
00104
00105 if (uiop_endpoint == 0)
00106 return -1;
00107
00108 const ACE_UNIX_Addr &remote_address = uiop_endpoint->object_addr ();
00109
00110
00111
00112
00113
00114 if (remote_address.get_type () != AF_UNIX)
00115 {
00116 if (TAO_debug_level > 0)
00117 {
00118 ACE_DEBUG ((LM_DEBUG,
00119 ACE_TEXT ("TAO (%P|%t) UIOP failure.\n")
00120 ACE_TEXT ("TAO (%P|%t) This is most likely ")
00121 ACE_TEXT ("due to a hostname lookup ")
00122 ACE_TEXT ("failure.\n")));
00123 }
00124
00125 return -1;
00126 }
00127
00128 return 0;
00129 }
00130
00131 TAO_Transport *
00132 TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
00133 TAO_Transport_Descriptor_Interface &desc,
00134 ACE_Time_Value *max_wait_time)
00135 {
00136 if (TAO_debug_level > 0)
00137 ACE_DEBUG ((LM_DEBUG,
00138 ACE_TEXT ("TAO (%P|%t) UIUP_Connector::make_connection, ")
00139 ACE_TEXT ("looking for UIOP connection.\n")));
00140
00141 TAO_UIOP_Endpoint *uiop_endpoint =
00142 this->remote_endpoint (desc.endpoint ());
00143
00144 if (uiop_endpoint == 0)
00145 return 0;
00146
00147 const ACE_UNIX_Addr &remote_address =
00148 uiop_endpoint->object_addr ();
00149
00150 if (TAO_debug_level > 2)
00151 ACE_DEBUG ((LM_DEBUG,
00152 ACE_TEXT ("TAO (%P|%t) UIUP_Connector::make_connection, ")
00153 ACE_TEXT ("making a new connection \n")));
00154
00155
00156 ACE_Synch_Options synch_options;
00157
00158 this->active_connect_strategy_->synch_options (max_wait_time,
00159 synch_options);
00160
00161
00162
00163
00164
00165 TAO_UIOP_Connection_Handler *svc_handler = 0;
00166
00167
00168 int result =
00169 this->base_connector_.connect (svc_handler,
00170 remote_address,
00171 synch_options);
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
00192
00193 TAO_Transport *transport =
00194 svc_handler->transport ();
00195
00196 if (result == -1)
00197 {
00198
00199 if (errno == EWOULDBLOCK)
00200 {
00201
00202
00203
00204 if (!this->wait_for_connection_completion (r,
00205 transport,
00206 max_wait_time))
00207 {
00208 if (TAO_debug_level > 2)
00209 ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - UIOP_Connector::"
00210 "make_connection, "
00211 "wait for completion failed\n"));
00212 }
00213 }
00214 else
00215 {
00216
00217 transport = 0;
00218 }
00219 }
00220
00221
00222 if (transport == 0)
00223 {
00224
00225 if (TAO_debug_level > 3)
00226 ACE_ERROR ((LM_ERROR,
00227 "TAO (%P|%t) - UIOP_Connector::make_connection, "
00228 "connection to <%s> failed (%p)\n",
00229 uiop_endpoint->rendezvous_point (),
00230 ACE_TEXT("errno")));
00231
00232 return 0;
00233 }
00234
00235 if (svc_handler->keep_waiting ())
00236 {
00237 svc_handler->connection_pending ();
00238 }
00239
00240 if (svc_handler->error_detected ())
00241 {
00242 svc_handler->cancel_pending_connection ();
00243 }
00244
00245
00246
00247 if (TAO_debug_level > 2)
00248 ACE_DEBUG ((LM_DEBUG,
00249 "TAO (%P|%t) - UIOP_Connector::make_connection, "
00250 "new %s connection to <%s> on Transport[%d]\n",
00251 transport->is_connected() ? "connected" : "not connected",
00252 uiop_endpoint->rendezvous_point (),
00253 svc_handler->peer ().get_handle ()));
00254
00255
00256 int retval =
00257 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
00258 transport);
00259
00260 if (retval != 0)
00261 {
00262
00263 svc_handler->close ();
00264
00265 if (TAO_debug_level > 0)
00266 {
00267 ACE_ERROR ((LM_ERROR,
00268 ACE_TEXT ("TAO (%P|%t) UIOP_Connector::make_connection, ")
00269 ACE_TEXT ("could not add the new connection to Cache \n")));
00270 }
00271
00272 return 0;
00273 }
00274
00275 if (svc_handler->error_detected ())
00276 {
00277 svc_handler->cancel_pending_connection ();
00278 transport->purge_entry();
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 (void)
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
00339 return profile;
00340 }
00341
00342 int
00343 TAO_UIOP_Connector::check_prefix (const char *endpoint)
00344 {
00345
00346 if (!endpoint || !*endpoint)
00347 return -1;
00348
00349 static const char *protocol[] = { "uiop", "uioploc" };
00350
00351 const size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00352
00353 const size_t len0 = ACE_OS::strlen (protocol[0]);
00354 const size_t len1 = ACE_OS::strlen (protocol[1]);
00355
00356
00357
00358 if (slot == len0
00359 && ACE_OS::strncasecmp (endpoint,
00360 protocol[0],
00361 len0) == 0)
00362 return 0;
00363 else if (slot == len1
00364 && ACE_OS::strncasecmp (endpoint,
00365 protocol[1],
00366 len1) == 0)
00367 return 0;
00368
00369 return -1;
00370
00371 }
00372
00373 char
00374 TAO_UIOP_Connector::object_key_delimiter (void) const
00375 {
00376 return TAO_UIOP_Profile::object_key_delimiter_;
00377 }
00378
00379 TAO_UIOP_Endpoint *
00380 TAO_UIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00381 {
00382 if (endpoint->tag () != TAO_TAG_UIOP_PROFILE)
00383 return 0;
00384
00385 TAO_UIOP_Endpoint *uiop_endpoint =
00386 dynamic_cast<TAO_UIOP_Endpoint *> (endpoint);
00387
00388 if (uiop_endpoint == 0)
00389 return 0;
00390
00391 return uiop_endpoint;
00392 }
00393
00394 int
00395 TAO_UIOP_Connector::cancel_svc_handler (
00396 TAO_Connection_Handler * svc_handler)
00397 {
00398 TAO_UIOP_Connection_Handler* handler=
00399 dynamic_cast<TAO_UIOP_Connection_Handler*> (svc_handler);
00400
00401 if (handler)
00402
00403 return this->base_connector_.cancel (handler);
00404
00405 return -1;
00406 }
00407
00408 TAO_END_VERSIONED_NAMESPACE_DECL
00409
00410 #endif