1 #include "tao/Strategies/UIOP_Connector.h"
5 #include "tao/Strategies/UIOP_Profile.h"
7 #include "tao/ORB_Core.h"
8 #include "tao/SystemException.h"
9 #include "tao/Protocols_Hooks.h"
10 #include "tao/Base_Transport_Property.h"
11 #include "tao/Transport_Cache_Manager.h"
12 #include "tao/Thread_Lane_Resources.h"
13 #include "tao/Connect_Strategy.h"
14 #include "tao/Profile_Transport_Resolver.h"
16 #include "ace/OS_NS_strings.h"
17 #include "ace/OS_NS_string.h"
20 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
22 TAO_UIOP_Connector::TAO_UIOP_Connector ()
23 : TAO_Connector (TAO_TAG_UIOP_PROFILE
),
29 TAO_UIOP_Connector::~TAO_UIOP_Connector ()
34 TAO_UIOP_Connector::open (TAO_ORB_Core
*orb_core
)
36 this->orb_core (orb_core
);
38 // Create our connect strategy
39 if (this->create_connect_strategy () == -1)
42 // Our connect creation strategy
43 TAO_UIOP_CONNECT_CREATION_STRATEGY
*connect_creation_strategy
= 0;
45 ACE_NEW_RETURN (connect_creation_strategy
,
46 TAO_UIOP_CONNECT_CREATION_STRATEGY
47 (orb_core
->thr_mgr (),
51 /// Our activation strategy
52 TAO_UIOP_CONNECT_CONCURRENCY_STRATEGY
*concurrency_strategy
= 0;
54 ACE_NEW_RETURN (concurrency_strategy
,
55 TAO_UIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core
),
58 return this->base_connector_
.open (this->orb_core ()->reactor (),
59 connect_creation_strategy
,
60 &this->connect_strategy_
,
61 concurrency_strategy
);
65 TAO_UIOP_Connector::close ()
67 // Zap the creation strategy that we created earlier.
68 delete this->base_connector_
.creation_strategy ();
69 delete this->base_connector_
.concurrency_strategy ();
71 return this->base_connector_
.close ();
75 TAO_UIOP_Connector::corbaloc_scan (const char *str
, size_t &len
)
77 if (this->check_prefix (str
) != 0)
80 const char *separator
= std::strchr (str
,'|');
84 TAOLIB_DEBUG ((LM_DEBUG
,
85 "TAO (%P|%t) - TAO_UIOP_CONNECTOR::corbaloc_scan error: "
86 "explicit terminating charactor '|' is missing from <%C>",
90 len
= separator
- str
;
91 return this->make_profile ();
96 TAO_UIOP_Connector::set_validate_endpoint (TAO_Endpoint
*endpoint
)
98 TAO_UIOP_Endpoint
*uiop_endpoint
= this->remote_endpoint (endpoint
);
100 if (uiop_endpoint
== 0)
103 const ACE_UNIX_Addr
&remote_address
= uiop_endpoint
->object_addr ();
105 // @@ Note, POSIX.1g renames AF_UNIX to AF_LOCAL.
106 // Verify that the remote ACE_UNIX_Addr was initialized properly.
107 // Failure can occur if hostname lookup failed when initializing the
108 // remote ACE_INET_Addr.
109 if (remote_address
.get_type () != AF_UNIX
)
111 if (TAO_debug_level
> 0)
113 TAOLIB_DEBUG ((LM_DEBUG
,
114 ACE_TEXT ("TAO (%P|%t) - UIOP failure.\n")
115 ACE_TEXT ("TAO (%P|%t) - This is most likely ")
116 ACE_TEXT ("due to a hostname lookup ")
117 ACE_TEXT ("failure.\n")));
127 TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver
*r
,
128 TAO_Transport_Descriptor_Interface
&desc
,
129 ACE_Time_Value
*max_wait_time
)
131 if (TAO_debug_level
> 0)
132 TAOLIB_DEBUG ((LM_DEBUG
,
133 ACE_TEXT ("TAO (%P|%t) - UIUP_Connector::make_connection, ")
134 ACE_TEXT ("looking for UIOP connection.\n")));
136 TAO_UIOP_Endpoint
*uiop_endpoint
=
137 this->remote_endpoint (desc
.endpoint ());
139 if (uiop_endpoint
== 0)
142 const ACE_UNIX_Addr
&remote_address
=
143 uiop_endpoint
->object_addr ();
145 if (TAO_debug_level
> 2)
146 TAOLIB_DEBUG ((LM_DEBUG
,
147 ACE_TEXT ("TAO (%P|%t) - UIUP_Connector::make_connection, ")
148 ACE_TEXT ("making a new connection\n")));
150 // Get the right synch options
151 ACE_Synch_Options synch_options
;
153 this->active_connect_strategy_
->synch_options (max_wait_time
,
156 // The code used to set the timeout to zero, with the intent of
157 // polling the reactor for connection completion. However, the side-effect
158 // was to cause the connection to timeout immediately.
160 TAO_UIOP_Connection_Handler
*svc_handler
= 0;
164 this->base_connector_
.connect (svc_handler
,
168 // Make sure that we always do a remove_reference
169 ACE_Event_Handler_var
svc_handler_auto_ptr (svc_handler
);
171 TAO_Transport
*transport
=
172 svc_handler
->transport ();
176 // No immediate result, wait for completion
177 if (errno
== EWOULDBLOCK
)
179 // Try to wait until connection completion. Incase we block, then we
180 // get a connected transport or not. In case of non block we get
181 // a connected or not connected transport
182 if (!this->wait_for_connection_completion (r
,
187 if (TAO_debug_level
> 2)
188 TAOLIB_ERROR ((LM_ERROR
, "TAO (%P|%t) - UIOP_Connector::"
190 "wait for completion failed\n"));
195 // Transport is not usable
200 // In case of errors transport is zero
203 // Give users a clue to the problem.
204 if (TAO_debug_level
> 3)
205 TAOLIB_ERROR ((LM_ERROR
,
206 "TAO (%P|%t) - UIOP_Connector::make_connection, "
207 "connection to <%C> failed (%p)\n",
208 uiop_endpoint
->rendezvous_point (),
214 TAO_Leader_Follower
&leader_follower
= this->orb_core ()->leader_follower ();
216 if (svc_handler
->keep_waiting (leader_follower
))
218 svc_handler
->connection_pending ();
221 if (svc_handler
->error_detected (leader_follower
))
223 svc_handler
->cancel_pending_connection ();
226 // At this point, the connection has be successfully created
227 // connected or not connected, but we have a connection.
228 if (TAO_debug_level
> 2)
229 TAOLIB_DEBUG ((LM_DEBUG
,
230 "TAO (%P|%t) - UIOP_Connector::make_connection, "
231 "new %C connection to <%C> on Transport[%d]\n",
232 transport
->is_connected() ? "connected" : "not connected",
233 uiop_endpoint
->rendezvous_point (),
234 svc_handler
->peer ().get_handle ()));
236 // Add the handler to Cache
238 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc
,
240 // Failure in adding to cache.
243 // Close the handler.
244 svc_handler
->close ();
246 if (TAO_debug_level
> 0)
248 TAOLIB_ERROR ((LM_ERROR
,
249 ACE_TEXT ("TAO (%P|%t) - UIOP_Connector::make_connection, ")
250 ACE_TEXT ("could not add the new connection to Cache\n")));
256 if (svc_handler
->error_detected (leader_follower
))
258 svc_handler
->cancel_pending_connection ();
259 transport
->purge_entry();
263 if (transport
->is_connected () &&
264 transport
->wait_strategy ()->register_handler () != 0)
266 // Registration failures.
268 // Purge from the connection cache, if we are not in the cache, this
269 // just does nothing.
270 (void) transport
->purge_entry ();
272 // Close the handler.
273 (void) transport
->close_connection ();
275 if (TAO_debug_level
> 0)
276 TAOLIB_ERROR ((LM_ERROR
,
277 "TAO (%P|%t) - UIOP_Connector [%d]::make_connection, "
278 "could not register the transport "
285 svc_handler_auto_ptr
.release ();
291 TAO_UIOP_Connector::create_profile (TAO_InputCDR
& cdr
)
294 ACE_NEW_RETURN (pfile
,
295 TAO_UIOP_Profile (this->orb_core ()),
298 const int r
= pfile
->decode (cdr
);
301 pfile
->_decr_refcnt ();
309 TAO_UIOP_Connector::make_profile ()
311 TAO_Profile
*profile
= 0;
312 ACE_NEW_THROW_EX (profile
,
313 TAO_UIOP_Profile (this->orb_core ()),
315 CORBA::SystemException::_tao_minor_code (
318 CORBA::COMPLETED_NO
));
325 TAO_UIOP_Connector::check_prefix (const char *endpoint
)
327 // Check for a valid string
328 if (!endpoint
|| !*endpoint
)
329 return -1; // Failure
331 static const char *protocol
[] = { "uiop", "uioploc" };
333 size_t const slot
= std::strchr (endpoint
, ':') - endpoint
;
335 size_t const len0
= std::strlen (protocol
[0]);
336 size_t const len1
= std::strlen (protocol
[1]);
338 // Check for the proper prefix in the IOR. If the proper prefix
339 // isn't in the IOR then it is not an IOR we can use.
341 && ACE_OS::strncasecmp (endpoint
,
345 else if (slot
== len1
346 && ACE_OS::strncasecmp (endpoint
,
352 // Failure: not an UIOP IOR DO NOT throw an exception here.
356 TAO_UIOP_Connector::object_key_delimiter () const
358 return TAO_UIOP_Profile::object_key_delimiter_
;
362 TAO_UIOP_Connector::remote_endpoint (TAO_Endpoint
*endpoint
)
364 if (endpoint
->tag () != TAO_TAG_UIOP_PROFILE
)
367 TAO_UIOP_Endpoint
*uiop_endpoint
=
368 dynamic_cast<TAO_UIOP_Endpoint
*> (endpoint
);
370 if (uiop_endpoint
== 0)
373 return uiop_endpoint
;
377 TAO_UIOP_Connector::cancel_svc_handler (
378 TAO_Connection_Handler
* svc_handler
)
380 TAO_UIOP_Connection_Handler
* handler
=
381 dynamic_cast<TAO_UIOP_Connection_Handler
*> (svc_handler
);
384 // Cancel from the connector
385 return this->base_connector_
.cancel (handler
);
390 TAO_END_VERSIONED_NAMESPACE_DECL
392 #endif /* TAO_HAS_UIOP == 1 */