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

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