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 90462 2010-06-08 10:04:47Z johnnyw $")
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 if (this->check_prefix (str) != 0)
00082 return 0;
00083
00084 const char *separator = ACE_OS::strchr (str,'|');
00085 if (separator == 0)
00086 {
00087 if (TAO_debug_level)
00088 ACE_DEBUG ((LM_DEBUG,
00089 "TAO (%P|%t) - TAO_UIOP_CONNECTOR::corbaloc_scan error: "
00090 "explicit terminating charactor '|' is missing from <%C>",
00091 str));
00092 return 0;
00093 }
00094 len = (separator - str) + 1;
00095 return this->make_profile ();
00096 }
00097
00098
00099 int
00100 TAO_UIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00101 {
00102 TAO_UIOP_Endpoint *uiop_endpoint = this->remote_endpoint (endpoint);
00103
00104 if (uiop_endpoint == 0)
00105 return -1;
00106
00107 const ACE_UNIX_Addr &remote_address = uiop_endpoint->object_addr ();
00108
00109
00110
00111
00112
00113 if (remote_address.get_type () != AF_UNIX)
00114 {
00115 if (TAO_debug_level > 0)
00116 {
00117 ACE_DEBUG ((LM_DEBUG,
00118 ACE_TEXT ("TAO (%P|%t) - UIOP failure.\n")
00119 ACE_TEXT ("TAO (%P|%t) - This is most likely ")
00120 ACE_TEXT ("due to a hostname lookup ")
00121 ACE_TEXT ("failure.\n")));
00122 }
00123
00124 return -1;
00125 }
00126
00127 return 0;
00128 }
00129
00130 TAO_Transport *
00131 TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
00132 TAO_Transport_Descriptor_Interface &desc,
00133 ACE_Time_Value *max_wait_time)
00134 {
00135 if (TAO_debug_level > 0)
00136 ACE_DEBUG ((LM_DEBUG,
00137 ACE_TEXT ("TAO (%P|%t) - UIUP_Connector::make_connection, ")
00138 ACE_TEXT ("looking for UIOP connection.\n")));
00139
00140 TAO_UIOP_Endpoint *uiop_endpoint =
00141 this->remote_endpoint (desc.endpoint ());
00142
00143 if (uiop_endpoint == 0)
00144 return 0;
00145
00146 const ACE_UNIX_Addr &remote_address =
00147 uiop_endpoint->object_addr ();
00148
00149 if (TAO_debug_level > 2)
00150 ACE_DEBUG ((LM_DEBUG,
00151 ACE_TEXT ("TAO (%P|%t) - UIUP_Connector::make_connection, ")
00152 ACE_TEXT ("making a new connection\n")));
00153
00154
00155 ACE_Synch_Options synch_options;
00156
00157 this->active_connect_strategy_->synch_options (max_wait_time,
00158 synch_options);
00159
00160
00161
00162
00163
00164 TAO_UIOP_Connection_Handler *svc_handler = 0;
00165
00166
00167 int result =
00168 this->base_connector_.connect (svc_handler,
00169 remote_address,
00170 synch_options);
00171
00172
00173 ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
00174
00175 TAO_Transport *transport =
00176 svc_handler->transport ();
00177
00178 if (result == -1)
00179 {
00180
00181 if (errno == EWOULDBLOCK)
00182 {
00183
00184
00185
00186 if (!this->wait_for_connection_completion (r,
00187 desc,
00188 transport,
00189 max_wait_time))
00190 {
00191 if (TAO_debug_level > 2)
00192 ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - UIOP_Connector::"
00193 "make_connection, "
00194 "wait for completion failed\n"));
00195 }
00196 }
00197 else
00198 {
00199
00200 transport = 0;
00201 }
00202 }
00203
00204
00205 if (transport == 0)
00206 {
00207
00208 if (TAO_debug_level > 3)
00209 ACE_ERROR ((LM_ERROR,
00210 "TAO (%P|%t) - UIOP_Connector::make_connection, "
00211 "connection to <%C> failed (%p)\n",
00212 uiop_endpoint->rendezvous_point (),
00213 ACE_TEXT("errno")));
00214
00215 return 0;
00216 }
00217
00218 if (svc_handler->keep_waiting ())
00219 {
00220 svc_handler->connection_pending ();
00221 }
00222
00223 if (svc_handler->error_detected ())
00224 {
00225 svc_handler->cancel_pending_connection ();
00226 }
00227
00228
00229
00230 if (TAO_debug_level > 2)
00231 ACE_DEBUG ((LM_DEBUG,
00232 "TAO (%P|%t) - UIOP_Connector::make_connection, "
00233 "new %C connection to <%C> on Transport[%d]\n",
00234 transport->is_connected() ? "connected" : "not connected",
00235 uiop_endpoint->rendezvous_point (),
00236 svc_handler->peer ().get_handle ()));
00237
00238
00239 int retval =
00240 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
00241 transport);
00242
00243 if (retval == -1)
00244 {
00245
00246 svc_handler->close ();
00247
00248 if (TAO_debug_level > 0)
00249 {
00250 ACE_ERROR ((LM_ERROR,
00251 ACE_TEXT ("TAO (%P|%t) - UIOP_Connector::make_connection, ")
00252 ACE_TEXT ("could not add the new connection to Cache\n")));
00253 }
00254
00255 return 0;
00256 }
00257
00258 if (svc_handler->error_detected ())
00259 {
00260 svc_handler->cancel_pending_connection ();
00261 transport->purge_entry();
00262 return 0;
00263 }
00264
00265 if (transport->is_connected () &&
00266 transport->wait_strategy ()->register_handler () != 0)
00267 {
00268
00269
00270
00271
00272 (void) transport->purge_entry ();
00273
00274
00275 (void) transport->close_connection ();
00276
00277 if (TAO_debug_level > 0)
00278 ACE_ERROR ((LM_ERROR,
00279 "TAO (%P|%t) - UIOP_Connector [%d]::make_connection, "
00280 "could not register the transport "
00281 "in the reactor.\n",
00282 transport->id ()));
00283
00284 return 0;
00285 }
00286
00287 svc_handler_auto_ptr.release ();
00288 return transport;
00289 }
00290
00291
00292 TAO_Profile *
00293 TAO_UIOP_Connector::create_profile (TAO_InputCDR& cdr)
00294 {
00295 TAO_Profile *pfile;
00296 ACE_NEW_RETURN (pfile,
00297 TAO_UIOP_Profile (this->orb_core ()),
00298 0);
00299
00300 const int r = pfile->decode (cdr);
00301 if (r == -1)
00302 {
00303 pfile->_decr_refcnt ();
00304 pfile = 0;
00305 }
00306
00307 return pfile;
00308 }
00309
00310 TAO_Profile *
00311 TAO_UIOP_Connector::make_profile (void)
00312 {
00313 TAO_Profile *profile = 0;
00314 ACE_NEW_THROW_EX (profile,
00315 TAO_UIOP_Profile (this->orb_core ()),
00316 CORBA::NO_MEMORY (
00317 CORBA::SystemException::_tao_minor_code (
00318 TAO::VMCID,
00319 ENOMEM),
00320 CORBA::COMPLETED_NO));
00321
00322
00323 return profile;
00324 }
00325
00326 int
00327 TAO_UIOP_Connector::check_prefix (const char *endpoint)
00328 {
00329
00330 if (!endpoint || !*endpoint)
00331 return -1;
00332
00333 static const char *protocol[] = { "uiop", "uioploc" };
00334
00335 const size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00336
00337 const size_t len0 = ACE_OS::strlen (protocol[0]);
00338 const size_t len1 = ACE_OS::strlen (protocol[1]);
00339
00340
00341
00342 if (slot == len0
00343 && ACE_OS::strncasecmp (endpoint,
00344 protocol[0],
00345 len0) == 0)
00346 return 0;
00347 else if (slot == len1
00348 && ACE_OS::strncasecmp (endpoint,
00349 protocol[1],
00350 len1) == 0)
00351 return 0;
00352
00353 return -1;
00354
00355 }
00356
00357 char
00358 TAO_UIOP_Connector::object_key_delimiter (void) const
00359 {
00360 return TAO_UIOP_Profile::object_key_delimiter_;
00361 }
00362
00363 TAO_UIOP_Endpoint *
00364 TAO_UIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00365 {
00366 if (endpoint->tag () != TAO_TAG_UIOP_PROFILE)
00367 return 0;
00368
00369 TAO_UIOP_Endpoint *uiop_endpoint =
00370 dynamic_cast<TAO_UIOP_Endpoint *> (endpoint);
00371
00372 if (uiop_endpoint == 0)
00373 return 0;
00374
00375 return uiop_endpoint;
00376 }
00377
00378 int
00379 TAO_UIOP_Connector::cancel_svc_handler (
00380 TAO_Connection_Handler * svc_handler)
00381 {
00382 TAO_UIOP_Connection_Handler* handler=
00383 dynamic_cast<TAO_UIOP_Connection_Handler*> (svc_handler);
00384
00385 if (handler)
00386
00387 return this->base_connector_.cancel (handler);
00388
00389 return -1;
00390 }
00391
00392 TAO_END_VERSIONED_NAMESPACE_DECL
00393
00394 #endif