Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Strategies / UIOP_Connector.cpp
blob4e0fb62ff5e1264c19c27c1b34f257e0e0e6d627
1 #include "tao/Strategies/UIOP_Connector.h"
3 #if TAO_HAS_UIOP == 1
5 #include "tao/Strategies/UIOP_Profile.h"
6 #include "tao/debug.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"
18 #include <cstring>
20 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
22 TAO_UIOP_Connector::TAO_UIOP_Connector ()
23 : TAO_Connector (TAO_TAG_UIOP_PROFILE),
24 connect_strategy_ (),
25 base_connector_ (0)
29 TAO_UIOP_Connector::~TAO_UIOP_Connector ()
33 int
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)
40 return -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 (),
48 orb_core),
49 -1);
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),
56 -1);
58 return this->base_connector_.open (this->orb_core ()->reactor (),
59 connect_creation_strategy,
60 &this->connect_strategy_,
61 concurrency_strategy);
64 int
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 ();
74 TAO_Profile *
75 TAO_UIOP_Connector::corbaloc_scan (const char *str, size_t &len)
77 if (this->check_prefix (str) != 0)
78 return 0;
80 const char *separator = std::strchr (str,'|');
81 if (separator == 0)
83 if (TAO_debug_level)
84 TAOLIB_DEBUG ((LM_DEBUG,
85 "TAO (%P|%t) - TAO_UIOP_CONNECTOR::corbaloc_scan error: "
86 "explicit terminating charactor '|' is missing from <%C>",
87 str));
88 return 0;
90 len = separator - str;
91 return this->make_profile ();
95 int
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)
101 return -1;
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")));
120 return -1;
123 return 0;
126 TAO_Transport *
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)
140 return 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,
154 synch_options);
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;
162 // Connect.
163 int result =
164 this->base_connector_.connect (svc_handler,
165 remote_address,
166 synch_options);
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 ();
174 if (result == -1)
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,
183 desc,
184 transport,
185 max_wait_time))
187 if (TAO_debug_level > 2)
188 TAOLIB_ERROR ((LM_ERROR, "TAO (%P|%t) - UIOP_Connector::"
189 "make_connection, "
190 "wait for completion failed\n"));
193 else
195 // Transport is not usable
196 transport = 0;
200 // In case of errors transport is zero
201 if (transport == 0)
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 (),
209 ACE_TEXT("errno")));
211 return 0;
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
237 int retval =
238 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
239 transport);
240 // Failure in adding to cache.
241 if (retval == -1)
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")));
253 return 0;
256 if (svc_handler->error_detected (leader_follower))
258 svc_handler->cancel_pending_connection ();
259 transport->purge_entry();
260 return 0;
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 "
279 "in the reactor.\n",
280 transport->id ()));
282 return 0;
285 svc_handler_auto_ptr.release ();
286 return transport;
290 TAO_Profile *
291 TAO_UIOP_Connector::create_profile (TAO_InputCDR& cdr)
293 TAO_Profile *pfile;
294 ACE_NEW_RETURN (pfile,
295 TAO_UIOP_Profile (this->orb_core ()),
298 const int r = pfile->decode (cdr);
299 if (r == -1)
301 pfile->_decr_refcnt ();
302 pfile = 0;
305 return pfile;
308 TAO_Profile *
309 TAO_UIOP_Connector::make_profile ()
311 TAO_Profile *profile = 0;
312 ACE_NEW_THROW_EX (profile,
313 TAO_UIOP_Profile (this->orb_core ()),
314 CORBA::NO_MEMORY (
315 CORBA::SystemException::_tao_minor_code (
316 TAO::VMCID,
317 ENOMEM),
318 CORBA::COMPLETED_NO));
321 return profile;
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.
340 if (slot == len0
341 && ACE_OS::strncasecmp (endpoint,
342 protocol[0],
343 len0) == 0)
344 return 0;
345 else if (slot == len1
346 && ACE_OS::strncasecmp (endpoint,
347 protocol[1],
348 len1) == 0)
349 return 0;
351 return -1;
352 // Failure: not an UIOP IOR DO NOT throw an exception here.
355 char
356 TAO_UIOP_Connector::object_key_delimiter () const
358 return TAO_UIOP_Profile::object_key_delimiter_;
361 TAO_UIOP_Endpoint *
362 TAO_UIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
364 if (endpoint->tag () != TAO_TAG_UIOP_PROFILE)
365 return 0;
367 TAO_UIOP_Endpoint *uiop_endpoint =
368 dynamic_cast<TAO_UIOP_Endpoint *> (endpoint);
370 if (uiop_endpoint == 0)
371 return 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);
383 if (handler)
384 // Cancel from the connector
385 return this->base_connector_.cancel (handler);
387 return -1;
390 TAO_END_VERSIONED_NAMESPACE_DECL
392 #endif /* TAO_HAS_UIOP == 1 */