1 #include "tao/Strategies/SCIOP_Connector.h"
2 #include "tao/Strategies/SCIOP_Profile.h"
7 #include "tao/ORB_Core.h"
8 #include "tao/Client_Strategy_Factory.h"
9 #include "tao/SystemException.h"
10 #include "tao/Base_Transport_Property.h"
11 #include "tao/Protocols_Hooks.h"
12 #include "tao/Transport_Cache_Manager.h"
13 #include "tao/Connect_Strategy.h"
14 #include "tao/Thread_Lane_Resources.h"
15 #include "tao/Transport.h"
16 #include "tao/Wait_Strategy.h"
17 #include "tao/Profile_Transport_Resolver.h"
19 #include "ace/OS_NS_strings.h"
20 #include "ace/Strategies_T.h"
23 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
25 TAO_SCIOP_Connector::TAO_SCIOP_Connector ()
26 : TAO_Connector (TAO_TAG_SCIOP_PROFILE
),
32 TAO_SCIOP_Connector::~TAO_SCIOP_Connector ()
37 TAO_SCIOP_Connector::open (TAO_ORB_Core
*orb_core
)
39 // @todo: The functionality of the following two statements could
40 // be done in the constructor, but that involves changing the
41 // interface of the pluggable transport factory.
44 this->orb_core (orb_core
);
46 // Create our connect strategy
47 if (this->create_connect_strategy () == -1)
50 /// Our connect creation strategy
51 TAO_SCIOP_CONNECT_CREATION_STRATEGY
*connect_creation_strategy
= 0;
53 ACE_NEW_RETURN (connect_creation_strategy
,
54 TAO_SCIOP_CONNECT_CREATION_STRATEGY
55 (orb_core
->thr_mgr (),
59 /// Our activation strategy
60 TAO_SCIOP_CONNECT_CONCURRENCY_STRATEGY
*concurrency_strategy
= 0;
62 ACE_NEW_RETURN (concurrency_strategy
,
63 TAO_SCIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core
),
66 return this->base_connector_
.open (this->orb_core ()->reactor (),
67 connect_creation_strategy
,
68 &this->connect_strategy_
,
69 concurrency_strategy
);
73 TAO_SCIOP_Connector::close ()
75 delete this->base_connector_
.concurrency_strategy ();
76 delete this->base_connector_
.creation_strategy ();
77 return this->base_connector_
.close ();
81 TAO_SCIOP_Connector::set_validate_endpoint (TAO_Endpoint
*endpoint
)
83 TAO_SCIOP_Endpoint
*sciop_endpoint
=
84 this->remote_endpoint (endpoint
);
86 if (sciop_endpoint
== 0)
89 const ACE_INET_Addr
&remote_address
=
90 sciop_endpoint
->object_addr ();
92 // Verify that the remote ACE_INET_Addr was initialized properly.
93 // Failure can occur if hostname lookup failed when initializing the
94 // remote ACE_INET_Addr.
95 if (remote_address
.get_type () != AF_INET
)
97 if (TAO_debug_level
> 0)
99 TAOLIB_DEBUG ((LM_DEBUG
,
100 ACE_TEXT ("TAO (%P|%t) SCIOP connection failed.\n")
101 ACE_TEXT ("TAO (%P|%t) This is most likely ")
102 ACE_TEXT ("due to a hostname lookup ")
103 ACE_TEXT ("failure.\n")));
113 TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver
*r
,
114 TAO_Transport_Descriptor_Interface
&desc
,
115 ACE_Time_Value
*timeout
)
117 TAO_Endpoint
*tao_endpoint
= desc
.endpoint ();
119 TAO_Transport
*transport
= 0;
121 // @@ ATL folks, is this while loop needed?
122 // TAO_Default_Endpoint_Selector has this code already, i.e., the
124 while (tao_endpoint
!= 0)
126 TAO_SCIOP_Endpoint
*sciop_endpoint
= this->remote_endpoint (tao_endpoint
);
128 if (sciop_endpoint
!= 0)
131 this->make_connection_i (r
, desc
, timeout
, sciop_endpoint
);
137 tao_endpoint
= tao_endpoint
->next();
145 TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver
*r
,
146 TAO_Transport_Descriptor_Interface
&desc
,
147 ACE_Time_Value
*timeout
,
148 TAO_SCIOP_Endpoint
*sciop_endpoint
)
150 const ACE_INET_Addr
&remote_address
=
151 sciop_endpoint
->object_addr ();
153 if (TAO_debug_level
> 2)
154 TAOLIB_DEBUG ((LM_DEBUG
,
155 ACE_TEXT("TAO (%P|%t) - SCIOP_Connector::make_connection_i, ")
156 ACE_TEXT("to <%C:%d> which should %s\n"),
157 sciop_endpoint
->host(),
158 sciop_endpoint
->port(),
159 r
->blocked_connect () ? ACE_TEXT("block") : ACE_TEXT("nonblock")));
161 // Get the right synch options
162 ACE_Synch_Options synch_options
;
164 this->active_connect_strategy_
->synch_options (timeout
, synch_options
);
166 // The code used to set the timeout to zero, with the intent of
167 // polling the reactor for connection completion. However, the side-effect
168 // was to cause the connection to timeout immediately.
170 TAO_SCIOP_Connection_Handler
*svc_handler
= 0;
173 ACE_Multihomed_INET_Addr multihomed
;
174 if (multihomed
.set(remote_address
.get_port_number(),
175 remote_address
.get_ip_address()))
178 ACE_Multihomed_INET_Addr local_address
;
181 sciop_endpoint
->is_preferred_network ();
184 local_address
.set ((u_short
) 0,
185 sciop_endpoint
->preferred_network ());
188 this->base_connector_
.connect (svc_handler
,
193 // Make sure that we always do a remove_reference
194 ACE_Event_Handler_var
svc_handler_auto_ptr (svc_handler
);
196 TAO_Transport
*transport
= svc_handler
->transport ();
200 // No immediate result, wait for completion
201 if (errno
== EWOULDBLOCK
)
203 // Try to wait until connection completion. Incase we block, then we
204 // get a connected transport or not. In case of non block we get
205 // a connected or not connected transport
206 if (!this->wait_for_connection_completion (r
,
211 if (TAO_debug_level
> 2)
212 TAOLIB_ERROR ((LM_ERROR
, "TAO (%P|%t) - SCIOP_Connector::"
213 "make_connection_i, "
214 "wait for completion failed\n"));
219 // Transport is not usable
224 // In case of errors transport is zero
227 // Give users a clue to the problem.
230 TAOLIB_ERROR ((LM_ERROR
,
231 ACE_TEXT("TAO (%P|%t) - SCIOP_Connector::make_connection_i, ")
232 ACE_TEXT("connection to <%C:%d> failed (%p)\n"),
233 sciop_endpoint
->host (), sciop_endpoint
->port (),
240 TAO_Leader_Follower
&leader_follower
= this->orb_core ()->leader_follower ();
242 if (svc_handler
->keep_waiting (leader_follower
))
244 svc_handler
->connection_pending ();
247 if (svc_handler
->error_detected (leader_follower
))
249 svc_handler
->cancel_pending_connection ();
253 // At this point, the connection has be successfully connected.
254 // #REFCOUNT# is one.
255 if (TAO_debug_level
> 2)
256 TAOLIB_DEBUG ((LM_DEBUG
,
257 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
258 "new %C connection to <%C:%d> on Transport[%d]\n",
259 transport
->is_connected() ? "connected" : "not connected",
260 sciop_endpoint
->host (), sciop_endpoint
->port (),
261 svc_handler
->peer ().get_handle ()));
263 // Add the handler to Cache
265 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc
,
268 // Failure in adding to cache.
271 // Close the handler.
272 svc_handler
->close ();
274 if (TAO_debug_level
> 0)
276 TAOLIB_ERROR ((LM_ERROR
,
277 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
278 "could not add the new connection to cache\n"));
284 if (svc_handler
->error_detected (leader_follower
))
286 svc_handler
->cancel_pending_connection ();
287 transport
->purge_entry();
291 if (transport
->is_connected () &&
292 transport
->wait_strategy ()->register_handler () != 0)
294 // Registration failures.
296 // Purge from the connection cache, if we are not in the cache, this
297 // just does nothing.
298 (void) transport
->purge_entry ();
300 // Close the handler.
301 (void) transport
->close_connection ();
303 if (TAO_debug_level
> 0)
304 TAOLIB_ERROR ((LM_ERROR
,
305 "TAO (%P|%t) - SCIOP_Connector [%d]::make_connection_i, "
306 "could not register the transport "
313 svc_handler_auto_ptr
.release ();
318 TAO_SCIOP_Connector::create_profile (TAO_InputCDR
& cdr
)
320 TAO_Profile
*pfile
= 0;
321 ACE_NEW_RETURN (pfile
,
322 TAO_SCIOP_Profile (this->orb_core ()),
325 int const r
= pfile
->decode (cdr
);
328 pfile
->_decr_refcnt ();
336 TAO_SCIOP_Connector::make_profile ()
338 // The endpoint should be of the form:
339 // N.n@host:port/object_key
341 // host:port/object_key
343 TAO_Profile
*profile
= 0;
344 ACE_NEW_THROW_EX (profile
,
345 TAO_SCIOP_Profile (this->orb_core ()),
347 CORBA::SystemException::_tao_minor_code (
350 CORBA::COMPLETED_NO
));
356 TAO_SCIOP_Connector::check_prefix (const char *endpoint
)
358 // Check for a valid string
359 if (!endpoint
|| !*endpoint
)
360 return -1; // Failure
362 const char *protocol
[] = { "sciop", "scioploc" };
364 size_t const slot
= std::strchr (endpoint
, ':') - endpoint
;
365 size_t const len0
= std::strlen (protocol
[0]);
366 size_t const len1
= std::strlen (protocol
[1]);
368 // Check for the proper prefix in the IOR. If the proper prefix
369 // isn't in the IOR then it is not an IOR we can use.
371 && ACE_OS::strncasecmp (endpoint
, protocol
[0], len0
) == 0)
373 else if (slot
== len1
374 && ACE_OS::strncasecmp (endpoint
, protocol
[1], len1
) == 0)
378 // Failure: not an SCIOP IOR
379 // DO NOT throw an exception here.
383 TAO_SCIOP_Connector::object_key_delimiter () const
385 return TAO_SCIOP_Profile::object_key_delimiter_
;
389 TAO_SCIOP_Connector::remote_endpoint (TAO_Endpoint
*endpoint
)
391 if (endpoint
->tag () != TAO_TAG_SCIOP_PROFILE
)
394 TAO_SCIOP_Endpoint
*sciop_endpoint
=
395 dynamic_cast<TAO_SCIOP_Endpoint
*> (endpoint
);
396 if (sciop_endpoint
== 0)
399 return sciop_endpoint
;
403 TAO_SCIOP_Connector::cancel_svc_handler (
404 TAO_Connection_Handler
* svc_handler
)
406 TAO_SCIOP_Connection_Handler
* handler
=
407 dynamic_cast<TAO_SCIOP_Connection_Handler
*>(svc_handler
);
410 // Cancel from the connector
411 return this->base_connector_
.cancel (handler
);
416 TAO_END_VERSIONED_NAMESPACE_DECL
418 #endif /* TAO_HAS_SCIOP == 1 */