1 #include "tao/Strategies/SHMIOP_Connector.h"
3 #if defined (TAO_HAS_SHMIOP) && (TAO_HAS_SHMIOP != 0)
5 #include "tao/Strategies/SHMIOP_Profile.h"
6 #include "tao/Strategies/SHMIOP_Endpoint.h"
8 #include "tao/Base_Transport_Property.h"
9 #include "tao/ORB_Core.h"
10 #include "tao/Client_Strategy_Factory.h"
11 #include "tao/SystemException.h"
12 #include "tao/Transport_Cache_Manager.h"
13 #include "tao/Thread_Lane_Resources.h"
14 #include "tao/Blocked_Connect_Strategy.h"
15 #include "ace/OS_NS_strings.h"
18 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
20 TAO_SHMIOP_Connector::TAO_SHMIOP_Connector ()
21 : TAO_Connector (TAO_TAG_SHMEM_PROFILE
),
28 TAO_SHMIOP_Connector::open (TAO_ORB_Core
*orb_core
)
30 this->orb_core (orb_core
);
32 // The SHMIOP always uses a blocked connect strategy
33 // @todo: There are better ways of doing this. Let it be like this
35 ACE_NEW_RETURN (this->active_connect_strategy_
,
36 TAO_Blocked_Connect_Strategy (orb_core
),
39 // Our connect creation strategy
40 TAO_SHMIOP_CONNECT_CREATION_STRATEGY
*connect_creation_strategy
= 0;
42 ACE_NEW_RETURN (connect_creation_strategy
,
43 TAO_SHMIOP_CONNECT_CREATION_STRATEGY
44 (orb_core
->thr_mgr (),
48 /// Our activation strategy
49 TAO_SHMIOP_CONNECT_CONCURRENCY_STRATEGY
*concurrency_strategy
= 0;
51 ACE_NEW_RETURN (concurrency_strategy
,
52 TAO_SHMIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core
),
55 if (this->base_connector_
.open (this->orb_core ()->reactor (),
56 connect_creation_strategy
,
57 &this->connect_strategy_
,
58 concurrency_strategy
) == -1)
60 // We can take advantage of the multithreaded shared-memory transport
61 // if the client will block on read (i.e., will not allow callback.)
62 else if (orb_core
->client_factory ()->allow_callback () == 0)
65 this->base_connector_
.connector ().preferred_strategy (ACE_MEM_IO::MT
);
66 this->connect_strategy_
.connector ().preferred_strategy (ACE_MEM_IO::MT
);
72 TAO_SHMIOP_Connector::close ()
74 delete this->base_connector_
.concurrency_strategy ();
75 delete this->base_connector_
.creation_strategy ();
76 return this->base_connector_
.close ();
80 TAO_SHMIOP_Connector::set_validate_endpoint (TAO_Endpoint
*endpoint
)
82 if (endpoint
->tag () != TAO_TAG_SHMEM_PROFILE
)
85 TAO_SHMIOP_Endpoint
*shmiop_endpoint
=
86 dynamic_cast <TAO_SHMIOP_Endpoint
*>(endpoint
);
87 if (shmiop_endpoint
== 0)
90 const ACE_INET_Addr
&remote_address
=
91 shmiop_endpoint
->object_addr ();
93 // Verify that the remote ACE_INET_Addr was initialized properly.
94 // Failure can occur if hostname lookup failed when initializing the
95 // remote ACE_INET_Addr.
96 switch (remote_address
.get_type ())
104 if (TAO_debug_level
> 0)
106 TAOLIB_ERROR ((LM_ERROR
,
107 ACE_TEXT ("TAO (%P|%t) SHMIOP connection failed.\n")
108 ACE_TEXT ("TAO (%P|%t) This is most likely ")
109 ACE_TEXT ("due to a hostname lookup ")
110 ACE_TEXT ("failure.\n")));
120 TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver
*,
121 TAO_Transport_Descriptor_Interface
&desc
,
122 ACE_Time_Value
*timeout
)
124 if (TAO_debug_level
> 0)
125 TAOLIB_DEBUG ((LM_DEBUG
,
126 ACE_TEXT ("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
127 ACE_TEXT ("looking for SHMIOP connection.\n")));
129 TAO_SHMIOP_Endpoint
*shmiop_endpoint
=
130 this->remote_endpoint (desc
.endpoint ());
132 if (shmiop_endpoint
== 0)
135 const ACE_INET_Addr
&remote_address
=
136 shmiop_endpoint
->object_addr ();
138 if (TAO_debug_level
> 2)
139 TAOLIB_DEBUG ((LM_DEBUG
,
140 "TAO (%P|%t) - SHMIOP_Connector::make_connection, "
141 "making a new connection to <%C:%d>\n",
142 shmiop_endpoint
->host (),
143 shmiop_endpoint
->port ()));
145 // Get the right synch options
146 ACE_Synch_Options synch_options
;
148 this->active_connect_strategy_
->synch_options (timeout
,
151 TAO_SHMIOP_Connection_Handler
*svc_handler
= 0;
154 int result
= this->base_connector_
.connect (svc_handler
,
158 // Make sure that we always do a remove_reference
159 ACE_Event_Handler_var
svc_handler_auto_ptr (svc_handler
);
161 // In case of errors.
164 // Give users a clue to the problem.
165 if (TAO_debug_level
> 0)
167 TAOLIB_ERROR ((LM_ERROR
,
168 ACE_TEXT ("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
169 ACE_TEXT ("connection to <%C:%u> failed (%p)\n"),
170 shmiop_endpoint
->host (),
171 shmiop_endpoint
->port (),
172 ACE_TEXT ("errno")));
178 TAO_Leader_Follower
&leader_follower
= this->orb_core ()->leader_follower ();
180 if (svc_handler
->keep_waiting (leader_follower
))
182 svc_handler
->connection_pending ();
185 if (svc_handler
->error_detected (leader_follower
))
187 svc_handler
->cancel_pending_connection ();
190 TAO_Transport
*transport
= svc_handler
->transport ();
192 // At this point, the connection has be successfully connected.
193 // #REFCOUNT# is one.
194 if (TAO_debug_level
> 2)
195 TAOLIB_DEBUG ((LM_DEBUG
,
196 "TAO (%P|%t) - SHMIOP_Connector::make_connection, "
197 "new %C connection to <%C:%d> on Transport[%d]\n",
198 transport
->is_connected() ? "connected" : "not connected",
199 shmiop_endpoint
->host (),
200 shmiop_endpoint
->port (),
201 svc_handler
->peer ().get_handle ()));
203 // Add the handler to Cache
205 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc
,
208 // Failure in adding to cache.
211 // Close the handler.
212 svc_handler
->close ();
214 if (TAO_debug_level
> 0)
216 TAOLIB_ERROR ((LM_ERROR
,
217 ACE_TEXT("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
218 ACE_TEXT("could not add the new connection to cache\n")));
224 if (svc_handler
->error_detected (leader_follower
))
226 svc_handler
->cancel_pending_connection ();
227 transport
->purge_entry();
231 if (transport
->is_connected () &&
232 transport
->wait_strategy ()->register_handler () != 0)
234 // Registration failures.
236 // Purge from the connection cache, if we are not in the cache, this
237 // just does nothing.
238 (void) transport
->purge_entry ();
240 // Close the handler.
241 (void) transport
->close_connection ();
243 if (TAO_debug_level
> 0)
244 TAOLIB_ERROR ((LM_ERROR
,
245 "TAO (%P|%t) - SHMIOP_Connector [%d]::make_connection, "
246 "could not register the transport in the reactor.\n",
252 svc_handler_auto_ptr
.release ();
257 TAO_SHMIOP_Connector::create_profile (TAO_InputCDR
& cdr
)
259 TAO_Profile
*pfile
= 0;
260 ACE_NEW_RETURN (pfile
,
261 TAO_SHMIOP_Profile (this->orb_core ()),
264 int r
= pfile
->decode (cdr
);
267 pfile
->_decr_refcnt ();
275 TAO_SHMIOP_Connector::make_profile ()
277 // The endpoint should be of the form:
278 // N.n@port/object_key
282 TAO_Profile
*profile
= 0;
283 ACE_NEW_THROW_EX (profile
,
284 TAO_SHMIOP_Profile (this->orb_core ()),
286 CORBA::SystemException::_tao_minor_code (
289 CORBA::COMPLETED_NO
));
295 TAO_SHMIOP_Connector::check_prefix (const char *endpoint
)
297 // Check for a valid string
298 if (!endpoint
|| !*endpoint
)
299 return -1; // Failure
301 const char *protocol
[] = { "shmiop", "shmioploc" };
303 size_t const slot
= std::strchr (endpoint
, ':') - endpoint
;
305 size_t const len0
= std::strlen (protocol
[0]);
306 size_t const len1
= std::strlen (protocol
[1]);
308 // Check for the proper prefix in the IOR. If the proper prefix
309 // isn't in the IOR then it is not an IOR we can use.
311 && ACE_OS::strncasecmp (endpoint
, protocol
[0], len0
) == 0)
313 else if (slot
== len1
314 && ACE_OS::strncasecmp (endpoint
, protocol
[1], len1
) == 0)
318 // Failure: not an SHMIOP IOR
319 // DO NOT throw an exception here.
323 TAO_SHMIOP_Connector::object_key_delimiter () const
325 return TAO_SHMIOP_Profile::object_key_delimiter_
;
328 TAO_SHMIOP_Endpoint
*
329 TAO_SHMIOP_Connector::remote_endpoint (TAO_Endpoint
*endpoint
)
331 if (endpoint
->tag () != TAO_TAG_SHMEM_PROFILE
)
334 TAO_SHMIOP_Endpoint
*shmiop_endpoint
=
335 dynamic_cast <TAO_SHMIOP_Endpoint
*>(endpoint
);
336 if (shmiop_endpoint
== 0)
339 return shmiop_endpoint
;
343 TAO_SHMIOP_Connector::cancel_svc_handler (
344 TAO_Connection_Handler
* svc_handler
)
346 TAO_SHMIOP_Connection_Handler
* handler
=
347 dynamic_cast<TAO_SHMIOP_Connection_Handler
*>(svc_handler
);
350 // Cancel from the connector
351 return this->base_connector_
.cancel (handler
);
356 TAO_END_VERSIONED_NAMESPACE_DECL
358 #endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */