Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Strategies / SHMIOP_Connector.cpp
blobab03c1c0fd47d55dc3fde30bfbe828596c001288
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"
7 #include "tao/debug.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"
16 #include <cstring>
18 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
20 TAO_SHMIOP_Connector::TAO_SHMIOP_Connector ()
21 : TAO_Connector (TAO_TAG_SHMEM_PROFILE),
22 connect_strategy_ (),
23 base_connector_ (0)
27 int
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
34 // for the present.
35 ACE_NEW_RETURN (this->active_connect_strategy_,
36 TAO_Blocked_Connect_Strategy (orb_core),
37 -1);
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 (),
45 orb_core),
46 -1);
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),
53 -1);
55 if (this->base_connector_.open (this->orb_core ()->reactor (),
56 connect_creation_strategy,
57 &this->connect_strategy_,
58 concurrency_strategy) == -1)
59 return -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);
68 return 0;
71 int
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 ();
79 int
80 TAO_SHMIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
82 if (endpoint->tag () != TAO_TAG_SHMEM_PROFILE)
83 return -1;
85 TAO_SHMIOP_Endpoint *shmiop_endpoint =
86 dynamic_cast <TAO_SHMIOP_Endpoint *>(endpoint);
87 if (shmiop_endpoint == 0)
88 return -1;
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 ())
98 case AF_INET:
99 #ifdef ACE_HAS_IPV6
100 case AF_INET6:
101 #endif
102 break;
103 default:
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")));
113 return -1;
116 return 0;
119 TAO_Transport *
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)
133 return 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,
149 synch_options);
151 TAO_SHMIOP_Connection_Handler *svc_handler = 0;
153 // Connect.
154 int result = this->base_connector_.connect (svc_handler,
155 remote_address,
156 synch_options);
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.
162 if (result == -1)
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")));
175 return 0;
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
204 int retval =
205 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
206 transport);
208 // Failure in adding to cache.
209 if (retval == -1)
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")));
221 return 0;
224 if (svc_handler->error_detected (leader_follower))
226 svc_handler->cancel_pending_connection ();
227 transport->purge_entry();
228 return 0;
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",
247 transport->id ()));
249 return 0;
252 svc_handler_auto_ptr.release ();
253 return transport;
256 TAO_Profile *
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);
265 if (r == -1)
267 pfile->_decr_refcnt ();
268 pfile = 0;
271 return pfile;
274 TAO_Profile *
275 TAO_SHMIOP_Connector::make_profile ()
277 // The endpoint should be of the form:
278 // N.n@port/object_key
279 // or:
280 // port/object_key
282 TAO_Profile *profile = 0;
283 ACE_NEW_THROW_EX (profile,
284 TAO_SHMIOP_Profile (this->orb_core ()),
285 CORBA::NO_MEMORY (
286 CORBA::SystemException::_tao_minor_code (
287 TAO::VMCID,
288 ENOMEM),
289 CORBA::COMPLETED_NO));
291 return profile;
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.
310 if (slot == len0
311 && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
312 return 0;
313 else if (slot == len1
314 && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
315 return 0;
317 return -1;
318 // Failure: not an SHMIOP IOR
319 // DO NOT throw an exception here.
322 char
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)
332 return 0;
334 TAO_SHMIOP_Endpoint *shmiop_endpoint =
335 dynamic_cast <TAO_SHMIOP_Endpoint *>(endpoint);
336 if (shmiop_endpoint == 0)
337 return 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);
349 if (handler)
350 // Cancel from the connector
351 return this->base_connector_.cancel (handler);
353 return -1;
356 TAO_END_VERSIONED_NAMESPACE_DECL
358 #endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */