Acceptor.cpp

Go to the documentation of this file.
00001 #ifndef ACE_ACCEPTOR_CPP
00002 #define ACE_ACCEPTOR_CPP
00003 
00004 #include "ace/ACE.h"
00005 
00006 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00007 # pragma once
00008 #endif /* ACE_LACKS_PRAGMA_ONCE */
00009 
00010 #include "ace/Acceptor.h"
00011 #include "ace/Handle_Set.h"
00012 #include "ace/Svc_Handler.h"
00013 #include "ace/WFMO_Reactor.h"
00014 #include "ace/OS_NS_stdio.h"
00015 #include "ace/OS_NS_string.h"
00016 #include "ace/OS_NS_sys_select.h"
00017 
00018 ACE_RCSID (ace,
00019            Acceptor,
00020            "$Id: Acceptor.cpp 81460 2008-04-28 11:34:23Z elliott_c $")
00021 
00022 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 ACE_ALLOC_HOOK_DEFINE(ACE_Acceptor)
00025 
00026 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
00027 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
00028 {
00029 #if defined (ACE_HAS_DUMP)
00030   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
00031 
00032   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00033   this->peer_acceptor_.dump ();
00034   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00035 #endif /* ACE_HAS_DUMP */
00036 }
00037 
00038 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00039 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR & () const
00040 {
00041   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR &");
00042   return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
00043 }
00044 
00045 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
00046 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
00047 {
00048   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
00049   return const_cast<ACE_PEER_ACCEPTOR &> (this->peer_acceptor_);
00050 }
00051 
00052 // Returns ACE_HANDLE of the underlying Acceptor_Strategy.
00053 
00054 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
00055 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
00056 {
00057   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
00058   return this->peer_acceptor_.get_handle ();
00059 }
00060 
00061 // Initialize the appropriate strategies for creation, passive
00062 // connection acceptance, and concurrency, and then register <this>
00063 // with the Reactor and listen for connection requests at the
00064 // designated <local_addr>.
00065 
00066 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00067 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
00068   (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
00069    ACE_Reactor *reactor,
00070    int flags,
00071    int use_select,
00072    int reuse_addr)
00073 {
00074   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
00075   this->flags_ = flags;
00076   this->use_select_ = use_select;
00077   this->reuse_addr_ = reuse_addr;
00078   this->peer_acceptor_addr_ = local_addr;
00079 
00080   // Must supply a valid Reactor to Acceptor::open()...
00081 
00082   if (reactor == 0)
00083     {
00084       errno = EINVAL;
00085       return -1;
00086     }
00087 
00088   if (this->peer_acceptor_.open (local_addr, reuse_addr) == -1)
00089     return -1;
00090 
00091   // Set the peer acceptor's handle into non-blocking mode.  This is a
00092   // safe-guard against the race condition that can otherwise occur
00093   // between the time when <select> indicates that a passive-mode
00094   // socket handle is "ready" and when we call <accept>.  During this
00095   // interval, the client can shutdown the connection, in which case,
00096   // the <accept> call can hang!
00097   (void) this->peer_acceptor_.enable (ACE_NONBLOCK);
00098 
00099   int const result = reactor->register_handler (this,
00100                                                 ACE_Event_Handler::ACCEPT_MASK);
00101   if (result != -1)
00102     this->reactor (reactor);
00103   else
00104     this->peer_acceptor_.close ();
00105 
00106   return result;
00107 }
00108 
00109 // Simple constructor.
00110 
00111 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00112 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor (ACE_Reactor *reactor,
00113                                                               int use_select)
00114   :flags_ (0),
00115    use_select_ (use_select),
00116    reuse_addr_ (1)
00117 {
00118   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor");
00119 
00120   this->reactor (reactor);
00121 }
00122 
00123 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00124 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor
00125   (const ACE_PEER_ACCEPTOR_ADDR &addr,
00126    ACE_Reactor *reactor,
00127    int flags,
00128    int use_select,
00129    int reuse_addr)
00130 {
00131   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor");
00132 
00133   if (this->open (addr,
00134                   reactor,
00135                   flags,
00136                   use_select,
00137                   reuse_addr) == -1)
00138     ACE_ERROR ((LM_ERROR,
00139                 ACE_TEXT ("%p\n"),
00140                 ACE_TEXT ("ACE_Acceptor::ACE_Acceptor")));
00141 }
00142 
00143 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00144 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Acceptor (void)
00145 {
00146   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Acceptor");
00147   this->handle_close ();
00148 }
00149 
00150 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00151 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini (void)
00152 {
00153   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini");
00154   return ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close ();
00155 }
00156 
00157 // Hook called by the explicit dynamic linking facility.
00158 
00159 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00160 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init (int, ACE_TCHAR *[])
00161 {
00162   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init");
00163   return -1;
00164 }
00165 
00166 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00167 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info (ACE_TCHAR **strp,
00168                                                       size_t length) const
00169 {
00170   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info");
00171   ACE_TCHAR buf[BUFSIZ];
00172   ACE_TCHAR addr_str[BUFSIZ];
00173   ACE_PEER_ACCEPTOR_ADDR addr;
00174 
00175   if (this->acceptor ().get_local_addr (addr) == -1)
00176     return -1;
00177   else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1)
00178     return -1;
00179 
00180   ACE_OS::sprintf (buf,
00181                    ACE_TEXT ("%s\t %s %s"),
00182                    ACE_TEXT ("ACE_Acceptor"),
00183                    addr_str,
00184                    ACE_TEXT ("# acceptor factory\n"));
00185 
00186   if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
00187     return -1;
00188   else
00189     ACE_OS::strsncpy (*strp, buf, length);
00190   return static_cast<int> (ACE_OS::strlen (buf));
00191 }
00192 
00193 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00194 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend (void)
00195 {
00196   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend");
00197   return this->reactor ()->suspend_handler (this);
00198 }
00199 
00200 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00201 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume (void)
00202 {
00203   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume");
00204   return this->reactor ()->resume_handler (this);
00205 }
00206 
00207 // Perform termination activities when <this> is removed from the
00208 // <reactor>.
00209 
00210 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00211 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close (void)
00212 {
00213   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close");
00214   return this->handle_close ();
00215 }
00216 
00217 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00218 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_accept_error (void)
00219 {
00220   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_accept_error");
00221   return 0;
00222 }
00223 
00224 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00225 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
00226                                                               ACE_Reactor_Mask)
00227 {
00228   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
00229   // Guard against multiple closes.
00230   if (this->reactor () != 0)
00231     {
00232       ACE_HANDLE handle = this->get_handle ();
00233 
00234       this->reactor ()->remove_handler
00235         (handle,
00236          // We must pass the DONT_CALL flag here to avoid infinite
00237          // recursion.
00238          ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
00239 
00240       // Shut down the listen socket to recycle the handles.
00241       if (this->peer_acceptor_.close () == -1)
00242         ACE_ERROR ((LM_ERROR,
00243                     ACE_TEXT ("close\n")));
00244       // Set the Reactor to 0 so that we don't try to close down
00245       // again.
00246       this->reactor (0);
00247     }
00248   return 0;
00249 }
00250 
00251 // Bridge method for creating a SVC_HANDLER.  The strategy for
00252 // creating a SVC_HANDLER are configured into the Acceptor via it's
00253 // <creation_strategy_>.  The default is to create a new SVC_HANDLER.
00254 // However, subclasses can override this strategy to perform
00255 // SVC_HANDLER creation in any way that they like (such as creating
00256 // subclass instances of SVC_HANDLER, using a singleton, dynamically
00257 // linking the handler, etc.).
00258 
00259 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00260 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
00261 {
00262   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler");
00263 
00264   if (sh == 0)
00265     ACE_NEW_RETURN (sh,
00266                     SVC_HANDLER,
00267                     -1);
00268 
00269   // Set the reactor of the newly created <SVC_HANDLER> to the same
00270   // reactor that this <ACE_Acceptor> is using.
00271   sh->reactor (this->reactor ());
00272   return 0;
00273 }
00274 
00275 // Bridge method for accepting the new connection into the
00276 // <svc_handler>.  The default behavior delegates to the
00277 // <PEER_ACCEPTOR::accept> in the Acceptor_Strategy.
00278 
00279 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00280 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler
00281   (SVC_HANDLER *svc_handler)
00282 {
00283   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler");
00284 
00285   // Try to find out if the implementation of the reactor that we are
00286   // using requires us to reset the event association for the newly
00287   // created handle. This is because the newly created handle will
00288   // inherit the properties of the listen handle, including its event
00289   // associations.
00290   int reset_new_handle = this->reactor ()->uses_event_associations ();
00291 
00292   if (this->acceptor ().accept (svc_handler->peer (), // stream
00293                                 0, // remote address
00294                                 0, // timeout
00295                                 1, // restart
00296                                 reset_new_handle  // reset new handler
00297                                 ) == -1)
00298     {
00299       // Ensure that errno is preserved in case the svc_handler
00300       // close() method resets it
00301       ACE_Errno_Guard error(errno);
00302 
00303       // Close down handler to avoid memory leaks.
00304       svc_handler->close (0);
00305 
00306       return -1;
00307     }
00308   else
00309     return 0;
00310 }
00311 
00312 // Bridge method for activating a <svc_handler> with the appropriate
00313 // concurrency strategy.  The default behavior of this method is to
00314 // activate the SVC_HANDLER by calling its open() method (which allows
00315 // the SVC_HANDLER to define its own concurrency strategy).  However,
00316 // subclasses can override this strategy to do more sophisticated
00317 // concurrency activations (such as creating the SVC_HANDLER as an
00318 // "active object" via multi-threading or multi-processing).
00319 
00320 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00321 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler
00322   (SVC_HANDLER *svc_handler)
00323 {
00324   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler");
00325 
00326   int result = 0;
00327 
00328   // See if we should enable non-blocking I/O on the <svc_handler>'s
00329   // peer.
00330   if (ACE_BIT_ENABLED (this->flags_,
00331                        ACE_NONBLOCK))
00332     {
00333       if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
00334         result = -1;
00335     }
00336   // Otherwise, make sure it's disabled by default.
00337   else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
00338     result = -1;
00339 
00340   if (result == 0 && svc_handler->open ((void *) this) == -1)
00341     result = -1;
00342 
00343   if (result == -1)
00344     svc_handler->close (0);
00345 
00346   return result;
00347 }
00348 
00349 // Template Method that makes a SVC_HANDLER (using the appropriate
00350 // creation strategy), accept the connection into the SVC_HANDLER, and
00351 // then activate the SVC_HANDLER.
00352 
00353 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00354 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input (ACE_HANDLE listener)
00355 {
00356   ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input");
00357   ACE_Handle_Set conn_handle;
00358 
00359   // Default is "timeout (0, 0)," which means "poll."
00360   ACE_Time_Value timeout;
00361 #  if defined (ACE_WIN32)
00362   // This arg is ignored on Windows and causes pointer truncation
00363   // warnings on 64-bit compiles
00364   int select_width = 0;
00365 #  else
00366   int select_width = int (listener) + 1;
00367 #  endif /* ACE_WIN32 */
00368 
00369   // Accept connections from clients.  Note that a loop is used for two
00370   // reasons:
00371   //
00372   // 1. It allows us to accept all pending connections without an
00373   //    extra trip through the ACE_Reactor and without having to use
00374   //    non-blocking I/O...
00375   //
00376   // 2. It allows the TLI_SAP::ACE_Acceptor class to work correctly (don't
00377   //    ask -- TLI is *horrible*...).
00378 
00379   // @@ What should we do if any of the substrategies fail?  Right
00380   // now, we just print out a diagnostic message if <ACE::debug>
00381   // returns > 0 and return 0 (which means that the Acceptor remains
00382   // registered with the Reactor)...
00383   do
00384     {
00385       // Create a service handler, using the appropriate creation
00386       // strategy.
00387 
00388       SVC_HANDLER *svc_handler = 0;
00389 
00390       if (this->make_svc_handler (svc_handler) == -1)
00391         {
00392           if (ACE::debug ())
00393             ACE_DEBUG ((LM_DEBUG,
00394                         ACE_TEXT ("%p\n"),
00395                         ACE_TEXT ("make_svc_handler")));
00396           return 0;
00397         }
00398       // Accept connection into the Svc_Handler.
00399       else if (this->accept_svc_handler (svc_handler) == -1)
00400         {
00401           // Note that <accept_svc_handler> closes the <svc_handler>
00402           // on failure.
00403           if (ACE::debug ())
00404             ACE_DEBUG ((LM_DEBUG,
00405                         ACE_TEXT ("%p\n"),
00406                         ACE_TEXT ("accept_svc_handler")));
00407           return this->handle_accept_error ();
00408         }
00409       // Activate the <svc_handler> using the designated concurrency
00410       // strategy (note that this method becomes responsible for
00411       // handling errors and freeing up the memory if things go
00412       // awry...).
00413       else if (this->activate_svc_handler (svc_handler) == -1)
00414         {
00415           // Note that <activate_svc_handler> closes the <svc_handler>
00416           // on failure.
00417 
00418           if (ACE::debug ())
00419             ACE_DEBUG ((LM_DEBUG,
00420                         ACE_TEXT ("%p\n"),
00421                         ACE_TEXT ("activate_svc_handler")));
00422           return 0;
00423         }
00424 
00425       conn_handle.set_bit (listener);
00426     }
00427 
00428   // Now, check to see if there is another connection pending and
00429   // break out of the loop if there is none.
00430   while (this->use_select_
00431          && ACE_OS::select (select_width,
00432                             conn_handle,
00433                             0,
00434                             0,
00435                             &timeout) == 1);
00436   return 0;
00437 }
00438 
00439 ACE_ALLOC_HOOK_DEFINE(ACE_Strategy_Acceptor)
00440 
00441 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00442 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend (void)
00443 {
00444   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend");
00445 
00446   // First suspend the SVC_HANDLER's we've created.
00447   if (this->scheduling_strategy_->suspend () == -1)
00448     return -1;
00449   else   // Then suspend ourselves.
00450     return ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend ();
00451 }
00452 
00453 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00454 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume (void)
00455 {
00456   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume");
00457 
00458   // First resume ourselves.
00459   if (ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume () == -1)
00460     return -1;
00461   else // Then resume the SVC_HANDLER's we've created.
00462     return this->scheduling_strategy_->resume ();
00463 }
00464 
00465 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
00466 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
00467 {
00468 #if defined (ACE_HAS_DUMP)
00469   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
00470 
00471   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00472   ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump ();
00473   this->creation_strategy_->dump ();
00474   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_creation_strategy_ = %d"), delete_creation_strategy_));
00475   this->accept_strategy_->dump ();
00476   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_accept_strategy_ = %d"), delete_accept_strategy_));
00477   this->concurrency_strategy_->dump ();
00478   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_concurrency_strategy_ = %d"), delete_concurrency_strategy_));
00479   this->scheduling_strategy_->dump ();
00480   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_scheduling_strategy_ = %d"), delete_scheduling_strategy_));
00481   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nservice_name_ = %s"),
00482               this->service_name_ == 0 ? ACE_TEXT ("<unknown>") : this->service_name_));
00483   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nservice_description_ = %s"),
00484               this->service_description_ == 0 ? ACE_TEXT ("<unknown>") : this->service_description_));
00485   this->service_addr_.dump ();
00486   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00487 #endif /* ACE_HAS_DUMP */
00488 }
00489 
00490 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
00491 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
00492 {
00493   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
00494   return this->accept_strategy_->acceptor ();
00495 }
00496 
00497 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00498 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR & () const
00499 {
00500   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR &");
00501   return this->accept_strategy_->acceptor ();
00502 }
00503 
00504 // Returns ACE_HANDLE of the underlying Acceptor_Strategy.
00505 
00506 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
00507 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
00508 {
00509   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
00510   return this->accept_strategy_->get_handle ();
00511 }
00512 
00513 // Initialize the appropriate strategies for creation, passive
00514 // connection acceptance, and concurrency, and then register <this>
00515 // with the Reactor and listen for connection requests at the
00516 // designated <local_addr>.
00517 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00518 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
00519   (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
00520    ACE_Reactor *reactor,
00521    int /* flags unused */,
00522    int use_select,
00523    int reuse_addr)
00524 {
00525   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
00526   return this->open
00527     (local_addr, reactor, 0, 0, 0, 0, 0, 0, use_select, reuse_addr);
00528 }
00529 
00530 
00531 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00532 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
00533   (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
00534    ACE_Reactor *reactor,
00535    ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
00536    ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> *acc_s,
00537    ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
00538    ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
00539    const ACE_TCHAR *service_name,
00540    const ACE_TCHAR *service_description,
00541    int use_select,
00542    int reuse_addr)
00543 {
00544   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
00545 
00546   if (this->service_name_ == 0 && service_name != 0)
00547     ACE_ALLOCATOR_RETURN (this->service_name_,
00548                           ACE_OS::strdup (service_name),
00549                           -1);
00550   if (this->service_description_ == 0 && service_description != 0)
00551     ACE_ALLOCATOR_RETURN (this->service_description_,
00552                           ACE_OS::strdup (service_description),
00553                           -1);
00554   this->reactor (reactor);
00555 
00556   // Must supply a valid Reactor to Acceptor::open()...
00557   if (reactor == 0)
00558     {
00559       errno = EINVAL;
00560       return -1;
00561     }
00562 
00563   // Initialize the creation strategy.
00564 
00565   if (cre_s == 0)
00566     {
00567       ACE_NEW_RETURN (cre_s,
00568                       CREATION_STRATEGY,
00569                       -1);
00570       this->delete_creation_strategy_ = true;
00571     }
00572   this->creation_strategy_ = cre_s;
00573 
00574   // Initialize the accept strategy.
00575 
00576   if (acc_s == 0)
00577     {
00578       ACE_NEW_RETURN (acc_s,
00579                       ACCEPT_STRATEGY (this->reactor ()),
00580                       -1);
00581       this->delete_accept_strategy_ = true;
00582     }
00583   this->accept_strategy_ = acc_s;
00584 
00585   if (this->accept_strategy_->open (local_addr, reuse_addr) == -1)
00586     return -1;
00587 
00588   // Set the peer acceptor's handle into non-blocking mode.  This is a
00589   // safe-guard against the race condition that can otherwise occur
00590   // between the time when <select> indicates that a passive-mode
00591   // socket handle is "ready" and when we call <accept>.  During this
00592   // interval, the client can shutdown the connection, in which case,
00593   // the <accept> call can hang!
00594   if (this->accept_strategy_->acceptor ().enable (ACE_NONBLOCK) != 0)
00595     return -1;
00596 
00597   // Initialize the concurrency strategy.
00598 
00599   if (con_s == 0)
00600     {
00601       ACE_NEW_RETURN (con_s,
00602                       CONCURRENCY_STRATEGY,
00603                       -1);
00604       this->delete_concurrency_strategy_ = true;
00605     }
00606   this->concurrency_strategy_ = con_s;
00607 
00608   // Initialize the scheduling strategy.
00609 
00610   if (sch_s == 0)
00611     {
00612       ACE_NEW_RETURN (sch_s,
00613                       SCHEDULING_STRATEGY,
00614                       -1);
00615       this->delete_scheduling_strategy_ = true;
00616     }
00617   this->scheduling_strategy_ = sch_s;
00618 
00619   this->use_select_ = use_select;
00620 
00621   return this->reactor ()->register_handler
00622     (this,
00623      ACE_Event_Handler::ACCEPT_MASK);
00624 }
00625 
00626 // Simple constructor.
00627 
00628 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00629 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor
00630   (const ACE_TCHAR service_name[],
00631    const ACE_TCHAR service_description[],
00632    int use_select,
00633    int reuse_addr)
00634     : creation_strategy_ (0),
00635       delete_creation_strategy_ (false),
00636       accept_strategy_ (0),
00637       delete_accept_strategy_ (false),
00638       concurrency_strategy_ (0),
00639       delete_concurrency_strategy_ (false),
00640       scheduling_strategy_ (0),
00641       delete_scheduling_strategy_ (false),
00642       service_name_ (0),
00643       service_description_ (0)
00644 {
00645   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor");
00646 
00647   if (service_name != 0)
00648     ACE_ALLOCATOR (this->service_name_,
00649                    ACE_OS::strdup (service_name));
00650   if (service_description != 0)
00651     ACE_ALLOCATOR (this->service_description_,
00652                    ACE_OS::strdup (service_description));
00653   this->use_select_ = use_select;
00654   this->reuse_addr_ = reuse_addr;
00655 }
00656 
00657 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00658 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor
00659   (const ACE_PEER_ACCEPTOR_ADDR &addr,
00660    ACE_Reactor *reactor,
00661    ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
00662    ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> *acc_s,
00663    ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
00664    ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
00665    const ACE_TCHAR service_name[],
00666    const ACE_TCHAR service_description[],
00667    int use_select,
00668    int reuse_addr)
00669     : creation_strategy_ (0),
00670       delete_creation_strategy_ (false),
00671       accept_strategy_ (0),
00672       delete_accept_strategy_ (false),
00673       concurrency_strategy_ (0),
00674       delete_concurrency_strategy_ (false),
00675       scheduling_strategy_ (0),
00676       delete_scheduling_strategy_ (false),
00677       service_name_ (0),
00678       service_description_ (0)
00679 {
00680   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor");
00681 
00682   if (this->open (addr,
00683                   reactor,
00684                   cre_s,
00685                   acc_s,
00686                   con_s,
00687                   sch_s,
00688                   service_name,
00689                   service_description,
00690                   use_select,
00691                   reuse_addr) == -1)
00692     ACE_ERROR ((LM_ERROR,
00693                 ACE_TEXT ("%p\n"),
00694                 ACE_TEXT ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor")));
00695 }
00696 
00697 // Perform termination activities when <this> is removed from the
00698 // <ACE_Reactor>.
00699 
00700 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00701 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
00702                                                                        ACE_Reactor_Mask)
00703 {
00704   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
00705   // Guard against multiple closes.
00706   if (this->reactor () != 0)
00707     {
00708       ACE_HANDLE handle = this->get_handle ();
00709 
00710       if (this->delete_creation_strategy_)
00711         delete this->creation_strategy_;
00712       this->delete_creation_strategy_ = false;
00713       this->creation_strategy_ = 0;
00714 
00715       if (this->delete_accept_strategy_)
00716         delete this->accept_strategy_;
00717       this->delete_accept_strategy_ = false;
00718       this->accept_strategy_ = 0;
00719 
00720       if (this->delete_concurrency_strategy_)
00721         delete this->concurrency_strategy_;
00722       this->delete_concurrency_strategy_ = false;
00723       this->concurrency_strategy_ = 0;
00724 
00725       if (this->delete_scheduling_strategy_)
00726         delete this->scheduling_strategy_;
00727       this->delete_scheduling_strategy_ = false;
00728       this->scheduling_strategy_ = 0;
00729 
00730       // We must use the <handle> obtained *before* we deleted the
00731       // accept_strategy_...
00732 
00733       this->reactor ()->remove_handler
00734         (handle,
00735          ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
00736 
00737       // Set the Reactor to 0 so that we don't try to close down
00738       // again.
00739       this->reactor (0);
00740     }
00741   return 0;
00742 }
00743 
00744 // Bridge method for creating a <SVC_HANDLER>.  The strategy for
00745 // creating a <SVC_HANDLER> are configured into the Acceptor via it's
00746 // <creation_strategy_>.  The default is to create a new
00747 // <SVC_HANDLER>.  However, subclasses can override this strategy to
00748 // perform <SVC_HANDLER> creation in any way that they like (such as
00749 // creating subclass instances of <SVC_HANDLER>, using a singleton,
00750 // dynamically linking the handler, etc.).
00751 
00752 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00753 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
00754 {
00755   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler");
00756   return this->creation_strategy_->make_svc_handler (sh);
00757 }
00758 
00759 // Bridge method for accepting the new connection into the
00760 // <svc_handler>.  The default behavior delegates to the
00761 // <Strategy_Acceptor::accept> in the Acceptor_Strategy.
00762 
00763 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00764 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler
00765   (SVC_HANDLER *svc_handler)
00766 {
00767   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler");
00768   return this->accept_strategy_->accept_svc_handler (svc_handler);
00769 }
00770 
00771 // Bridge method for activating a <svc_handler> with the appropriate
00772 // concurrency strategy.  The default behavior of this method is to
00773 // activate the SVC_HANDLER by calling its open() method (which allows
00774 // the SVC_HANDLER to define its own concurrency strategy).  However,
00775 // subclasses can override this strategy to do more sophisticated
00776 // concurrency activations (such as creating the SVC_HANDLER as an
00777 // "active object" via multi-threading or multi-processing).
00778 
00779 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00780 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler
00781   (SVC_HANDLER *svc_handler)
00782 {
00783   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler");
00784   return this->concurrency_strategy_->activate_svc_handler
00785     (svc_handler,
00786      (void *) this);
00787 }
00788 
00789 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00790 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Strategy_Acceptor (void)
00791 {
00792   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Strategy_Acceptor");
00793   ACE_OS::free ((void *) this->service_name_);
00794   ACE_OS::free ((void *) this->service_description_);
00795   this->handle_close ();
00796 }
00797 
00798 // Signal the server to shutdown gracefully.
00799 
00800 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00801 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_signal (int, siginfo_t *, ucontext_t *)
00802 {
00803   ACE_Reactor::instance()->end_reactor_event_loop ();
00804   return 0;
00805 }
00806 
00807 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00808 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info (ACE_TCHAR **strp,
00809                                                                size_t length) const
00810 {
00811   ACE_TRACE ("ACE_Strategy_Acceptor::info");
00812 
00813   ACE_TCHAR buf[BUFSIZ];
00814   ACE_TCHAR service_addr_str[BUFSIZ];
00815   ACE_PEER_ACCEPTOR_ADDR addr;
00816 
00817   if (this->acceptor ().get_local_addr (addr) == -1)
00818     return -1;
00819   else if (addr.addr_to_string (service_addr_str,
00820                                 sizeof service_addr_str) == -1)
00821     return -1;
00822 
00823   // @@ Should add the protocol in...
00824   ACE_OS::sprintf (buf,
00825                    ACE_TEXT ("%s\t %s #%s\n"),
00826                    this->service_name_ == 0
00827                    ? ACE_TEXT ("<unknown>")
00828                    : this->service_name_,
00829                    service_addr_str,
00830                    this->service_description_ == 0
00831                    ? ACE_TEXT ("<unknown>")
00832                    : this->service_description_);
00833 
00834   if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
00835     return -1;
00836   else
00837     ACE_OS::strsncpy (*strp, buf, length);
00838   return static_cast<int> (ACE_OS::strlen (buf));
00839 }
00840 
00841 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00842 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini (void)
00843 {
00844   ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini");
00845   return this->ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close ();
00846 }
00847 
00848 ACE_ALLOC_HOOK_DEFINE(ACE_Oneshot_Acceptor)
00849 
00850 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
00851 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
00852 {
00853 #if defined (ACE_HAS_DUMP)
00854   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
00855 
00856   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00857   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nsvc_handler_ = %x"), this->svc_handler_));
00858   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nrestart_ = %d"), this->restart_));
00859   this->peer_acceptor_.dump ();
00860   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("delete_concurrency_strategy_ = %d"),
00861               delete_concurrency_strategy_));
00862   this->concurrency_strategy_->dump ();
00863   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00864 #endif /* ACE_HAS_DUMP */
00865 }
00866 
00867 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00868 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
00869   (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
00870    ACE_Reactor *reactor,
00871    ACE_Concurrency_Strategy<SVC_HANDLER> *con_s)
00872 {
00873   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
00874   this->reactor (reactor);
00875 
00876   // Initialize the concurrency strategy.
00877 
00878   if (con_s == 0)
00879     {
00880       ACE_NEW_RETURN (con_s,
00881                       ACE_Concurrency_Strategy<SVC_HANDLER>,
00882                       -1);
00883       this->delete_concurrency_strategy_ = true;
00884     }
00885   this->concurrency_strategy_ = con_s;
00886 
00887   // Reuse the addr, even if it is already in use...!
00888   return this->peer_acceptor_.open (local_addr, 1);
00889 }
00890 
00891 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00892 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor (void)
00893   : delete_concurrency_strategy_ (false)
00894 {
00895   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor");
00896   this->reactor (0);
00897 }
00898 
00899 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00900 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor
00901   (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
00902    ACE_Reactor *reactor,
00903    ACE_Concurrency_Strategy<SVC_HANDLER> *cs)
00904     : delete_concurrency_strategy_ (false)
00905 {
00906   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor");
00907   if (this->open (local_addr, reactor, cs) == -1)
00908     ACE_ERROR ((LM_ERROR,
00909                 ACE_TEXT ("%p\n"),
00910                 ACE_TEXT ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor")));
00911 }
00912 
00913 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00914 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Oneshot_Acceptor (void)
00915 {
00916   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Oneshot_Acceptor");
00917   this->handle_close ();
00918 }
00919 
00920 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00921 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close (void)
00922 {
00923   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close");
00924   return this->handle_close ();
00925 }
00926 
00927 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00928 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
00929                                                                       ACE_Reactor_Mask)
00930 {
00931   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
00932 
00933   // Guard against multiple closes.
00934   if (this->delete_concurrency_strategy_)
00935     {
00936       delete this->concurrency_strategy_;
00937       this->delete_concurrency_strategy_ = false;
00938       this->concurrency_strategy_ = 0;
00939     }
00940   // Note that if we aren't actually registered with the
00941   // ACE_Reactor then it's ok for this call to fail...
00942 
00943   if (this->reactor ())
00944     this->reactor ()->remove_handler
00945       (this,
00946        ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
00947 
00948   if (this->peer_acceptor_.close () == -1)
00949     ACE_ERROR ((LM_ERROR,
00950                 ACE_TEXT ("close\n")));
00951   return 0;
00952 }
00953 
00954 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00955 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_timeout
00956   (const ACE_Time_Value &tv,
00957    const void *arg)
00958 {
00959   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_timeout");
00960   errno = ETIME;
00961 
00962   if (this->svc_handler_->handle_timeout (tv, arg) == -1)
00963     this->svc_handler_->handle_close (this->svc_handler_->get_handle (),
00964                                       ACE_Event_Handler::TIMER_MASK);
00965 
00966   // Since we aren't necessarily registered with the Reactor, don't
00967   // bother to check the return value here...
00968   if (this->reactor ())
00969     this->reactor ()->remove_handler (this,
00970                                       ACE_Event_Handler::ACCEPT_MASK);
00971   return 0;
00972 }
00973 
00974 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00975 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::cancel (void)
00976 {
00977   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::cancel");
00978   return this->reactor () && this->reactor ()->cancel_timer (this);
00979 }
00980 
00981 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00982 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::register_handler
00983   (SVC_HANDLER *svc_handler,
00984    const ACE_Synch_Options &synch_options,
00985    int restart)
00986 {
00987   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::register_handler");
00988   // Can't do this if we don't have a Reactor.
00989   if (this->reactor () == 0)
00990     {
00991       errno = EINVAL;
00992       return -1;
00993     }
00994   else
00995     {
00996       this->svc_handler_ = svc_handler;
00997       this->restart_ = restart;
00998       ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value ();
00999 
01000       if (tv != 0
01001           && this->reactor ()->schedule_timer (this,
01002                                                synch_options.arg (),
01003                                                *tv) == 0)
01004         return -1;
01005       else
01006         return this->reactor ()->register_handler
01007           (this,
01008            ACE_Event_Handler::ACCEPT_MASK);
01009     }
01010 }
01011 
01012 // Bridge method for activating a <svc_handler> with the appropriate
01013 // concurrency strategy.  The default behavior of this method is to
01014 // activate the SVC_HANDLER by calling its open() method (which allows
01015 // the SVC_HANDLER to define its own concurrency strategy).  However,
01016 // subclasses can override this strategy to do more sophisticated
01017 // concurrency activations (such as creating the SVC_HANDLER as an
01018 // "active object" via multi-threading or multi-processing).
01019 
01020 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01021 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler
01022   (SVC_HANDLER *svc_handler)
01023 {
01024   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler");
01025   return this->concurrency_strategy_->activate_svc_handler
01026     (svc_handler,
01027      (void *) this);
01028 }
01029 
01030 // Factors out the code shared between the <accept> and <handle_input>
01031 // methods.
01032 
01033 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01034 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::shared_accept
01035   (SVC_HANDLER *svc_handler,
01036    ACE_PEER_ACCEPTOR_ADDR *remote_addr,
01037    ACE_Time_Value *timeout,
01038    int restart,
01039    int reset_new_handle)
01040 {
01041   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::shared_accept");
01042   if (svc_handler == 0)
01043     return -1;
01044 
01045   // Accept connection into the Svc_Handler.
01046   else if (this->peer_acceptor_.accept (svc_handler->peer (), // stream
01047                                         remote_addr, // remote address
01048                                         timeout, // timeout
01049                                         restart, // restart
01050                                         reset_new_handle // reset new handle
01051                                         ) == -1)
01052     {
01053       // Check whether we just timed out or whether we failed...
01054       if (!(errno == EWOULDBLOCK || errno == ETIME))
01055         // Close down handler to avoid memory leaks.
01056         svc_handler->close (0);
01057       return -1;
01058     }
01059   // Activate the <svc_handler> using the designated concurrency
01060   // strategy (note that this method becomes responsible for handling
01061   // errors and freeing up the memory if things go awry...)
01062   else
01063     return this->activate_svc_handler (svc_handler);
01064 }
01065 
01066 // Make a SVC_HANDLER, accept the connection into the SVC_HANDLER, and
01067 // then activate the SVC_HANDLER.  Note that SVC_HANDLER::open()
01068 // decides what type of concurrency strategy to use.
01069 
01070 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01071 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept
01072   (SVC_HANDLER *svc_handler,
01073    ACE_PEER_ACCEPTOR_ADDR *remote_addr,
01074    const ACE_Synch_Options &synch_options,
01075    int restart,
01076    int reset_new_handle)
01077 {
01078   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept");
01079   // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y >
01080   // 0) then this->connector_.connect() will block synchronously.  If
01081   // <use_reactor> is set then we don't want this to happen (since we
01082   // want the ACE_Reactor to do the timeout asynchronously).
01083   // Therefore, we'll force this->connector_ to use ACE_Time_Value (0,
01084   // 0) in this case...
01085 
01086   ACE_Time_Value *timeout;
01087   int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
01088 
01089   if (use_reactor)
01090     timeout = (ACE_Time_Value *) &ACE_Time_Value::zero;
01091   else
01092     timeout = (ACE_Time_Value *) synch_options.time_value ();
01093 
01094   if (this->shared_accept (svc_handler, // stream
01095                            remote_addr, // remote address
01096                            timeout, // timeout
01097                            restart, // restart
01098                            reset_new_handle // reset new handler
01099                            ) == -1)
01100     {
01101       if (use_reactor && errno == EWOULDBLOCK)
01102         // We couldn't accept right away, so let's wait in the
01103         // <ACE_Reactor>.
01104         this->register_handler (svc_handler,
01105                                 synch_options,
01106                                 restart);
01107       return -1;
01108     }
01109   return 0;
01110 }
01111 
01112 // Accepts one pending connection from a client (since we're the
01113 // "oneshot" Acceptor).
01114 
01115 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01116 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input (ACE_HANDLE)
01117 {
01118   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input");
01119   int result = 0;
01120 
01121   // Cancel any timer that might be pending.
01122   this->cancel ();
01123 
01124   // Try to find out if the implementation of the reactor that we are
01125   // using requires us to reset the event association for the newly
01126   // created handle.  This is because the newly created handle will
01127   // inherit the properties of the listen handle, including its event
01128   // associations.
01129   int reset_new_handle = this->reactor ()->uses_event_associations ();
01130 
01131   // There is a use-case whereby this object will be gone upon return
01132   // from shared_accept - if the Svc_Handler deletes this Oneshot_Acceptor
01133   // during the shared_accept/activation steps. So, do whatever we need
01134   // to do with this object before calling shared_accept.
01135   if (this->reactor ())
01136     this->reactor ()->remove_handler
01137       (this,
01138        ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
01139 
01140   if (this->shared_accept (this->svc_handler_, // stream
01141                            0, // remote address
01142                            0, // timeout
01143                            this->restart_, // restart
01144                            reset_new_handle // reset new handle
01145                            ) == -1)
01146     result = -1;
01147 
01148   return result;
01149 }
01150 
01151 // Hook called by the explicit dynamic linking facility.
01152 
01153 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01154 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init (int, ACE_TCHAR *[])
01155 {
01156   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init");
01157   return -1;
01158 }
01159 
01160 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01161 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini (void)
01162 {
01163   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini");
01164   return this->handle_close ();
01165 }
01166 
01167 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01168 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info (ACE_TCHAR **strp,
01169                                                               size_t length) const
01170 {
01171   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info");
01172   ACE_TCHAR buf[BUFSIZ];
01173   ACE_TCHAR addr_str[BUFSIZ];
01174   ACE_PEER_ACCEPTOR_ADDR addr;
01175 
01176   if (this->peer_acceptor_.get_local_addr (addr) == -1)
01177     return -1;
01178   else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1)
01179     return -1;
01180 
01181   ACE_OS::sprintf (buf,
01182                    ACE_TEXT ("%s\t %s %s"),
01183                    ACE_TEXT ("ACE_Oneshot_Acceptor"),
01184                    addr_str,
01185                    ACE_TEXT ("#oneshot acceptor factory\n"));
01186 
01187   if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
01188     return -1;
01189   else
01190     ACE_OS::strsncpy (*strp, buf, length);
01191   return static_cast<int> (ACE_OS::strlen (buf));
01192 }
01193 
01194 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01195 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend (void)
01196 {
01197   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend");
01198   return this->reactor () && this->reactor ()->suspend_handler (this);
01199 }
01200 
01201 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
01202 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume (void)
01203 {
01204   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume");
01205   return this->reactor () && this->reactor ()->resume_handler (this);
01206 }
01207 
01208 // Returns ACE_HANDLE of the underlying peer_acceptor.
01209 
01210 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
01211 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
01212 {
01213   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
01214   return this->peer_acceptor_.get_handle ();
01215 }
01216 
01217 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
01218 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
01219 {
01220   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
01221   return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
01222 }
01223 
01224 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
01225 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR & () const
01226 {
01227   ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR &");
01228   return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
01229 }
01230 
01231 ACE_END_VERSIONED_NAMESPACE_DECL
01232 
01233 #endif /* ACE_ACCEPTOR_CPP */

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7