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

Generated on Sun Jan 27 12:05:20 2008 for ACE by doxygen 1.3.6