Restore build on FreeBSD.
[getmangos.git] / dep / ACE_wrappers / ace / Connector.cpp
blob3e68abc097a3661baafceffe3f140790fa8aa074
1 // $Id: Connector.cpp 81991 2008-06-16 19:05:40Z elliott_c $
3 #ifndef ACE_CONNECTOR_CPP
4 #define ACE_CONNECTOR_CPP
6 #include "ace/Connector.h"
7 #include "ace/ACE.h"
8 #include "ace/OS_NS_stdio.h"
9 #include "ace/OS_NS_string.h"
10 #include "ace/os_include/os_fcntl.h" /* Has ACE_NONBLOCK */
12 #if !defined (ACE_LACKS_PRAGMA_ONCE)
13 # pragma once
14 #endif /* ACE_LACKS_PRAGMA_ONCE */
16 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
18 ACE_ALLOC_HOOK_DEFINE(ACE_Connector)
20 template <class SVC_HANDLER>
21 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler
22 (ACE_Connector_Base<SVC_HANDLER> &connector,
23 SVC_HANDLER *sh,
24 long id)
25 : connector_ (connector)
26 , svc_handler_ (sh)
27 , timer_id_ (id)
29 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler");
31 this->reference_counting_policy ().value
32 (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
35 template <class SVC_HANDLER> SVC_HANDLER *
36 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::svc_handler (void)
38 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::svc_handler");
39 return this->svc_handler_;
42 template <class SVC_HANDLER> long
43 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id (void)
45 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id");
46 return this->timer_id_;
49 template <class SVC_HANDLER> void
50 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id (long id)
52 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id");
53 this->timer_id_ = id;
56 template <class SVC_HANDLER> void
57 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump (void) const
59 #if defined (ACE_HAS_DUMP)
60 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump");
62 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
63 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("svc_handler_ = %x"), this->svc_handler_));
64 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_id_ = %d"), this->timer_id_));
65 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
66 #endif /* ACE_HAS_DUMP */
69 template <class SVC_HANDLER> bool
70 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
72 // Make sure that we haven't already initialized the Svc_Handler.
73 if (!this->svc_handler_)
74 return false;
77 // Exclusive access to the Reactor.
78 ACE_GUARD_RETURN (ACE_Lock,
79 ace_mon,
80 this->reactor ()->lock (),
81 0);
83 // Double check.
84 if (!this->svc_handler_)
85 return false;
87 // Remember the Svc_Handler.
88 sh = this->svc_handler_;
89 ACE_HANDLE h = sh->get_handle ();
90 this->svc_handler_ = 0;
92 // Remove this handle from the set of non-blocking handles
93 // in the Connector.
94 this->connector_.non_blocking_handles ().remove (h);
96 // Cancel timer.
97 if (this->reactor ()->cancel_timer (this->timer_id (),
99 0) == -1)
100 return false;
102 // Remove from Reactor.
103 if (this->reactor ()->remove_handler (
105 ACE_Event_Handler::ALL_EVENTS_MASK) == -1)
106 return false;
109 return true;
113 template <class SVC_HANDLER> int
114 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout
115 (const ACE_Time_Value &tv,
116 const void *arg)
118 // This method is called if a connection times out before completing.
119 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout");
121 SVC_HANDLER *svc_handler = 0;
122 int retval = this->close (svc_handler) ? 0 : -1;
124 // Forward to the SVC_HANDLER the <arg> that was passed in as a
125 // magic cookie during ACE_Connector::connect(). This gives the
126 // SVC_HANDLER an opportunity to take corrective action (e.g., wait
127 // a few milliseconds and try to reconnect again.
128 if (svc_handler != 0 && svc_handler->handle_timeout (tv, arg) == -1)
129 svc_handler->handle_close (svc_handler->get_handle (),
130 ACE_Event_Handler::TIMER_MASK);
132 return retval;
136 template <class SVC_HANDLER> int
137 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE)
139 // Called when a failure occurs during asynchronous connection
140 // establishment.
141 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input");
143 SVC_HANDLER *svc_handler = 0;
144 int const retval = this->close (svc_handler) ? 0 : -1;
146 // Close Svc_Handler.
147 if (svc_handler != 0)
148 svc_handler->close (NORMAL_CLOSE_OPERATION);
150 return retval;
153 template <class SVC_HANDLER> int
154 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle)
156 // Called when a connection is establishment asynchronous.
157 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output");
159 // Grab the connector ref before smashing ourselves in close().
160 ACE_Connector_Base<SVC_HANDLER> &connector = this->connector_;
161 SVC_HANDLER *svc_handler = 0;
162 int const retval = this->close (svc_handler) ? 0 : -1;
164 if (svc_handler != 0)
165 connector.initialize_svc_handler (handle, svc_handler);
167 return retval;
170 template <class SVC_HANDLER> int
171 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception (ACE_HANDLE h)
173 // On Win32, the except mask must also be set for asynchronous
174 // connects.
175 ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception");
176 return this->handle_output (h);
179 template <class SVC_HANDLER> int
180 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::resume_handler (void)
182 return ACE_Event_Handler::ACE_EVENT_HANDLER_NOT_RESUMED;
185 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
186 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump (void) const
188 #if defined (ACE_HAS_DUMP)
189 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump");
191 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
192 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = %d"), this->flags_));
193 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
194 #endif /* ACE_HAS_DUMP */
197 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
198 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
200 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::make_svc_handler");
202 if (sh == 0)
203 ACE_NEW_RETURN (sh,
204 SVC_HANDLER,
205 -1);
207 // Set the reactor of the newly created <SVC_HANDLER> to the same
208 // reactor that this <Connector> is using.
209 sh->reactor (this->reactor ());
210 return 0;
213 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
214 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::activate_svc_handler (SVC_HANDLER *svc_handler)
216 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::activate_svc_handler");
217 // No errors initially
218 int error = 0;
220 // See if we should enable non-blocking I/O on the <svc_handler>'s
221 // peer.
222 if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0)
224 if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
225 error = 1;
227 // Otherwise, make sure it's disabled by default.
228 else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
229 error = 1;
231 // We are connected now, so try to open things up.
232 if (error || svc_handler->open ((void *) this) == -1)
234 // Make sure to close down the <svc_handler> to avoid descriptor
235 // leaks.
236 // The connection was already made; so this close is a "normal"
237 // close operation.
238 svc_handler->close (NORMAL_CLOSE_OPERATION);
239 return -1;
241 else
242 return 0;
245 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_PEER_CONNECTOR &
246 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connector (void) const
248 return const_cast<ACE_PEER_CONNECTOR &> (this->connector_);
251 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
252 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
253 (SVC_HANDLER *&svc_handler,
254 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
255 ACE_Time_Value *timeout,
256 const ACE_PEER_CONNECTOR_ADDR &local_addr,
257 int reuse_addr,
258 int flags,
259 int perms)
261 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler");
263 return this->connector_.connect (svc_handler->peer (),
264 remote_addr,
265 timeout,
266 local_addr,
267 reuse_addr,
268 flags,
269 perms);
272 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
273 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
274 (SVC_HANDLER *&svc_handler,
275 SVC_HANDLER *&sh_copy,
276 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
277 ACE_Time_Value *timeout,
278 const ACE_PEER_CONNECTOR_ADDR &local_addr,
279 int reuse_addr,
280 int flags,
281 int perms)
283 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler");
285 sh_copy = svc_handler;
286 return this->connector_.connect (svc_handler->peer (),
287 remote_addr,
288 timeout,
289 local_addr,
290 reuse_addr,
291 flags,
292 perms);
295 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
296 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open (ACE_Reactor *r, int flags)
298 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open");
299 this->reactor (r);
300 this->flags_ = flags;
301 return 0;
304 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
305 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Connector (ACE_Reactor *r,
306 int flags)
308 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Connector");
309 (void) this->open (r, flags);
312 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
313 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect
314 (SVC_HANDLER *&sh,
315 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
316 const ACE_Synch_Options &synch_options,
317 const ACE_PEER_CONNECTOR_ADDR &local_addr,
318 int reuse_addr,
319 int flags,
320 int perms)
322 // Initiate connection to peer.
323 return this->connect_i (sh,
325 remote_addr,
326 synch_options,
327 local_addr,
328 reuse_addr,
329 flags,
330 perms);
333 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
334 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect
335 (SVC_HANDLER *&sh,
336 SVC_HANDLER *&sh_copy,
337 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
338 const ACE_Synch_Options &synch_options,
339 const ACE_PEER_CONNECTOR_ADDR &local_addr,
340 int reuse_addr,
341 int flags,
342 int perms)
344 // Initiate connection to peer.
345 return this->connect_i (sh,
346 &sh_copy,
347 remote_addr,
348 synch_options,
349 local_addr,
350 reuse_addr,
351 flags,
352 perms);
355 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
356 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_i
357 (SVC_HANDLER *&sh,
358 SVC_HANDLER **sh_copy,
359 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
360 const ACE_Synch_Options &synch_options,
361 const ACE_PEER_CONNECTOR_ADDR &local_addr,
362 int reuse_addr,
363 int flags,
364 int perms)
366 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_i");
368 // If the user hasn't supplied us with a <SVC_HANDLER> we'll use the
369 // factory method to create one. Otherwise, things will remain as
370 // they are...
371 if (this->make_svc_handler (sh) == -1)
372 return -1;
374 ACE_Time_Value *timeout = 0;
375 int const use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
377 if (use_reactor)
378 timeout = const_cast<ACE_Time_Value *> (&ACE_Time_Value::zero);
379 else
380 timeout = const_cast<ACE_Time_Value *> (synch_options.time_value ());
382 int result;
383 if (sh_copy == 0)
384 result = this->connect_svc_handler (sh,
385 remote_addr,
386 timeout,
387 local_addr,
388 reuse_addr,
389 flags,
390 perms);
391 else
392 result = this->connect_svc_handler (sh,
393 *sh_copy,
394 remote_addr,
395 timeout,
396 local_addr,
397 reuse_addr,
398 flags,
399 perms);
401 // Activate immediately if we are connected.
402 if (result != -1)
403 return this->activate_svc_handler (sh);
405 // Delegate to connection strategy.
406 if (use_reactor && ACE_OS::last_error () == EWOULDBLOCK)
408 // If the connection hasn't completed and we are using
409 // non-blocking semantics then register
410 // ACE_NonBlocking_Connect_Handler with the ACE_Reactor so that
411 // it will call us back when the connection is complete or we
412 // timeout, whichever comes first...
413 int result;
415 if (sh_copy == 0)
416 result = this->nonblocking_connect (sh, synch_options);
417 else
418 result = this->nonblocking_connect (*sh_copy, synch_options);
420 // If for some reason the <nonblocking_connect> call failed, then <errno>
421 // will be set to the new error. If the call succeeds, however,
422 // we need to make sure that <errno> remains set to
423 // <EWOULDBLOCK>.
424 if (result == 0)
425 errno = EWOULDBLOCK;
427 else
429 // Save/restore errno.
430 ACE_Errno_Guard error (errno);
431 // Make sure to close down the service handler to avoid handle
432 // leaks.
433 if (sh_copy == 0)
435 if (sh)
436 sh->close (CLOSE_DURING_NEW_CONNECTION);
438 else if (*sh_copy)
439 (*sh_copy)->close (CLOSE_DURING_NEW_CONNECTION);
442 return -1;
445 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
446 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_n
447 (size_t n,
448 SVC_HANDLER *sh[],
449 ACE_PEER_CONNECTOR_ADDR remote_addrs[],
450 ACE_TCHAR *failed_svc_handlers,
451 const ACE_Synch_Options &synch_options)
453 int result = 0;
455 for (size_t i = 0; i < n; i++)
457 if (this->connect (sh[i], remote_addrs[i], synch_options) == -1
458 && !(synch_options[ACE_Synch_Options::USE_REACTOR]
459 && errno == EWOULDBLOCK))
461 result = -1;
462 if (failed_svc_handlers != 0)
463 // Mark this entry as having failed.
464 failed_svc_handlers[i] = 1;
466 else if (failed_svc_handlers != 0)
467 // Mark this entry as having succeeded.
468 failed_svc_handlers[i] = 0;
471 return result;
474 // Cancel a <svc_handler> that was started asynchronously.
475 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
476 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::cancel (SVC_HANDLER *sh)
478 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::cancel");
480 ACE_Event_Handler *handler =
481 this->reactor ()->find_handler (sh->get_handle ());
483 if (handler == 0)
484 return -1;
486 // find_handler() increments handler's refcount; ensure we decrement it.
487 ACE_Event_Handler_var safe_handler (handler);
489 NBCH *nbch =
490 dynamic_cast<NBCH *> (handler);
492 if (nbch == 0)
493 return -1;
495 SVC_HANDLER *tmp_sh = 0;
497 if (nbch->close (tmp_sh) == false)
498 return -1;
500 return 0;
503 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
504 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::nonblocking_connect
505 (SVC_HANDLER *sh,
506 const ACE_Synch_Options &synch_options)
508 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::nonblocking_connect");
510 // Must have a valid Reactor for non-blocking connects to work.
511 if (this->reactor () == 0)
512 return -1;
514 // Register the pending SVC_HANDLER so that it can be activated
515 // later on when the connection completes.
517 ACE_HANDLE handle = sh->get_handle ();
518 long timer_id = -1;
519 ACE_Time_Value *tv = 0;
520 NBCH *nbch = 0;
522 ACE_NEW_RETURN (nbch,
523 NBCH (*this,
525 -1),
526 -1);
528 ACE_Event_Handler_var safe_nbch (nbch);
530 // Exclusive access to the Reactor.
531 ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1);
533 // Register handle with the reactor for connection events.
534 ACE_Reactor_Mask mask = ACE_Event_Handler::CONNECT_MASK;
535 if (this->reactor ()->register_handler (handle,
536 nbch,
537 mask) == -1)
538 goto reactor_registration_failure;
540 // Add handle to non-blocking handle set.
541 this->non_blocking_handles ().insert (handle);
543 // If we're starting connection under timer control then we need to
544 // schedule a timeout with the ACE_Reactor.
545 tv = const_cast<ACE_Time_Value *> (synch_options.time_value ());
546 if (tv != 0)
548 timer_id =
549 this->reactor ()->schedule_timer (nbch,
550 synch_options.arg (),
551 *tv);
552 if (timer_id == -1)
553 goto timer_registration_failure;
555 // Remember timer id.
556 nbch->timer_id (timer_id);
559 return 0;
561 // Undo previous actions using the ol' "goto label and fallthru"
562 // trick...
563 timer_registration_failure:
565 // Remove from Reactor.
566 this->reactor ()->remove_handler (handle, mask);
568 // Remove handle from the set of non-blocking handles.
569 this->non_blocking_handles ().remove (handle);
571 /* FALLTHRU */
573 reactor_registration_failure:
574 // Close the svc_handler
576 sh->close (CLOSE_DURING_NEW_CONNECTION);
578 return -1;
581 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
582 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connector (void)
584 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connector");
586 this->close ();
589 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
590 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::initialize_svc_handler
591 (ACE_HANDLE handle,
592 SVC_HANDLER *svc_handler)
594 // Try to find out if the reactor uses event associations for the
595 // handles it waits on. If so we need to reset it.
596 int reset_new_handle =
597 this->reactor ()->uses_event_associations ();
599 if (reset_new_handle)
600 this->connector_.reset_new_handle (handle);
602 // Transfer ownership of the ACE_HANDLE to the SVC_HANDLER.
603 svc_handler->set_handle (handle);
605 ACE_PEER_CONNECTOR_ADDR raddr;
607 // Check to see if we're connected.
608 if (svc_handler->peer ().get_remote_addr (raddr) != -1)
609 this->activate_svc_handler (svc_handler);
610 else // Somethings gone wrong, so close down...
612 #if defined (ACE_WIN32)
613 // Win32 (at least prior to Windows 2000) has a timing problem.
614 // If you check to see if the connection has completed too fast,
615 // it will fail - so wait 35 milliseconds to let it catch up.
616 ACE_Time_Value tv (0, ACE_NON_BLOCKING_BUG_DELAY);
617 ACE_OS::sleep (tv);
618 if (svc_handler->peer ().get_remote_addr (raddr) != -1)
619 this->activate_svc_handler (svc_handler);
620 else // do the svc handler close below...
621 #endif /* ACE_WIN32 */
622 svc_handler->close (NORMAL_CLOSE_OPERATION);
626 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
627 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::reactor (ACE_Reactor *reactor)
629 this->reactor_ = reactor;
632 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Reactor *
633 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::reactor (void) const
635 return this->reactor_;
638 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Unbounded_Set<ACE_HANDLE> &
639 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::non_blocking_handles (void)
641 return this->non_blocking_handles_;
644 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
645 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::close (void)
647 // If there are no non-blocking handle pending, return immediately.
648 if (this->non_blocking_handles ().size () == 0)
649 return 0;
651 // Exclusive access to the Reactor.
652 ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1);
654 // Go through all the non-blocking handles. It is necessary to
655 // create a new iterator each time because we remove from the handle
656 // set when we cancel the Svc_Handler.
657 ACE_HANDLE *handle = 0;
658 while (1)
660 ACE_Unbounded_Set_Iterator<ACE_HANDLE>
661 iterator (this->non_blocking_handles ());
662 if (!iterator.next (handle))
663 break;
665 ACE_Event_Handler *handler =
666 this->reactor ()->find_handler (*handle);
667 if (handler == 0)
669 ACE_ERROR ((LM_ERROR,
670 ACE_TEXT ("%t: Connector::close h %d, no handler\n"),
671 *handle));
672 // Remove handle from the set of non-blocking handles.
673 this->non_blocking_handles ().remove (*handle);
674 continue;
677 // find_handler() incremented handler's refcount; ensure it's decremented
678 ACE_Event_Handler_var safe_handler (handler);
679 NBCH *nbch = dynamic_cast<NBCH *> (handler);
680 if (nbch == 0)
682 ACE_ERROR ((LM_ERROR,
683 ACE_TEXT ("%t: Connector::close h %d handler %@ ")
684 ACE_TEXT ("not a legit handler\n"),
685 *handle,
686 handler));
687 // Remove handle from the set of non-blocking handles.
688 this->non_blocking_handles ().remove (*handle);
689 continue;
691 SVC_HANDLER *svc_handler = nbch->svc_handler ();
693 // Cancel the non-blocking connection.
694 this->cancel (svc_handler);
696 // Close the associated Svc_Handler.
697 svc_handler->close (NORMAL_CLOSE_OPERATION);
700 return 0;
703 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
704 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::fini (void)
706 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::fini");
708 return this->close ();
711 // Hook called by the explicit dynamic linking facility.
713 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
714 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::init (int, ACE_TCHAR *[])
716 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::init");
717 return -1;
720 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
721 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::suspend (void)
723 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::suspend");
724 return -1;
727 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
728 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::resume (void)
730 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::resume");
731 return -1;
734 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
735 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::info (ACE_TCHAR **strp, size_t length) const
737 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::info");
738 ACE_TCHAR buf[BUFSIZ];
740 ACE_OS::sprintf (buf,
741 ACE_TEXT ("%s\t %s"),
742 ACE_TEXT ("ACE_Connector"),
743 ACE_TEXT ("# connector factory\n"));
745 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
746 return -1;
747 else
748 ACE_OS::strsncpy (*strp, buf, length);
749 return static_cast<int> (ACE_OS::strlen (buf));
752 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
753 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open (ACE_Reactor *r,
754 int flags)
756 ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open");
757 return this->open (r, 0, 0, 0, flags);
760 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
761 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open
762 (ACE_Reactor *r,
763 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
764 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *conn_s,
765 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
766 int flags)
768 ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open");
770 this->reactor (r);
772 // @@ Not implemented yet.
773 // this->flags_ = flags;
774 ACE_UNUSED_ARG (flags);
776 // Initialize the creation strategy.
778 // First we decide if we need to clean up.
779 if (this->creation_strategy_ != 0 &&
780 this->delete_creation_strategy_ &&
781 cre_s != 0)
783 delete this->creation_strategy_;
784 this->creation_strategy_ = 0;
785 this->delete_creation_strategy_ = false;
788 if (cre_s != 0)
789 this->creation_strategy_ = cre_s;
790 else if (this->creation_strategy_ == 0)
792 ACE_NEW_RETURN (this->creation_strategy_,
793 CREATION_STRATEGY,
794 -1);
795 this->delete_creation_strategy_ = true;
799 // Initialize the accept strategy.
801 if (this->connect_strategy_ != 0 &&
802 this->delete_connect_strategy_ &&
803 conn_s != 0)
805 delete this->connect_strategy_;
806 this->connect_strategy_ = 0;
807 this->delete_connect_strategy_ = false;
810 if (conn_s != 0)
811 this->connect_strategy_ = conn_s;
812 else if (this->connect_strategy_ == 0)
814 ACE_NEW_RETURN (this->connect_strategy_,
815 CONNECT_STRATEGY,
816 -1);
817 this->delete_connect_strategy_ = true;
820 // Initialize the concurrency strategy.
822 if (this->concurrency_strategy_ != 0 &&
823 this->delete_concurrency_strategy_ &&
824 con_s != 0)
826 delete this->concurrency_strategy_;
827 this->concurrency_strategy_ = 0;
828 this->delete_concurrency_strategy_ = false;
831 if (con_s != 0)
832 this->concurrency_strategy_ = con_s;
833 else if (this->concurrency_strategy_ == 0)
835 ACE_NEW_RETURN (this->concurrency_strategy_,
836 CONCURRENCY_STRATEGY,
837 -1);
838 this->delete_concurrency_strategy_ = true;
841 return 0;
844 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
845 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Strategy_Connector
846 (ACE_Reactor *reactor,
847 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
848 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *conn_s,
849 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
850 int flags)
851 : creation_strategy_ (0),
852 delete_creation_strategy_ (false),
853 connect_strategy_ (0),
854 delete_connect_strategy_ (false),
855 concurrency_strategy_ (0),
856 delete_concurrency_strategy_ (false)
858 ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Strategy_Connector");
860 if (this->open (reactor, cre_s, conn_s, con_s, flags) == -1)
861 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_Strategy_Connector::ACE_Strategy_Connector")));
864 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
865 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Strategy_Connector (void)
867 ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Strategy_Connector");
869 // Close down
870 this->close ();
873 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
874 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::close (void)
876 if (this->delete_creation_strategy_)
877 delete this->creation_strategy_;
878 this->delete_creation_strategy_ = false;
879 this->creation_strategy_ = 0;
881 if (this->delete_connect_strategy_)
882 delete this->connect_strategy_;
883 this->delete_connect_strategy_ = false;
884 this->connect_strategy_ = 0;
886 if (this->delete_concurrency_strategy_)
887 delete this->concurrency_strategy_;
888 this->delete_concurrency_strategy_ = false;
889 this->concurrency_strategy_ = 0;
891 return SUPER::close ();
894 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
895 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
897 return this->creation_strategy_->make_svc_handler (sh);
900 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
901 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
902 (SVC_HANDLER *&sh,
903 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
904 ACE_Time_Value *timeout,
905 const ACE_PEER_CONNECTOR_ADDR &local_addr,
906 int reuse_addr,
907 int flags,
908 int perms)
910 return this->connect_strategy_->connect_svc_handler (sh,
911 remote_addr,
912 timeout,
913 local_addr,
914 reuse_addr,
915 flags,
916 perms);
919 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
920 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
921 (SVC_HANDLER *&sh,
922 SVC_HANDLER *&sh_copy,
923 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
924 ACE_Time_Value *timeout,
925 const ACE_PEER_CONNECTOR_ADDR &local_addr,
926 int reuse_addr,
927 int flags,
928 int perms)
930 return this->connect_strategy_->connect_svc_handler (sh,
931 sh_copy,
932 remote_addr,
933 timeout,
934 local_addr,
935 reuse_addr,
936 flags,
937 perms);
940 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
941 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::activate_svc_handler (SVC_HANDLER *svc_handler)
943 return this->concurrency_strategy_->activate_svc_handler (svc_handler, this);
946 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Creation_Strategy<SVC_HANDLER> *
947 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::creation_strategy (void) const
949 return this->creation_strategy_;
952 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *
953 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_strategy (void) const
955 return this->connect_strategy_;
958 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Concurrency_Strategy<SVC_HANDLER> *
959 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::concurrency_strategy (void) const
961 return this->concurrency_strategy_;
964 ACE_END_VERSIONED_NAMESPACE_DECL
966 #endif /* ACE_CONNECTOR_C */