Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / IIOP_Connector.cpp
blob068759189d6c9a98c5d3a1bde9ff0d199793bd41
1 // -*- C++ -*-
2 #include "tao/IIOP_Connector.h"
4 #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0)
6 #include "tao/IIOP_Profile.h"
7 #include "tao/debug.h"
8 #include "tao/ORB_Core.h"
9 #include "tao/Protocols_Hooks.h"
10 #include "tao/Connect_Strategy.h"
11 #include "tao/Thread_Lane_Resources.h"
12 #include "tao/Profile_Transport_Resolver.h"
13 #include "tao/Base_Transport_Property.h"
14 #include "tao/Transport.h"
15 #include "tao/Wait_Strategy.h"
16 #include "tao/SystemException.h"
17 #include "tao/LF_Multi_Event.h"
18 #include "ace/OS_NS_strings.h"
19 #include "ace/OS_NS_string.h"
20 #include "ace/OS_NS_time.h"
21 #include "ace/CORBA_macros.h"
22 #include <cstring>
24 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
26 // Uncomment *one* of the the following defines if you want to explicitly induce
27 // the race condition defined in Bug 2654. These enable the introduction of a
28 // slight delay during connection completion processing.
29 // A - before checking the connection_pending status
30 // B - after A but before checking the connection error result
31 // C - acter B but before caching
32 // D - after caching
33 //#define INDUCE_BUG_2654_A
34 //#define INDUCE_BUG_2654_B
35 //#define INDUCE_BUG_2654_C
36 //#define INDUCE_BUG_2654_D
38 //-----------------------------------------------------------------------------
40 /**
41 * @class TAO_Event_Handler_Array_var
43 * @brief Unique pointer like class for an array of Event Handlers.
45 * Used to manage lifecycle of handlers. This class calls
46 * ACE_Event_Handler::remove_reference() on each handler in its destructor
47 * This class started out life as a replacement for the ACE_Event_Handle_var
48 * but is now pared down to be very specific in its role..
50 class TAO_IIOP_Connection_Handler_Array_Guard
52 public:
53 TAO_IIOP_Connection_Handler_Array_Guard (TAO_IIOP_Connection_Handler **p, unsigned count);
54 ~TAO_IIOP_Connection_Handler_Array_Guard ();
56 private:
57 /// Handler.
58 TAO_IIOP_Connection_Handler **ptr_;
59 unsigned count_;
62 TAO_IIOP_Connection_Handler_Array_Guard::TAO_IIOP_Connection_Handler_Array_Guard (
63 TAO_IIOP_Connection_Handler **p,
64 unsigned count)
65 : ptr_ (p),
66 count_ (count)
70 TAO_IIOP_Connection_Handler_Array_Guard::~TAO_IIOP_Connection_Handler_Array_Guard ()
72 ACE_Errno_Guard eguard (errno);
73 if (this->ptr_ != nullptr)
75 for (unsigned i = 0; i < this->count_; i++)
76 this->ptr_[i]->remove_reference ();
80 //---------------------------------------------------------------------------
83 TAO_IIOP_Connector::~TAO_IIOP_Connector ()
87 TAO_IIOP_Connector::TAO_IIOP_Connector ()
88 : TAO_Connector (IOP::TAG_INTERNET_IOP)
89 , connect_strategy_ ()
90 , base_connector_ (nullptr)
94 int
95 TAO_IIOP_Connector::open (TAO_ORB_Core *orb_core)
97 // @todo: The functionality of the following two statements could
98 // be done in the constructor, but that involves changing the
99 // interface of the pluggable transport factory.
101 // Set the ORB Core
102 this->orb_core (orb_core);
104 // Create our connect strategy
105 if (this->create_connect_strategy () == -1)
106 return -1;
108 /// Our connect creation strategy
109 TAO_IIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = nullptr;
111 ACE_NEW_RETURN (connect_creation_strategy,
112 TAO_IIOP_CONNECT_CREATION_STRATEGY
113 (orb_core->thr_mgr (),
114 orb_core),
115 -1);
117 /// Our activation strategy
118 TAO_IIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = nullptr;
120 ACE_NEW_RETURN (concurrency_strategy,
121 TAO_IIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
122 -1);
124 return this->base_connector_.open (this->orb_core ()->reactor (),
125 connect_creation_strategy,
126 &this->connect_strategy_,
127 concurrency_strategy);
131 TAO_IIOP_Connector::close ()
133 delete this->base_connector_.concurrency_strategy ();
134 delete this->base_connector_.creation_strategy ();
135 return this->base_connector_.close ();
139 TAO_IIOP_Connector::supports_parallel_connects() const
141 return 1;
145 TAO_IIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
147 TAO_IIOP_Endpoint *iiop_endpoint = this->remote_endpoint (endpoint);
149 if (iiop_endpoint == nullptr)
150 return -1;
152 const ACE_INET_Addr &remote_address = iiop_endpoint->object_addr ();
154 // Verify that the remote ACE_INET_Addr was initialized properly.
155 // Failure can occur if hostname lookup failed when initializing the
156 // remote ACE_INET_Addr.
157 #if defined (ACE_HAS_IPV6)
158 if (remote_address.get_type () != AF_INET &&
159 remote_address.get_type () != AF_INET6)
160 #else /* ACE_HAS_IPV6 */
161 if (remote_address.get_type () != AF_INET)
162 #endif /* !ACE_HAS_IPV6 */
164 if (TAO_debug_level > 0)
166 TAOLIB_DEBUG ((LM_DEBUG,
167 ACE_TEXT ("TAO (%P|%t) - IIOP connection failed.\n")
168 ACE_TEXT (" This is most likely ")
169 ACE_TEXT ("due to a hostname lookup ")
170 ACE_TEXT ("failure.\n")));
173 return -1;
176 return 0;
179 TAO_Transport *
180 TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
181 TAO_Transport_Descriptor_Interface &desc,
182 ACE_Time_Value *timeout)
184 TAO_IIOP_Connection_Handler *svc_handler = nullptr;
185 TAO_IIOP_Endpoint *iiop_endpoint =
186 this->remote_endpoint (desc.endpoint());
187 if (iiop_endpoint == nullptr)
188 return nullptr;
190 int const result =
191 this->begin_connection (svc_handler, r, iiop_endpoint, timeout);
193 // Make sure that we always do a remove_reference
194 ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
196 if (result == -1 && errno != EWOULDBLOCK)
198 // Give users a clue to the problem.
199 if (TAO_debug_level > 1)
201 TAOLIB_ERROR ((LM_ERROR,
202 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::make_connection, ")
203 ACE_TEXT("connection to <%C:%d> failed (%p)\n"),
204 iiop_endpoint->host (),
205 iiop_endpoint->port (),
206 ACE_TEXT("errno")));
208 return nullptr;
211 TAO_IIOP_Connection_Handler **sh_ptr = &svc_handler;
212 TAO_IIOP_Endpoint **ep_ptr = &iiop_endpoint;
213 TAO_LF_Multi_Event mev;
214 mev.add_event (svc_handler);
216 TAO_Transport *transport =
217 this->complete_connection (result,
218 desc,
219 sh_ptr,
220 ep_ptr,
223 &mev,
224 timeout);
226 // If complete_connection was unsuccessful then remove
227 // the last reference that we have to the svc_handler.
228 if (transport == nullptr)
230 if (TAO_debug_level > 1)
232 TAOLIB_ERROR ((LM_ERROR,
233 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::make_connection, ")
234 ACE_TEXT ("connection to <%C:%d> completed unsuccessfully\n"),
235 iiop_endpoint->host (),
236 iiop_endpoint->port ()));
238 return nullptr;
241 svc_handler_auto_ptr.release ();
242 return transport;
245 TAO_Transport *
246 TAO_IIOP_Connector::make_parallel_connection (
247 TAO::Profile_Transport_Resolver * r,
248 TAO_Transport_Descriptor_Interface & desc,
249 ACE_Time_Value * timeout)
251 TAO_Endpoint *root_ep = desc.endpoint();
252 unsigned max_count = 1;
253 long ns_stagger =
254 this->orb_core ()->orb_params ()->parallel_connect_delay ();
255 time_t sec_stagger = ns_stagger/1000;
256 ns_stagger = (ns_stagger % 1000) * 1000000;
257 for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(), nullptr);
258 ep != nullptr;
259 ep = ep->next_filtered (this->orb_core(), root_ep))
260 ++max_count;
262 if (TAO_debug_level > 2)
263 TAOLIB_DEBUG ((LM_DEBUG,
264 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::")
265 ACE_TEXT ("make_parallel_connection, ")
266 ACE_TEXT ("to %d endpoints\n"), max_count));
267 TAO_IIOP_Endpoint **eplist = nullptr;
268 TAO_IIOP_Connection_Handler **shlist = nullptr;
269 ACE_NEW_RETURN (shlist, TAO_IIOP_Connection_Handler *[max_count], nullptr);
270 ACE_NEW_RETURN (eplist, TAO_IIOP_Endpoint *[max_count], nullptr);
272 TAO_LF_Multi_Event mev;
273 int result = 0;
274 unsigned count = 0;
275 for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(),nullptr);
276 ep != nullptr;
277 ep = ep->next_filtered(this->orb_core(),root_ep))
279 eplist[count] = this->remote_endpoint (ep);
280 shlist[count] = nullptr;
281 result = this->begin_connection (shlist[count],
283 eplist[count],
284 timeout);
286 // The connection may fail because it is slow, or for other reasons.
287 // If it was an incomplete non-blocking connection, add it to the list
288 // to be waited on, otherwise remove the reference to the handler and
289 // move on to the next endpoint.
290 if (result == -1)
292 if (errno == EWOULDBLOCK)
294 mev.add_event(shlist[count++]);
295 if (ep->next() != nullptr)
297 struct timespec nsleep = {sec_stagger, ns_stagger};
298 ACE_OS::nanosleep (&nsleep);
299 result = this->active_connect_strategy_->poll (&mev);
300 if (result != -1)
301 break;
304 else
306 shlist[count]->remove_reference(); // done bump the list count
308 continue;
311 if (result != -1) // we have a winner!
313 count++;
314 break; // no waiting involved since a connection is completed
318 TAO_Transport *winner = nullptr;
319 if (count > 0) // only complete if at least one pending or success
321 // Make sure that we always do a remove_reference for every member
322 // of the list
323 TAO_IIOP_Connection_Handler_Array_Guard svc_handler_auto_ptr (shlist, count);
325 winner = this->complete_connection (result,
326 desc,
327 shlist,
328 eplist,
329 count,r,
330 &mev,
331 timeout);
333 // We add here an extra reference so that when svc_handler_auto_ptr
334 // will go out of scope the winner will be still alive.
335 if (winner)
336 winner->add_reference ();
339 delete [] shlist; // reference reductions should have been done already
340 delete [] eplist;
341 return winner;
345 TAO_IIOP_Connector::begin_connection (TAO_IIOP_Connection_Handler *&svc_handler,
346 TAO::Profile_Transport_Resolver *r,
347 TAO_IIOP_Endpoint *iiop_endpoint,
348 ACE_Time_Value *timeout)
350 const ACE_INET_Addr &remote_address = iiop_endpoint->object_addr ();
352 u_short port = this->orb_core ()->orb_params ()->iiop_client_port_base ();
353 ACE_UINT32 const ia_any = INADDR_ANY;
354 ACE_INET_Addr local_addr(port, ia_any);
356 if (iiop_endpoint->is_preferred_network ())
358 local_addr.set (port, iiop_endpoint->preferred_network ());
360 #if defined (ACE_HAS_IPV6)
361 else if (remote_address.get_type () == AF_INET6)
363 local_addr.set (port, ACE_IPV6_ANY);
365 #endif /* ACE_HAS_IPV6 */
367 if (TAO_debug_level > 2)
369 TAOLIB_DEBUG ((LM_DEBUG,
370 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::begin_connection, ")
371 ACE_TEXT ("to <%C:%d> which should %s\n"),
372 iiop_endpoint->host(),
373 iiop_endpoint->port(),
374 r->blocked_connect () ? ACE_TEXT("block") : ACE_TEXT("nonblock")));
377 // Get the right synch options
378 ACE_Synch_Options synch_options;
380 this->active_connect_strategy_->synch_options (timeout, synch_options);
382 // The code used to set the timeout to zero, with the intent of
383 // polling the reactor for connection completion. However, the side-effect
384 // was to cause the connection to timeout immediately.
385 svc_handler = nullptr;
387 int result = -1;
388 u_short span = this->orb_core ()->orb_params ()->iiop_client_port_span ();
389 for (u_short offset = 0; offset <= span; ++offset)
391 local_addr.set_port_number (port + offset);
392 if (TAO_debug_level > 0 && (port + offset) > 0 )
394 TAOLIB_DEBUG ((LM_DEBUG,
395 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::begin_connection, ")
396 ACE_TEXT ("trying local port %d\n"),
397 port + offset));
399 result = this->base_connector_.connect (svc_handler,
400 remote_address,
401 synch_options,
402 local_addr);
403 if (result == 0 || (errno != EADDRINUSE && errno != EINVAL))
405 break;
407 else
409 if (svc_handler != nullptr)
411 svc_handler->remove_reference ();
412 svc_handler = nullptr;
417 return result;
420 namespace TAO_IIOP
422 /// RAII holder for a TAO_Transport list
423 class TList_Holder
425 public:
426 TList_Holder (size_t count)
427 : tlist_ (nullptr)
429 // Resources are acquired during initialization (RAII)
430 ACE_NEW (tlist_, TAO_Transport*[count]);
433 ~TList_Holder ()
435 // Resources are unacquired during uninitialization
436 delete [] tlist_;
439 operator TAO_Transport** ()
441 return tlist_;
444 private:
445 TAO_Transport** tlist_;
446 private:
447 void operator= (const TList_Holder &) = delete;
448 TList_Holder (const TList_Holder &) = delete;
452 TAO_Transport *
453 TAO_IIOP_Connector::complete_connection (int result,
454 TAO_Transport_Descriptor_Interface &desc,
455 TAO_IIOP_Connection_Handler **&sh_list,
456 TAO_IIOP_Endpoint **ep_list,
457 unsigned count,
458 TAO::Profile_Transport_Resolver *r,
459 TAO_LF_Multi_Event *mev,
460 ACE_Time_Value *timeout)
462 TAO_IIOP::TList_Holder tlist(count);
464 TAO_Transport *transport = nullptr;
466 // populate the transport list
467 for (unsigned i = 0; i < count; i++)
468 tlist[i] = sh_list[i]->transport();
470 if (result != -1)
472 // We received a completed connection and 0 or more pending.
473 // the winner is the last member of the list, because the
474 // iterator stopped on a successful connect.
475 transport = tlist[count-1];
477 this->cleanup_pending (transport, tlist, count);
479 desc.reset_endpoint (ep_list[count-1]);
480 TAO::Transport_Cache_Manager &tcm =
481 this->orb_core ()->lane_resources ().transport_cache ();
482 if (tcm.cache_transport (&desc, transport) == -1)
484 // Cache is full, so close the connection again
485 sh_list[count-1]->close ();
486 transport = nullptr;
489 else
491 if (count == 1)
493 transport = tlist[0];
494 desc.reset_endpoint(ep_list[0]);
495 if (!this->wait_for_connection_completion (r,
496 desc,
497 transport,
498 timeout))
500 if (TAO_debug_level > 2)
501 TAOLIB_ERROR ((LM_ERROR,
502 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::")
503 ACE_TEXT ("complete_connection, wait for completion ")
504 ACE_TEXT ("failed for 1 pending connect\n")));
507 else
509 if (!this->wait_for_connection_completion (r,
510 transport,
511 tlist,
512 count,
513 mev,
514 timeout))
516 if (TAO_debug_level > 2)
517 TAOLIB_ERROR ((LM_ERROR,
518 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::")
519 ACE_TEXT ("complete_connection, wait for completion ")
520 ACE_TEXT ("failed for %d pending connects\n"),
521 count));
526 #if defined (INDUCE_BUG_2654_A)
527 // This is where the fatal error would occur. A pending asynch
528 // connection would fail, the failure handled by another thread,
529 // closing the connection. However the remainder of this method
530 // only checked to see if the keep_waiting status was true, and bump
531 // the refcount then. However if the status was really
532 // error_detected, then no bump in refcount occurred allowing the
533 // connection_handler's close_handler method to effectively steal
534 // the reference to be handed back to the caller. That would then
535 // trigger an abort as the profile_transport_resolver (our caller)
536 // to delete the transport while it is still cached.
537 ACE_Time_Value udelay(0,600);
538 struct timespec ts = udelay;
539 ACE_OS::nanosleep (&ts);
540 #endif // INDUCE_BUG_2654_A
542 // At this point, the connection has been successfully created
543 // connected or not connected, but we have a connection.
544 TAO_IIOP_Connection_Handler *svc_handler = nullptr;
545 TAO_IIOP_Endpoint *iiop_endpoint = nullptr;
547 if (transport != nullptr)
549 for (unsigned i = 0; i < count; i++)
551 if (transport == tlist[i])
553 svc_handler = sh_list[i];
554 iiop_endpoint = ep_list[i];
555 break;
559 else
561 // In case of errors transport is zero
562 // Give users a clue to the problem.
563 if (TAO_debug_level > 3)
565 for (unsigned i = 0; i < count; i++)
567 TAOLIB_ERROR ((LM_ERROR,
568 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::complete_connection,")
569 ACE_TEXT (" connection to <%C:%d> failed (%p)\n"),
570 ep_list[i]->host (),
571 ep_list[i]->port (),
572 ACE_TEXT("errno")));
575 return nullptr;
578 TAO_Leader_Follower &leader_follower = this->orb_core ()->leader_follower ();
580 if (svc_handler->keep_waiting(leader_follower))
582 svc_handler->connection_pending();
585 #if defined (INDUCE_BUG_2654_B)
586 // It is possible for the connection failure to be processed after bumping
587 // the reference count and before we plan to cache the connection. Prior to
588 // fixing bug 2654, this would lead to a failed connection in the cache.
589 // Though not a fatal condition, it was certainly wasteful of resources.
590 ACE_Time_Value udelay(0,600);
591 struct timespec ts = udelay;
592 ACE_OS::nanosleep (&ts);
593 #endif // INDUCE_BUG_2654_B
595 // Fix for bug 2654.
596 if (transport->connection_handler()->error_detected(leader_follower))
598 if (TAO_debug_level > 0)
599 TAOLIB_DEBUG((LM_DEBUG,
600 ACE_TEXT("TAO (%P|%t) - IIOP_Connector::make_connection, ")
601 ACE_TEXT("transport in error before cache!\n")));
602 transport->connection_handler()->cancel_pending_connection();
603 return nullptr;
606 if (TAO_debug_level > 2)
608 TAOLIB_DEBUG ((LM_DEBUG,
609 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::make_connection, ")
610 ACE_TEXT ("new %s connection to <%C:%d> on Transport[%d]\n"),
611 transport->is_connected() ?
612 ACE_TEXT("connected") : ACE_TEXT("not connected"),
613 iiop_endpoint->host (),
614 iiop_endpoint->port (),
615 svc_handler->peer ().get_handle ()));
618 #if defined (INDUCE_BUG_2654_C)
619 // This sets up the possibility that a failed connection is detected after we
620 // checked the connection status but before we cached the connection. This
621 // will allow a failed connection to be cached
622 ACE_Time_Value udelay(0,600);
623 struct timespec ts = udelay;
624 ACE_OS::nanosleep (&ts);
625 #endif // INDUCE_BUG_2654_C
626 int retval = 0;
628 // Only for parallel connect, update the cache to show this in idle state
629 if (count > 1 && desc.reset_endpoint (iiop_endpoint))
631 retval = this->orb_core ()->
632 lane_resources ().transport_cache ().cache_transport (&desc,
633 transport);
636 // Failure in adding to cache
637 if (retval == -1)
639 // Close the handler.
640 svc_handler->close ();
642 if (TAO_debug_level > 0)
644 TAOLIB_ERROR ((LM_ERROR,
645 ACE_TEXT ("TAO (%P|%t) IIOP_Connector::make_connection, ")
646 ACE_TEXT ("could not add new connection to cache\n")));
649 return nullptr;
652 // Other part of fix for bug 2654.
653 // It is possible that after checking for a connection failure but
654 // before caching, the connection really failed, thus an invalid
655 // connection is put into the cache. Thus we do one last status
656 // check before handing the connection back to the caller.
657 if (svc_handler->error_detected(leader_follower))
659 if (TAO_debug_level > 0)
660 TAOLIB_DEBUG((LM_DEBUG,
661 ACE_TEXT("TAO (%P|%t) - IIOP_Connector::make_connection, ")
662 ACE_TEXT("transport in error after cache!\n")));
663 svc_handler->cancel_pending_connection();
664 transport->purge_entry();
665 return nullptr;
669 #if defined (INDUCE_BUG_2654_D)
670 // at this point the connection handler's close connection will manage
671 // purging the entry from the cache so we are fine there.
672 ACE_Time_Value udelay(0,600);
673 struct timespec ts = udelay;
674 ACE_OS::nanosleep (&ts);
675 #endif // INDUCE_BUG_2654_D
677 // Have the transport register itself with the wait strategy and
678 // deal with the transport cache if there is a failure.
679 if (!transport->register_if_necessary ())
681 return nullptr;
684 return transport;
687 TAO_Profile *
688 TAO_IIOP_Connector::create_profile (TAO_InputCDR& cdr)
690 TAO_Profile *pfile = nullptr;
691 ACE_NEW_RETURN (pfile,
692 TAO_IIOP_Profile (this->orb_core ()),
693 nullptr);
695 int const r = pfile->decode (cdr);
696 if (r == -1)
698 pfile->_decr_refcnt ();
699 pfile = nullptr;
702 return pfile;
705 TAO_Profile *
706 TAO_IIOP_Connector::make_profile ()
708 // The endpoint should be of the form:
709 // N.n@host:port/object_key
710 // or:
711 // host:port/object_key
713 TAO_Profile *profile = nullptr;
714 ACE_NEW_THROW_EX (profile,
715 TAO_IIOP_Profile (this->orb_core ()),
716 CORBA::NO_MEMORY (
717 CORBA::SystemException::_tao_minor_code (
719 ENOMEM),
720 CORBA::COMPLETED_NO));
722 return profile;
726 TAO_IIOP_Connector::check_prefix (const char *endpoint)
728 // Check for a valid string
729 if (!endpoint || !*endpoint)
730 return -1; // Failure
732 static const char *protocol[] = { "iiop", "iioploc" };
734 size_t const slot = std::strchr (endpoint, ':') - endpoint;
735 if (slot == 0) // an empty string is valid for corbaloc.
736 return 0;
738 size_t const len0 = std::strlen (protocol[0]);
739 size_t const len1 = std::strlen (protocol[1]);
741 // Check for the proper prefix in the IOR. If the proper prefix
742 // isn't in the IOR then it is not an IOR we can use.
743 if (slot == len0 && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
744 return 0;
745 else if (slot == len1 && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
746 return 0;
748 return -1;
749 // Failure: not an IIOP IOR
750 // DO NOT throw an exception here.
753 char
754 TAO_IIOP_Connector::object_key_delimiter () const
756 return TAO_IIOP_Profile::object_key_delimiter_;
759 TAO_IIOP_Endpoint *
760 TAO_IIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
762 if (endpoint->tag () != IOP::TAG_INTERNET_IOP)
763 return nullptr;
765 TAO_IIOP_Endpoint *iiop_endpoint =
766 dynamic_cast<TAO_IIOP_Endpoint *> (endpoint );
768 if (iiop_endpoint == nullptr)
769 return nullptr;
771 return iiop_endpoint;
775 TAO_IIOP_Connector::cancel_svc_handler (
776 TAO_Connection_Handler * svc_handler)
778 TAO_IIOP_Connection_Handler* handler=
779 dynamic_cast<TAO_IIOP_Connection_Handler*>(svc_handler);
781 // Cancel from the connector
782 if (handler)
784 handler->abort();
785 return this->base_connector_.cancel (handler);
788 return -1;
791 TAO_END_VERSIONED_NAMESPACE_DECL
793 #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */