Connector.cpp

Go to the documentation of this file.
00001 // Connector.cpp,v 4.103 2006/02/28 11:11:29 jwillemsen Exp
00002 
00003 #ifndef ACE_CONNECTOR_CPP
00004 #define ACE_CONNECTOR_CPP
00005 
00006 #include "ace/Connector.h"
00007 #include "ace/ACE.h"
00008 #include "ace/OS_NS_stdio.h"
00009 #include "ace/OS_NS_string.h"
00010 #include "ace/os_include/os_fcntl.h"     /* Has ACE_NONBLOCK */
00011 
00012 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00013 # pragma once
00014 #endif /* ACE_LACKS_PRAGMA_ONCE */
00015 
00016 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00017 
00018 ACE_ALLOC_HOOK_DEFINE(ACE_Connector)
00019 
00020 template <class SVC_HANDLER>
00021 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler
00022 (ACE_Connector_Base<SVC_HANDLER> &connector,
00023  SVC_HANDLER *sh,
00024  long id)
00025   : connector_ (connector)
00026   , svc_handler_ (sh)
00027   , timer_id_ (id)
00028 {
00029   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler");
00030 
00031   this->reference_counting_policy ().value
00032     (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
00033 }
00034 
00035 template <class SVC_HANDLER> SVC_HANDLER *
00036 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::svc_handler (void)
00037 {
00038   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::svc_handler");
00039   return this->svc_handler_;
00040 }
00041 
00042 template <class SVC_HANDLER> long
00043 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id (void)
00044 {
00045   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id");
00046   return this->timer_id_;
00047 }
00048 
00049 template <class SVC_HANDLER> void
00050 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id (long id)
00051 {
00052   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id");
00053   this->timer_id_ = id;
00054 }
00055 
00056 template <class SVC_HANDLER> void
00057 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump (void) const
00058 {
00059 #if defined (ACE_HAS_DUMP)
00060   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump");
00061 
00062   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00063   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("svc_handler_ = %x"), this->svc_handler_));
00064   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\ntimer_id_ = %d"), this->timer_id_));
00065   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00066 #endif /* ACE_HAS_DUMP */
00067 }
00068 
00069 template <class SVC_HANDLER> bool
00070 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
00071 {
00072   // Make sure that we haven't already initialized the Svc_Handler.
00073   if (!this->svc_handler_)
00074     return false;
00075 
00076   {
00077     // Exclusive access to the Reactor.
00078     ACE_GUARD_RETURN (ACE_Lock,
00079                       ace_mon,
00080                       this->reactor ()->lock (),
00081                       0);
00082 
00083     // Double check.
00084     if (!this->svc_handler_)
00085       return false;
00086 
00087     // Remember the Svc_Handler.
00088     sh = this->svc_handler_;
00089     ACE_HANDLE h = sh->get_handle ();
00090     this->svc_handler_ = 0;
00091 
00092     // Remove this handle from the set of non-blocking handles
00093     // in the Connector.
00094     this->connector_.non_blocking_handles ().remove (h);
00095 
00096     // Cancel timer.
00097     if (this->reactor ()->cancel_timer (this->timer_id (),
00098                                         0,
00099                                         0) == -1)
00100       return false;
00101 
00102     // Remove from Reactor.
00103     if (this->reactor ()->remove_handler (
00104           h,
00105           ACE_Event_Handler::ALL_EVENTS_MASK) == -1)
00106       return false;
00107   }
00108 
00109   return true;
00110 }
00111 
00112 
00113 template <class SVC_HANDLER> int
00114 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout
00115 (const ACE_Time_Value &tv,
00116  const void *arg)
00117 {
00118   // This method is called if a connection times out before completing.
00119   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout");
00120 
00121   SVC_HANDLER *svc_handler = 0;
00122   int retval = this->close (svc_handler) ? 0 : -1;
00123 
00124   // Forward to the SVC_HANDLER the <arg> that was passed in as a
00125   // magic cookie during ACE_Connector::connect().  This gives the
00126   // SVC_HANDLER an opportunity to take corrective action (e.g., wait
00127   // a few milliseconds and try to reconnect again.
00128   if (svc_handler != 0 && svc_handler->handle_timeout (tv, arg) == -1)
00129     svc_handler->handle_close (svc_handler->get_handle (),
00130                                ACE_Event_Handler::TIMER_MASK);
00131 
00132   return retval;
00133 }
00134 
00135 
00136 template <class SVC_HANDLER> int
00137 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE)
00138 {
00139   // Called when a failure occurs during asynchronous connection
00140   // establishment.
00141   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input");
00142 
00143   SVC_HANDLER *svc_handler = 0;
00144   int retval = this->close (svc_handler) ? 0 : -1;
00145 
00146   // Close Svc_Handler.
00147   if (svc_handler != 0)
00148     svc_handler->close (0);
00149 
00150   return retval;
00151 }
00152 
00153 template <class SVC_HANDLER> int
00154 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle)
00155 {
00156   // Called when a connection is establishment asynchronous.
00157   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output");
00158 
00159   // Grab the connector ref before smashing ourselves in close().
00160   ACE_Connector_Base<SVC_HANDLER> &connector = this->connector_;
00161   SVC_HANDLER *svc_handler = 0;
00162   int retval = this->close (svc_handler) ? 0 : -1;
00163 
00164   if (svc_handler != 0)
00165     connector.initialize_svc_handler (handle, svc_handler);
00166 
00167   return retval;
00168 }
00169 
00170 template <class SVC_HANDLER> int
00171 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception (ACE_HANDLE h)
00172 {
00173   // On Win32, the except mask must also be set for asynchronous
00174   // connects.
00175   ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception");
00176   return this->handle_output (h);
00177 }
00178 
00179 template <class SVC_HANDLER> int
00180 ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::resume_handler (void)
00181 {
00182   return ACE_Event_Handler::ACE_EVENT_HANDLER_NOT_RESUMED;
00183 }
00184 
00185 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
00186 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump (void) const
00187 {
00188 #if defined (ACE_HAS_DUMP)
00189   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump");
00190 
00191   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00192   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nflags_ = %d"), this->flags_));
00193   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00194 #endif /* ACE_HAS_DUMP */
00195 }
00196 
00197 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00198 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
00199 {
00200   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::make_svc_handler");
00201 
00202   if (sh == 0)
00203     ACE_NEW_RETURN (sh,
00204                     SVC_HANDLER,
00205                     -1);
00206 
00207   // Set the reactor of the newly created <SVC_HANDLER> to the same
00208   // reactor that this <Connector> is using.
00209   sh->reactor (this->reactor ());
00210   return 0;
00211 }
00212 
00213 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00214 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::activate_svc_handler (SVC_HANDLER *svc_handler)
00215 {
00216   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::activate_svc_handler");
00217   // No errors initially
00218   int error = 0;
00219 
00220   // See if we should enable non-blocking I/O on the <svc_handler>'s
00221   // peer.
00222   if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0)
00223     {
00224       if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
00225         error = 1;
00226     }
00227   // Otherwise, make sure it's disabled by default.
00228   else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
00229     error = 1;
00230 
00231   // We are connected now, so try to open things up.
00232   if (error || svc_handler->open ((void *) this) == -1)
00233     {
00234       // Make sure to close down the <svc_handler> to avoid descriptor
00235       // leaks.
00236       svc_handler->close (0);
00237       return -1;
00238     }
00239   else
00240     return 0;
00241 }
00242 
00243 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_PEER_CONNECTOR &
00244 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connector (void) const
00245 {
00246   return const_cast<ACE_PEER_CONNECTOR &> (this->connector_);
00247 }
00248 
00249 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00250 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
00251 (SVC_HANDLER *&svc_handler,
00252  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00253  ACE_Time_Value *timeout,
00254  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00255  int reuse_addr,
00256  int flags,
00257  int perms)
00258 {
00259   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler");
00260 
00261   return this->connector_.connect (svc_handler->peer (),
00262                                    remote_addr,
00263                                    timeout,
00264                                    local_addr,
00265                                    reuse_addr,
00266                                    flags,
00267                                    perms);
00268 }
00269 
00270 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00271 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
00272 (SVC_HANDLER *&svc_handler,
00273  SVC_HANDLER *&sh_copy,
00274  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00275  ACE_Time_Value *timeout,
00276  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00277  int reuse_addr,
00278  int flags,
00279  int perms)
00280 {
00281   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler");
00282 
00283   sh_copy = svc_handler;
00284   return this->connector_.connect (svc_handler->peer (),
00285                                    remote_addr,
00286                                    timeout,
00287                                    local_addr,
00288                                    reuse_addr,
00289                                    flags,
00290                                    perms);
00291 }
00292 
00293 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00294 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open (ACE_Reactor *r, int flags)
00295 {
00296   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open");
00297   this->reactor (r);
00298   this->flags_ = flags;
00299   return 0;
00300 }
00301 
00302 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
00303 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Connector (ACE_Reactor *r,
00304                                                                  int flags)
00305 {
00306   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Connector");
00307   (void) this->open (r, flags);
00308 }
00309 
00310 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00311 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect
00312 (SVC_HANDLER *&sh,
00313  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00314  const ACE_Synch_Options &synch_options,
00315  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00316  int reuse_addr,
00317  int flags,
00318  int perms)
00319 {
00320   // Initiate connection to peer.
00321   return this->connect_i (sh,
00322                           0,
00323                           remote_addr,
00324                           synch_options,
00325                           local_addr,
00326                           reuse_addr,
00327                           flags,
00328                           perms);
00329 }
00330 
00331 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00332 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect
00333 (SVC_HANDLER *&sh,
00334  SVC_HANDLER *&sh_copy,
00335  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00336  const ACE_Synch_Options &synch_options,
00337  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00338  int reuse_addr,
00339  int flags,
00340  int perms)
00341 {
00342   // Initiate connection to peer.
00343   return this->connect_i (sh,
00344                           &sh_copy,
00345                           remote_addr,
00346                           synch_options,
00347                           local_addr,
00348                           reuse_addr,
00349                           flags,
00350                           perms);
00351 }
00352 
00353 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00354 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_i
00355 (SVC_HANDLER *&sh,
00356  SVC_HANDLER **sh_copy,
00357  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00358  const ACE_Synch_Options &synch_options,
00359  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00360  int reuse_addr,
00361  int flags,
00362  int perms)
00363 {
00364   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_i");
00365 
00366   // If the user hasn't supplied us with a <SVC_HANDLER> we'll use the
00367   // factory method to create one.  Otherwise, things will remain as
00368   // they are...
00369   if (this->make_svc_handler (sh) == -1)
00370     return -1;
00371 
00372   ACE_Time_Value *timeout = 0;
00373   int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
00374 
00375   if (use_reactor)
00376     timeout = const_cast<ACE_Time_Value *> (&ACE_Time_Value::zero);
00377   else
00378     timeout = const_cast<ACE_Time_Value *> (synch_options.time_value ());
00379 
00380   int result;
00381   if (sh_copy == 0)
00382     result = this->connect_svc_handler (sh,
00383                                         remote_addr,
00384                                         timeout,
00385                                         local_addr,
00386                                         reuse_addr,
00387                                         flags,
00388                                         perms);
00389   else
00390     result = this->connect_svc_handler (sh,
00391                                         *sh_copy,
00392                                         remote_addr,
00393                                         timeout,
00394                                         local_addr,
00395                                         reuse_addr,
00396                                         flags,
00397                                         perms);
00398 
00399   // Activate immediately if we are connected.
00400   if (result != -1)
00401     return this->activate_svc_handler (sh);
00402 
00403   // Delegate to connection strategy.
00404   if (use_reactor && ACE_OS::last_error () == EWOULDBLOCK)
00405     {
00406       // If the connection hasn't completed and we are using
00407       // non-blocking semantics then register
00408       // ACE_NonBlocking_Connect_Handler with the ACE_Reactor so that
00409       // it will call us back when the connection is complete or we
00410       // timeout, whichever comes first...
00411       int result;
00412 
00413       if (sh_copy == 0)
00414         result = this->nonblocking_connect (sh, synch_options);
00415       else
00416         result = this->nonblocking_connect (*sh_copy, synch_options);
00417 
00418       // If for some reason the <nonblocking_connect> call failed, then <errno>
00419       // will be set to the new error.  If the call succeeds, however,
00420       // we need to make sure that <errno> remains set to
00421       // <EWOULDBLOCK>.
00422       if (result == 0)
00423         errno = EWOULDBLOCK;
00424     }
00425   else
00426     {
00427       // Save/restore errno.
00428       ACE_Errno_Guard error (errno);
00429       // Make sure to close down the service handler to avoid handle
00430       // leaks.
00431       if (sh_copy == 0)
00432         {
00433           if (sh)
00434             sh->close (0);
00435         }
00436       else if (*sh_copy)
00437         (*sh_copy)->close (0);
00438     }
00439 
00440   return -1;
00441 }
00442 
00443 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00444 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_n
00445 (size_t n,
00446  SVC_HANDLER *sh[],
00447  ACE_PEER_CONNECTOR_ADDR remote_addrs[],
00448  ACE_TCHAR *failed_svc_handlers,
00449  const ACE_Synch_Options &synch_options)
00450 {
00451   int result = 0;
00452 
00453   for (size_t i = 0; i < n; i++)
00454     {
00455       if (this->connect (sh[i], remote_addrs[i], synch_options) == -1
00456           && !(synch_options[ACE_Synch_Options::USE_REACTOR]
00457                && errno == EWOULDBLOCK))
00458         {
00459           result = -1;
00460           if (failed_svc_handlers != 0)
00461             // Mark this entry as having failed.
00462             failed_svc_handlers[i] = 1;
00463         }
00464       else if (failed_svc_handlers != 0)
00465         // Mark this entry as having succeeded.
00466         failed_svc_handlers[i] = 0;
00467     }
00468 
00469   return result;
00470 }
00471 
00472 // Cancel a <svc_handler> that was started asynchronously.
00473 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00474 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::cancel (SVC_HANDLER *sh)
00475 {
00476   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::cancel");
00477 
00478   ACE_Event_Handler *handler =
00479     this->reactor ()->find_handler (sh->get_handle ());
00480 
00481   if (handler == 0)
00482     return -1;
00483 
00484   // find_handler() increments handler's refcount; ensure we decrement it.
00485   ACE_Event_Handler_var safe_handler (handler);
00486 
00487   NBCH *nbch =
00488     dynamic_cast<NBCH *> (handler);
00489 
00490   if (nbch == 0)
00491     return -1;
00492 
00493   SVC_HANDLER *tmp_sh = 0;
00494 
00495   if (nbch->close (tmp_sh) == false)
00496     return -1;
00497 
00498   return 0;
00499 }
00500 
00501 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00502 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::nonblocking_connect
00503 (SVC_HANDLER *sh,
00504  const ACE_Synch_Options &synch_options)
00505 {
00506   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::nonblocking_connect");
00507 
00508   // Must have a valid Reactor for non-blocking connects to work.
00509   if (this->reactor () == 0)
00510     return -1;
00511 
00512   // Register the pending SVC_HANDLER so that it can be activated
00513   // later on when the connection completes.
00514 
00515   ACE_HANDLE handle = sh->get_handle ();
00516   long timer_id = -1;
00517   ACE_Time_Value *tv = 0;
00518   NBCH *nbch = 0;
00519 
00520   ACE_NEW_RETURN (nbch,
00521                   NBCH (*this,
00522                         sh,
00523                         -1),
00524                   -1);
00525 
00526   ACE_Event_Handler_var safe_nbch (nbch);
00527 
00528   // Exclusive access to the Reactor.
00529   ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1);
00530 
00531   // Register handle with the reactor for connection events.
00532   ACE_Reactor_Mask mask = ACE_Event_Handler::CONNECT_MASK;
00533   if (this->reactor ()->register_handler (handle,
00534                                           nbch,
00535                                           mask) == -1)
00536     goto reactor_registration_failure;
00537 
00538   // Add handle to non-blocking handle set.
00539   this->non_blocking_handles ().insert (handle);
00540 
00541   // If we're starting connection under timer control then we need to
00542   // schedule a timeout with the ACE_Reactor.
00543   tv = const_cast<ACE_Time_Value *> (synch_options.time_value ());
00544   if (tv != 0)
00545     {
00546       timer_id =
00547         this->reactor ()->schedule_timer (nbch,
00548                                           synch_options.arg (),
00549                                           *tv);
00550       if (timer_id == -1)
00551         goto timer_registration_failure;
00552 
00553       // Remember timer id.
00554       nbch->timer_id (timer_id);
00555     }
00556 
00557   return 0;
00558 
00559   // Undo previous actions using the ol' "goto label and fallthru"
00560   // trick...
00561  timer_registration_failure:
00562 
00563   // Remove from Reactor.
00564   this->reactor ()->remove_handler (handle, mask);
00565 
00566   // Remove handle from the set of non-blocking handles.
00567   this->non_blocking_handles ().remove (handle);
00568 
00569   /* FALLTHRU */
00570 
00571  reactor_registration_failure:
00572   // Close the svc_handler
00573 
00574   sh->close (0);
00575 
00576   return -1;
00577 }
00578 
00579 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
00580 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connector (void)
00581 {
00582   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connector");
00583 
00584   this->close ();
00585 }
00586 
00587 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
00588 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::initialize_svc_handler
00589 (ACE_HANDLE handle,
00590  SVC_HANDLER *svc_handler)
00591 {
00592   // Try to find out if the reactor uses event associations for the
00593   // handles it waits on. If so we need to reset it.
00594   int reset_new_handle =
00595     this->reactor ()->uses_event_associations ();
00596 
00597   if (reset_new_handle)
00598     this->connector_.reset_new_handle (handle);
00599 
00600   // Transfer ownership of the ACE_HANDLE to the SVC_HANDLER.
00601   svc_handler->set_handle (handle);
00602 
00603   ACE_PEER_CONNECTOR_ADDR raddr;
00604 
00605   // Check to see if we're connected.
00606   if (svc_handler->peer ().get_remote_addr (raddr) != -1)
00607     this->activate_svc_handler (svc_handler);
00608   else // Somethings gone wrong, so close down...
00609     {
00610 #if defined (ACE_WIN32)
00611       // Win32 (at least prior to Windows 2000) has a timing problem.
00612       // If you check to see if the connection has completed too fast,
00613       // it will fail - so wait 35 milliseconds to let it catch up.
00614       ACE_Time_Value tv (0, ACE_NON_BLOCKING_BUG_DELAY);
00615       ACE_OS::sleep (tv);
00616       if (svc_handler->peer ().get_remote_addr (raddr) != -1)
00617         this->activate_svc_handler (svc_handler);
00618       else // do the svc handler close below...
00619 #endif /* ACE_WIN32 */
00620         svc_handler->close (0);
00621     }
00622 }
00623 
00624 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
00625 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::reactor (ACE_Reactor *reactor)
00626 {
00627   this->reactor_ = reactor;
00628 }
00629 
00630 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Reactor *
00631 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::reactor (void) const
00632 {
00633   return this->reactor_;
00634 }
00635 
00636 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Unbounded_Set<ACE_HANDLE> &
00637 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::non_blocking_handles (void)
00638 {
00639   return this->non_blocking_handles_;
00640 }
00641 
00642 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00643 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::close (void)
00644 {
00645   // If there are no non-blocking handle pending, return immediately.
00646   if (this->non_blocking_handles ().size () == 0)
00647     return 0;
00648 
00649   // Exclusive access to the Reactor.
00650   ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1);
00651 
00652   // Go through all the non-blocking handles.  It is necessary to
00653   // create a new iterator each time because we remove from the handle
00654   // set when we cancel the Svc_Handler.
00655   ACE_HANDLE *handle = 0;
00656   while (1)
00657     {
00658       ACE_Unbounded_Set_Iterator<ACE_HANDLE>
00659         iterator (this->non_blocking_handles ());
00660       if (!iterator.next (handle))
00661         break;
00662 
00663       ACE_Event_Handler *handler =
00664         this->reactor ()->find_handler (*handle);
00665       if (handler == 0)
00666         {
00667           ACE_ERROR ((LM_ERROR,
00668                       ACE_LIB_TEXT ("%t: Connector::close h %d, no handler\n"),
00669                       *handle));
00670           // Remove handle from the set of non-blocking handles.
00671           this->non_blocking_handles ().remove (*handle);
00672           continue;
00673         }
00674 
00675       // find_handler() incremented handler's refcount; ensure it's decremented
00676       ACE_Event_Handler_var safe_handler (handler);
00677       NBCH *nbch = dynamic_cast<NBCH *> (handler);
00678       if (nbch == 0)
00679         {
00680           ACE_ERROR ((LM_ERROR,
00681                       ACE_LIB_TEXT ("%t: Connector::close h %d handler %@ ")
00682                       ACE_LIB_TEXT ("not a legit handler\n"),
00683                       *handle,
00684                       handler));
00685           // Remove handle from the set of non-blocking handles.
00686           this->non_blocking_handles ().remove (*handle);
00687           continue;
00688         }
00689       SVC_HANDLER *svc_handler = nbch->svc_handler ();
00690 
00691       // Cancel the non-blocking connection.
00692       this->cancel (svc_handler);
00693 
00694       // Close the associated Svc_Handler.
00695       svc_handler->close (0);
00696     }
00697 
00698   return 0;
00699 }
00700 
00701 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00702 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::fini (void)
00703 {
00704   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::fini");
00705 
00706   return this->close ();
00707 }
00708 
00709 // Hook called by the explicit dynamic linking facility.
00710 
00711 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00712 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::init (int, ACE_TCHAR *[])
00713 {
00714   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::init");
00715   return -1;
00716 }
00717 
00718 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00719 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::suspend (void)
00720 {
00721   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::suspend");
00722   return -1;
00723 }
00724 
00725 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00726 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::resume (void)
00727 {
00728   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::resume");
00729   return -1;
00730 }
00731 
00732 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00733 ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::info (ACE_TCHAR **strp, size_t length) const
00734 {
00735   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::info");
00736   ACE_TCHAR buf[BUFSIZ];
00737 
00738   ACE_OS::sprintf (buf,
00739                    ACE_LIB_TEXT ("%s\t %s"),
00740                    ACE_LIB_TEXT ("ACE_Connector"),
00741                    ACE_LIB_TEXT ("# connector factory\n"));
00742 
00743   if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
00744     return -1;
00745   else
00746     ACE_OS::strsncpy (*strp, buf, length);
00747   return static_cast<int> (ACE_OS::strlen (buf));
00748 }
00749 
00750 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00751 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open (ACE_Reactor *r,
00752                                                                  int flags)
00753 {
00754   ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open");
00755   return this->open (r, 0, 0, 0, flags);
00756 }
00757 
00758 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00759 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open
00760 (ACE_Reactor *r,
00761  ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
00762  ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *conn_s,
00763  ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
00764  int flags)
00765 {
00766   ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::open");
00767 
00768   this->reactor (r);
00769 
00770   // @@ Not implemented yet.
00771   // this->flags_ = flags;
00772   ACE_UNUSED_ARG (flags);
00773 
00774   // Initialize the creation strategy.
00775 
00776   // First we decide if we need to clean up.
00777   if (this->creation_strategy_ != 0 &&
00778       this->delete_creation_strategy_ != 0 &&
00779       cre_s != 0)
00780     {
00781       delete this->creation_strategy_;
00782       this->creation_strategy_ = 0;
00783       this->delete_creation_strategy_ = 0;
00784     }
00785 
00786   if (cre_s != 0)
00787     this->creation_strategy_ = cre_s;
00788   else if (this->creation_strategy_ == 0)
00789     {
00790       ACE_NEW_RETURN (this->creation_strategy_,
00791                       CREATION_STRATEGY,
00792                       -1);
00793       this->delete_creation_strategy_ = 1;
00794     }
00795 
00796 
00797   // Initialize the accept strategy.
00798 
00799   if (this->connect_strategy_ != 0 &&
00800       this->delete_connect_strategy_ != 0 &&
00801       conn_s != 0)
00802     {
00803       delete this->connect_strategy_;
00804       this->connect_strategy_ = 0;
00805       this->delete_connect_strategy_ = 0;
00806     }
00807 
00808   if (conn_s != 0)
00809     this->connect_strategy_ = conn_s;
00810   else if (this->connect_strategy_ == 0)
00811     {
00812       ACE_NEW_RETURN (this->connect_strategy_,
00813                       CONNECT_STRATEGY,
00814                       -1);
00815       this->delete_connect_strategy_ = 1;
00816     }
00817 
00818   // Initialize the concurrency strategy.
00819 
00820   if (this->concurrency_strategy_ != 0 &&
00821       this->delete_concurrency_strategy_ != 0 &&
00822       con_s != 0)
00823     {
00824       delete this->concurrency_strategy_;
00825       this->concurrency_strategy_ = 0;
00826       this->delete_concurrency_strategy_ = 0;
00827     }
00828 
00829   if (con_s != 0)
00830     this->concurrency_strategy_ = con_s;
00831   else if (this->concurrency_strategy_ == 0)
00832     {
00833       ACE_NEW_RETURN (this->concurrency_strategy_,
00834                       CONCURRENCY_STRATEGY,
00835                       -1);
00836       this->delete_concurrency_strategy_ = 1;
00837     }
00838 
00839   return 0;
00840 }
00841 
00842 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
00843 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Strategy_Connector
00844 (ACE_Reactor *reactor,
00845  ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
00846  ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *conn_s,
00847  ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
00848  int flags)
00849   : creation_strategy_ (0),
00850     delete_creation_strategy_ (0),
00851     connect_strategy_ (0),
00852     delete_connect_strategy_ (0),
00853     concurrency_strategy_ (0),
00854     delete_concurrency_strategy_ (0)
00855 {
00856   ACE_TRACE ("ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::ACE_Strategy_Connector");
00857 
00858   if (this->open (reactor, cre_s, conn_s, con_s, flags) == -1)
00859     ACE_ERROR ((LM_ERROR,  ACE_LIB_TEXT ("%p\n"),  ACE_LIB_TEXT ("ACE_Strategy_Connector::ACE_Strategy_Connector")));
00860 }
00861 
00862 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
00863 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Strategy_Connector (void)
00864 {
00865   ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Strategy_Connector");
00866 
00867   // Close down
00868   this->close ();
00869 }
00870 
00871 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00872 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::close (void)
00873 {
00874   if (this->delete_creation_strategy_)
00875     delete this->creation_strategy_;
00876   this->delete_creation_strategy_ = 0;
00877   this->creation_strategy_ = 0;
00878 
00879   if (this->delete_connect_strategy_)
00880     delete this->connect_strategy_;
00881   this->delete_connect_strategy_ = 0;
00882   this->connect_strategy_ = 0;
00883 
00884   if (this->delete_concurrency_strategy_)
00885     delete this->concurrency_strategy_;
00886   this->delete_concurrency_strategy_ = 0;
00887   this->concurrency_strategy_ = 0;
00888 
00889   return SUPER::close ();
00890 }
00891 
00892 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00893 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
00894 {
00895   return this->creation_strategy_->make_svc_handler (sh);
00896 }
00897 
00898 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00899 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
00900 (SVC_HANDLER *&sh,
00901  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00902  ACE_Time_Value *timeout,
00903  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00904  int reuse_addr,
00905  int flags,
00906  int perms)
00907 {
00908   return this->connect_strategy_->connect_svc_handler (sh,
00909                                                        remote_addr,
00910                                                        timeout,
00911                                                        local_addr,
00912                                                        reuse_addr,
00913                                                        flags,
00914                                                        perms);
00915 }
00916 
00917 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00918 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
00919 (SVC_HANDLER *&sh,
00920  SVC_HANDLER *&sh_copy,
00921  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00922  ACE_Time_Value *timeout,
00923  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00924  int reuse_addr,
00925  int flags,
00926  int perms)
00927 {
00928   return this->connect_strategy_->connect_svc_handler (sh,
00929                                                        sh_copy,
00930                                                        remote_addr,
00931                                                        timeout,
00932                                                        local_addr,
00933                                                        reuse_addr,
00934                                                        flags,
00935                                                        perms);
00936 }
00937 
00938 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00939 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::activate_svc_handler (SVC_HANDLER *svc_handler)
00940 {
00941   return this->concurrency_strategy_->activate_svc_handler (svc_handler, this);
00942 }
00943 
00944 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Creation_Strategy<SVC_HANDLER> *
00945 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::creation_strategy (void) const
00946 {
00947   return this->creation_strategy_;
00948 }
00949 
00950 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *
00951 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_strategy (void) const
00952 {
00953   return this->connect_strategy_;
00954 }
00955 
00956 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Concurrency_Strategy<SVC_HANDLER> *
00957 ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::concurrency_strategy (void) const
00958 {
00959   return this->concurrency_strategy_;
00960 }
00961 
00962 ACE_END_VERSIONED_NAMESPACE_DECL
00963 
00964 #endif /* ACE_CONNECTOR_C */

Generated on Thu Nov 9 09:41:49 2006 for ACE by doxygen 1.3.6