Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Acceptor.cpp

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

Generated on Mon Jun 16 11:18:59 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002