Strategies_T.cpp

Go to the documentation of this file.
00001 // $Id: Strategies_T.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #ifndef ACE_STRATEGIES_T_CPP
00004 #define ACE_STRATEGIES_T_CPP
00005 
00006 #include "ace/Strategies_T.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #include "ace/Service_Repository.h"
00013 #include "ace/Service_Types.h"
00014 #include "ace/Thread_Manager.h"
00015 #include "ace/WFMO_Reactor.h"
00016 #include "ace/ACE.h"
00017 #include "ace/OS_NS_dlfcn.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/OS_Errno.h"
00020 #if defined (ACE_OPENVMS)
00021 # include "ace/Lib_Find.h"
00022 #endif
00023 
00024 #if !defined (__ACE_INLINE__)
00025 #include "ace/Strategies_T.inl"
00026 #endif /* __ACE_INLINE__ */
00027 
00028 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00029 
00030 template<class SVC_HANDLER>
00031 ACE_Recycling_Strategy<SVC_HANDLER>::~ACE_Recycling_Strategy (void)
00032 {
00033 }
00034 
00035 template<class SVC_HANDLER> int
00036 ACE_Recycling_Strategy<SVC_HANDLER>::assign_recycler (SVC_HANDLER *svc_handler,
00037                                                       ACE_Connection_Recycling_Strategy *recycler,
00038                                                       const void *recycling_act)
00039 {
00040   svc_handler->recycler (recycler, recycling_act);
00041   return 0;
00042 }
00043 
00044 template<class SVC_HANDLER> int
00045 ACE_Recycling_Strategy<SVC_HANDLER>::prepare_for_recycling (SVC_HANDLER *svc_handler)
00046 {
00047   return svc_handler->recycle ();
00048 }
00049 
00050 template <class SVC_HANDLER>
00051 ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy (void)
00052 {
00053   ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy");
00054   if (this->delete_svc_handler_)
00055     delete this->svc_handler_;
00056 }
00057 
00058 // Create a Singleton SVC_HANDLER by always returning the same
00059 // SVC_HANDLER.
00060 
00061 template <class SVC_HANDLER> int
00062 ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh)
00063 {
00064   ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler");
00065   sh = this->svc_handler_;
00066   return 0;
00067 }
00068 
00069 template <class SVC_HANDLER> int
00070 ACE_Singleton_Strategy<SVC_HANDLER>::open (SVC_HANDLER *sh,
00071                                            ACE_Thread_Manager *)
00072 {
00073   ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::open");
00074 
00075   if (this->delete_svc_handler_)
00076     delete this->svc_handler_;
00077 
00078   // If <sh> is NULL then create a new <SVC_HANDLER>.
00079   if (sh == 0)
00080     {
00081       ACE_NEW_RETURN (this->svc_handler_,
00082                       SVC_HANDLER,
00083                       -1);
00084       this->delete_svc_handler_ = true;
00085     }
00086   else
00087     {
00088       this->svc_handler_ = sh;
00089       this->delete_svc_handler_ = false;
00090     }
00091 
00092   return 0;
00093 }
00094 
00095 template <class SVC_HANDLER> int
00096 ACE_DLL_Strategy<SVC_HANDLER>::open (const ACE_TCHAR dll_name[],
00097                                      const ACE_TCHAR factory_function[],
00098                                      const ACE_TCHAR svc_name[],
00099                                      ACE_Service_Repository *svc_rep,
00100                                      ACE_Thread_Manager *thr_mgr)
00101 {
00102   ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::open");
00103   this->inherited::open (thr_mgr);
00104   ACE_OS::strcpy (this->dll_name_, dll_name);
00105   ACE_OS::strcpy (this->factory_function_, factory_function);
00106   ACE_OS::strcpy (this->svc_name_, svc_name);
00107   this->svc_rep_ = svc_rep;
00108   return 0;
00109 }
00110 
00111 // Create a SVC_HANDLER by dynamically linking it from a DLL.
00112 
00113 template <class SVC_HANDLER> int
00114 ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh)
00115 {
00116   ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler");
00117 
00118   // Open the shared library.
00119   ACE_SHLIB_HANDLE handle = ACE_OS::dlopen (this->dll_name_);
00120 
00121   // Extract the factory function.
00122 #if defined (ACE_OPENVMS)
00123   SVC_HANDLER *(*factory)(void) =
00124     (SVC_HANDLER *(*)(void)) ACE::ldsymbol (handle,
00125                                             this->factory_function_);
00126 #else
00127   SVC_HANDLER *(*factory)(void) =
00128     (SVC_HANDLER *(*)(void)) ACE_OS::dlsym (handle,
00129                                             this->factory_function_);
00130 #endif
00131 
00132   // Call the factory function to obtain the new SVC_Handler (should
00133   // use RTTI here when it becomes available...)
00134   SVC_HANDLER *svc_handler = 0;
00135 
00136   ACE_ALLOCATOR_RETURN (svc_handler, (*factory)(), -1);
00137 
00138   if (svc_handler != 0)
00139     {
00140       // Create an ACE_Service_Type containing the SVC_Handler and
00141       // insert into this->svc_rep_;
00142 
00143       ACE_Service_Type_Impl *stp = 0;
00144       ACE_NEW_RETURN (stp,
00145                       ACE_Service_Object_Type (svc_handler,
00146                                                this->svc_name_),
00147                       -1);
00148 
00149       ACE_Service_Type *srp = 0;
00150 
00151       ACE_NEW_RETURN (srp,
00152                       ACE_Service_Type (this->svc_name_,
00153                                         stp,
00154                                         handle,
00155                                         1),
00156                       -1);
00157       if (srp == 0)
00158         {
00159           delete stp;
00160           errno = ENOMEM;
00161           return -1;
00162         }
00163 
00164       if (this->svc_rep_->insert (srp) == -1)
00165         return -1;
00166       // @@ Somehow, we need to deal with this->thr_mgr_...
00167     }
00168 
00169   sh = svc_handler;
00170   return 0;
00171 }
00172 
00173 // Default behavior is to activate the SVC_HANDLER by calling it's
00174 // open() method, which allows the SVC_HANDLER to determine its own
00175 // concurrency strategy.
00176 
00177 template <class SVC_HANDLER> int
00178 ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler,
00179                                                              void *arg)
00180 {
00181   ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler");
00182 
00183   int result = 0;
00184 
00185   // See if we should enable non-blocking I/O on the <svc_handler>'s
00186   // peer.
00187   if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0)
00188     {
00189       if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
00190         result = -1;
00191     }
00192   // Otherwise, make sure it's disabled by default.
00193   else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
00194     result = -1;
00195 
00196   if (result == 0 && svc_handler->open (arg) == -1)
00197     result = -1;
00198 
00199   if (result == -1)
00200     svc_handler->close (0);
00201 
00202   return result;
00203 }
00204 
00205 template <class SVC_HANDLER> int
00206 ACE_Reactive_Strategy<SVC_HANDLER>::open (ACE_Reactor *reactor,
00207                                           ACE_Reactor_Mask mask,
00208                                           int flags)
00209 {
00210   ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::open");
00211   this->reactor_ = reactor;
00212   this->mask_ = mask;
00213   this->flags_ = flags;
00214 
00215   // Must have a <Reactor>
00216   if (this->reactor_ == 0)
00217     return -1;
00218   else
00219     return 0;
00220 }
00221 
00222 template <class SVC_HANDLER> int
00223 ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler,
00224                                                           void *arg)
00225 {
00226   ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler");
00227 
00228   int result = 0;
00229 
00230   if (this->reactor_ == 0)
00231     result = -1;
00232 
00233   // Register with the Reactor with the appropriate <mask>.
00234   else if (this->reactor_->register_handler (svc_handler, this->mask_) == -1)
00235     result = -1;
00236 
00237   // If the implementation of the reactor uses event associations
00238   else if (this->reactor_->uses_event_associations ())
00239     {
00240       // If we don't have non-block on, it won't work with
00241       // WFMO_Reactor
00242       // This maybe too harsh
00243       // if (!ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK))
00244       // goto failure;
00245       if (svc_handler->open (arg) != -1)
00246         return 0;
00247       else
00248         result = -1;
00249     }
00250   else
00251     // Call up to our parent to do the SVC_HANDLER initialization.
00252     return this->inherited::activate_svc_handler (svc_handler, arg);
00253 
00254   if (result == -1)
00255     svc_handler->close (0);
00256 
00257   return result;
00258 }
00259 
00260 template <class SVC_HANDLER> int
00261 ACE_Thread_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr,
00262                                         long thr_flags,
00263                                         int n_threads,
00264                                         int flags)
00265 {
00266   ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::open");
00267   this->thr_mgr_ = thr_mgr;
00268   this->n_threads_ = n_threads;
00269   this->thr_flags_ = thr_flags;
00270   this->flags_ = flags;
00271 
00272   // Must have a thread manager!
00273   if (this->thr_mgr_ == 0)
00274     ACE_ERROR_RETURN ((LM_ERROR,
00275                        ACE_TEXT ("error: must have a non-NULL thread manager\n")),
00276                       -1);
00277   else
00278     return 0;
00279 }
00280 
00281 template <class SVC_HANDLER> int
00282 ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler,
00283                                                         void *arg)
00284 {
00285   ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler");
00286   // Call up to our parent to do the SVC_HANDLER initialization.
00287   if (this->inherited::activate_svc_handler (svc_handler,
00288                                              arg) == -1)
00289     return -1;
00290   else
00291     // Turn the <svc_handler> into an active object (if it isn't
00292     // already one as a result of the first activation...)
00293     return svc_handler->activate (this->thr_flags_,
00294                                   this->n_threads_);
00295 }
00296 
00297 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00298 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
00299   (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int reuse_addr)
00300 {
00301   this->reuse_addr_ = reuse_addr;
00302   this->peer_acceptor_addr_ = local_addr;
00303   if (this->peer_acceptor_.open (local_addr,
00304                                  reuse_addr) == -1)
00305     return -1;
00306 
00307   // Set the peer acceptor's handle into non-blocking mode.  This is a
00308   // safe-guard against the race condition that can otherwise occur
00309   // between the time when <select> indicates that a passive-mode
00310   // socket handle is "ready" and when we call <accept>.  During this
00311   // interval, the client can shutdown the connection, in which case,
00312   // the <accept> call can hang!
00313   this->peer_acceptor_.enable (ACE_NONBLOCK);
00314   return 0;
00315 }
00316 
00317 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
00318 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy
00319   (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
00320    int reuse_addr,
00321    ACE_Reactor *reactor)
00322     : reactor_ (reactor)
00323 {
00324   ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy");
00325 
00326   if (this->open (local_addr, reuse_addr) == -1)
00327     ACE_ERROR ((LM_ERROR,
00328                 ACE_TEXT ("%p\n"),
00329                 ACE_TEXT ("open")));
00330 }
00331 
00332 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
00333 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler
00334   (SVC_HANDLER *svc_handler)
00335 {
00336   ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler");
00337 
00338   // Try to find out if the implementation of the reactor that we are
00339   // using requires us to reset the event association for the newly
00340   // created handle. This is because the newly created handle will
00341   // inherit the properties of the listen handle, including its event
00342   // associations.
00343   int reset_new_handle = this->reactor_->uses_event_associations ();
00344 
00345   if (this->peer_acceptor_.accept (svc_handler->peer (), // stream
00346                                    0, // remote address
00347                                    0, // timeout
00348                                    1, // restart
00349                                    reset_new_handle  // reset new handler
00350                                    ) == -1)
00351     {
00352       // Ensure that errno is preserved in case the svc_handler
00353       // close() method resets it
00354       ACE_Errno_Guard error(errno);
00355 
00356       // Close down handler to avoid memory leaks.
00357       svc_handler->close (0);
00358 
00359       return -1;
00360     }
00361   else
00362     return 0;
00363 }
00364 
00365 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00366 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
00367 (SVC_HANDLER *&sh,
00368  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00369  ACE_Time_Value *timeout,
00370  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00371  int reuse_addr,
00372  int flags,
00373  int perms)
00374 {
00375   ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler");
00376 
00377   return this->connector_.connect (sh->peer (),
00378                                    remote_addr,
00379                                    timeout,
00380                                    local_addr,
00381                                    reuse_addr,
00382                                    flags,
00383                                    perms);
00384 }
00385 
00386 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
00387 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
00388 (SVC_HANDLER *&sh,
00389  SVC_HANDLER *&sh_copy,
00390  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00391  ACE_Time_Value *timeout,
00392  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00393  int reuse_addr,
00394  int flags,
00395  int perms)
00396 {
00397   ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler");
00398 
00399   int const result =
00400     this->connector_.connect (sh->peer (),
00401                               remote_addr,
00402                               timeout,
00403                               local_addr,
00404                               reuse_addr,
00405                               flags,
00406                               perms);
00407   sh_copy = sh;
00408   return result;
00409 }
00410 
00411 template <class SVC_HANDLER> int
00412 ACE_Process_Strategy<SVC_HANDLER>::open (size_t n_processes,
00413                                          ACE_Event_Handler *acceptor,
00414                                          ACE_Reactor *reactor,
00415                                          int avoid_zombies)
00416 {
00417   ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::open");
00418   this->n_processes_ = n_processes;
00419   this->acceptor_ = acceptor;
00420   this->reactor_ = reactor;
00421   this->flags_ = avoid_zombies;
00422 
00423   return 0;
00424 }
00425 
00426 template <class SVC_HANDLER> int
00427 ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler,
00428                                                          void *arg)
00429 {
00430   ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler");
00431 
00432   // If <flags_> is non-0 then we won't create zombies.
00433   switch (ACE::fork (ACE_TEXT ("child"), this->flags_))
00434     {
00435     case -1:
00436       {
00437         ACE_Errno_Guard error (errno);
00438         svc_handler->destroy ();
00439       }
00440       ACE_ERROR_RETURN ((LM_ERROR,
00441                          ACE_TEXT ("%p\n"),
00442                          ACE_TEXT ("fork")),
00443                         -1);
00444       /* NOTREACHED */
00445     case 0: // In child process.
00446 
00447       // Close down the SOCK_Acceptor's handle since we don't need to
00448       // keep it open.
00449       if (this->acceptor_ != 0)
00450         // Ignore the return value here...
00451         (void) this->reactor_->remove_handler (this->acceptor_,
00452                                                ACE_Event_Handler::ACCEPT_MASK);
00453 
00454       // Call up to our ancestor in the inheritance to do the
00455       // SVC_HANDLER initialization.
00456       return this->inherited::activate_svc_handler (svc_handler, arg);
00457       /* NOTREACHED */
00458     default: // In parent process.
00459       // We need to close down the <SVC_HANDLER> here because it's
00460       // running in the child.
00461       svc_handler->destroy ();
00462       return 0;
00463     }
00464 }
00465 
00466 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX>
00467 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::ACE_Cached_Connect_Strategy
00468 (creation_strategy_type *cre_s,
00469  ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
00470  ACE_Recycling_Strategy<SVC_HANDLER> *rec_s,
00471  MUTEX *lock,
00472  bool delete_lock)
00473   : lock_ (lock),
00474     delete_lock_ (delete_lock),
00475     reverse_lock_ (0),
00476     creation_strategy_ (0),
00477     delete_creation_strategy_ (false),
00478     concurrency_strategy_ (0),
00479     delete_concurrency_strategy_ (false),
00480     recycling_strategy_ (0),
00481     delete_recycling_strategy_ (false)
00482 {
00483   // Create a new lock if necessary.
00484   if (this->lock_ == 0)
00485     {
00486       ACE_NEW (this->lock_,
00487                MUTEX);
00488 
00489       this->delete_lock_ = true;
00490     }
00491 
00492   ACE_NEW (this->reverse_lock_,
00493            REVERSE_MUTEX (*this->lock_));
00494 
00495   if (this->open (cre_s,
00496                   con_s,
00497                   rec_s) == -1)
00498     ACE_ERROR ((LM_ERROR,
00499                 ACE_TEXT ("%p\n"),
00500                 ACE_TEXT ("ACE_Cached_Connect_Strategy::ACE_Cached_Connect_Strategy")));
00501 }
00502 
00503 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX>
00504 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::~ACE_Cached_Connect_Strategy (void)
00505 {
00506   if (this->delete_lock_)
00507     delete this->lock_;
00508 
00509   delete this->reverse_lock_;
00510 
00511   if (this->delete_creation_strategy_)
00512     delete this->creation_strategy_;
00513   this->delete_creation_strategy_ = false;
00514   this->creation_strategy_ = 0;
00515 
00516   if (this->delete_concurrency_strategy_)
00517     delete this->concurrency_strategy_;
00518   this->delete_concurrency_strategy_ = false;
00519   this->concurrency_strategy_ = 0;
00520 
00521   if (this->delete_recycling_strategy_)
00522     delete this->recycling_strategy_;
00523   this->delete_recycling_strategy_ = false;
00524   this->recycling_strategy_ = 0;
00525 
00526   // Close down all cached service handlers.
00527   CONNECTION_MAP_ENTRY *entry = 0;
00528   for (CONNECTION_MAP_ITERATOR iterator (connection_map_);
00529        iterator.next (entry);
00530        iterator.advance ())
00531     {
00532       entry->int_id_->recycler (0, 0);
00533       entry->int_id_->close ();
00534     }
00535 }
00536 
00537 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00538 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::open
00539 (creation_strategy_type *cre_s,
00540  ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
00541  ACE_Recycling_Strategy<SVC_HANDLER> *rec_s)
00542 {
00543   // Initialize the creation strategy.
00544 
00545   // First we decide if we need to clean up.
00546   if (this->creation_strategy_ != 0 &&
00547       this->delete_creation_strategy_ &&
00548       cre_s != 0)
00549     {
00550       delete this->creation_strategy_;
00551       this->creation_strategy_ = 0;
00552       this->delete_creation_strategy_ = false;
00553     }
00554 
00555   if (cre_s != 0)
00556     this->creation_strategy_ = cre_s;
00557   else if (this->creation_strategy_ == 0)
00558     {
00559       ACE_NEW_RETURN (this->creation_strategy_,
00560                       CREATION_STRATEGY, -1);
00561       this->delete_creation_strategy_ = true;
00562     }
00563 
00564   // Initialize the concurrency strategy.
00565 
00566   if (this->concurrency_strategy_ != 0 &&
00567       this->delete_concurrency_strategy_ &&
00568       con_s != 0)
00569     {
00570       delete this->concurrency_strategy_;
00571       this->concurrency_strategy_ = 0;
00572       this->delete_concurrency_strategy_ = false;
00573     }
00574 
00575   if (con_s != 0)
00576     this->concurrency_strategy_ = con_s;
00577   else if (this->concurrency_strategy_ == 0)
00578     {
00579       ACE_NEW_RETURN (this->concurrency_strategy_,
00580                       CONCURRENCY_STRATEGY, -1);
00581       this->delete_concurrency_strategy_ = true;
00582     }
00583 
00584   // Initialize the recycling strategy.
00585 
00586   if (this->recycling_strategy_ != 0 &&
00587       this->delete_recycling_strategy_ &&
00588       rec_s != 0)
00589     {
00590       delete this->recycling_strategy_;
00591       this->recycling_strategy_ = 0;
00592       this->delete_recycling_strategy_ = false;
00593     }
00594 
00595   if (rec_s != 0)
00596     this->recycling_strategy_ = rec_s;
00597   else if (this->recycling_strategy_ == 0)
00598     {
00599       ACE_NEW_RETURN (this->recycling_strategy_,
00600                       RECYCLING_STRATEGY, -1);
00601       this->delete_recycling_strategy_ = true;
00602     }
00603 
00604   return 0;
00605 }
00606 
00607 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00608 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::make_svc_handler
00609   (SVC_HANDLER *&sh)
00610 {
00611   return this->creation_strategy_->make_svc_handler (sh);
00612 }
00613 
00614 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00615 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::activate_svc_handler
00616   (SVC_HANDLER *svc_handler)
00617 {
00618   return this->concurrency_strategy_->activate_svc_handler (svc_handler);
00619 }
00620 
00621 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00622 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::assign_recycler
00623   (SVC_HANDLER *svc_handler,
00624    ACE_Connection_Recycling_Strategy *recycler,
00625    const void *recycling_act)
00626 {
00627   return this->recycling_strategy_->assign_recycler (svc_handler,
00628                                                      recycler,
00629                                                      recycling_act);
00630 }
00631 
00632 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00633 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::prepare_for_recycling
00634   (SVC_HANDLER *svc_handler)
00635 {
00636   return this->recycling_strategy_->prepare_for_recycling (svc_handler);
00637 }
00638 
00639 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00640 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::check_hint_i
00641 (SVC_HANDLER *&sh,
00642  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00643  ACE_Time_Value *timeout,
00644  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00645  int reuse_addr,
00646  int flags,
00647  int perms,
00648  CONNECTION_MAP_ENTRY *&entry,
00649  int &found)
00650 {
00651   ACE_UNUSED_ARG (remote_addr);
00652   ACE_UNUSED_ARG (timeout);
00653   ACE_UNUSED_ARG (local_addr);
00654   ACE_UNUSED_ARG (reuse_addr);
00655   ACE_UNUSED_ARG (flags);
00656   ACE_UNUSED_ARG (perms);
00657 
00658   found = 0;
00659 
00660   // Get the recycling act for the svc_handler
00661   CONNECTION_MAP_ENTRY *possible_entry = (CONNECTION_MAP_ENTRY *) sh->recycling_act ();
00662 
00663   // Check to see if the hint svc_handler has been closed down
00664   if (possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED)
00665     {
00666       // If close, decrement refcount
00667       if (possible_entry->ext_id_.decrement () == 0)
00668         {
00669           // If refcount goes to zero, close down the svc_handler
00670           possible_entry->int_id_->recycler (0, 0);
00671           possible_entry->int_id_->close ();
00672           this->purge_i (possible_entry);
00673         }
00674 
00675       // Hint not successful
00676       found = 0;
00677 
00678       // Reset hint
00679       sh = 0;
00680     }
00681 
00682   // If hint is not closed, see if it is connected to the correct
00683   // address and is recyclable
00684   else if ((possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE ||
00685             possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE) &&
00686            possible_entry->ext_id_.subject () == remote_addr)
00687     {
00688       // Hint successful
00689       found = 1;
00690 
00691       // Tell the <svc_handler> that it should prepare itself for
00692       // being recycled.
00693       this->prepare_for_recycling (sh);
00694     }
00695   else
00696     {
00697       // This hint will not be used.
00698       possible_entry->ext_id_.decrement ();
00699 
00700       // Hint not successful
00701       found = 0;
00702 
00703       // If <sh> is not connected to the correct address or is busy,
00704       // we will not use it.
00705       sh = 0;
00706     }
00707 
00708   if (found)
00709     entry = possible_entry;
00710 
00711   return 0;
00712 }
00713 
00714 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00715 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::find_or_create_svc_handler_i
00716 (SVC_HANDLER *&sh,
00717  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00718  ACE_Time_Value *timeout,
00719  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00720  int reuse_addr,
00721  int flags,
00722  int perms,
00723  CONNECTION_MAP_ENTRY *&entry,
00724  int &found)
00725 {
00726   // Explicit type conversion
00727   REFCOUNTED_HASH_RECYCLABLE_ADDRESS search_addr (remote_addr);
00728 
00729   // Try to find the address in the cache.  Only if we don't find it
00730   // do we create a new <SVC_HANDLER> and connect it with the server.
00731   if (this->find (search_addr, entry) == -1)
00732     {
00733       // Set the flag
00734       found = 0;
00735 
00736       // We need to use a temporary variable here since we are not
00737       // allowed to change <sh> because other threads may use this
00738       // when we let go of the lock during the OS level connect.
00739       //
00740       // Note that making a new svc_handler, connecting remotely,
00741       // binding to the map, and assigning of the hint and recycler
00742       // should be atomic to the outside world.
00743       SVC_HANDLER *potential_handler = 0;
00744 
00745       // Create a new svc_handler
00746       if (this->make_svc_handler (potential_handler) == -1)
00747         return -1;
00748 
00749       // Actively establish the connection.  This is a timed blocking
00750       // connect.
00751       if (this->new_connection (potential_handler,
00752                                 remote_addr,
00753                                 timeout,
00754                                 local_addr,
00755                                 reuse_addr,
00756                                 flags,
00757                                 perms) == -1)
00758         {
00759           // If connect() failed because of timeouts, we have to
00760           // reject the connection entirely. This is necessary since
00761           // currently there is no way for the non-blocking connects
00762           // to complete and for the <Connector> to notify the cache
00763           // of the completion of connect().
00764           if (errno == EWOULDBLOCK)
00765             errno = ENOTSUP;
00766 
00767           // Close the svc handler.
00768           potential_handler->close (0);
00769 
00770           return -1;
00771         }
00772       else
00773         {
00774           // Insert the new SVC_HANDLER instance into the cache.
00775           if (this->connection_map_.bind (search_addr,
00776                                           potential_handler,
00777                                           entry) == -1)
00778             {
00779               // Close the svc handler.
00780               potential_handler->close (0);
00781 
00782               return -1;
00783             }
00784 
00785           // Everything succeeded as planned. Assign <sh> to <potential_handler>.
00786           sh = potential_handler;
00787 
00788           // Set the recycler and the recycling act
00789           this->assign_recycler (sh, this, entry);
00790         }
00791     }
00792   else
00793     // We found a cached svc_handler.
00794     {
00795       // Set the flag
00796       found = 1;
00797 
00798       // Get the cached <svc_handler>
00799       sh = entry->int_id_;
00800 
00801       // Tell the <svc_handler> that it should prepare itself for
00802       // being recycled.
00803       this->prepare_for_recycling (sh);
00804     }
00805 
00806   return 0;
00807 }
00808 
00809 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00810 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::new_connection
00811 (SVC_HANDLER *&sh,
00812  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00813  ACE_Time_Value *timeout,
00814  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00815  int reuse_addr,
00816  int flags,
00817  int perms)
00818 {
00819   // Yow, Reverse Guard!  Let go of the lock for the duration of the
00820   // actual connect.  This will allow other threads to hack on the
00821   // connection cache while this thread creates the new connection.
00822   ACE_GUARD_RETURN (REVERSE_MUTEX, ace_mon, *this->reverse_lock_, -1);
00823 
00824   return this->CONNECT_STRATEGY::connect_svc_handler (sh,
00825                                                       remote_addr,
00826                                                       timeout,
00827                                                       local_addr,
00828                                                       reuse_addr,
00829                                                       flags,
00830                                                       perms);
00831 }
00832 
00833 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00834 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler
00835 (SVC_HANDLER *&sh,
00836  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00837  ACE_Time_Value *timeout,
00838  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00839  int reuse_addr,
00840  int flags,
00841  int perms)
00842 {
00843   int found = 0;
00844 
00845   // This artificial scope is required since we need to let go of the
00846   // lock *before* registering the newly created handler with the
00847   // Reactor.
00848   {
00849     // Synchronization is required here as the setting of the
00850     // recyclable state must be done atomically with the finding and
00851     // binding of the service handler in the cache.
00852     ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
00853 
00854     int result = this->connect_svc_handler_i (sh,
00855                                               remote_addr,
00856                                               timeout,
00857                                               local_addr,
00858                                               reuse_addr,
00859                                               flags,
00860                                               perms,
00861                                               found);
00862     if (result != 0)
00863       return result;
00864 
00865   }
00866 
00867   // If it is a new connection, activate it.
00868   //
00869   // Note: This activation is outside the scope of the lock of the
00870   // cached connector.  This is necessary to avoid subtle deadlock
00871   // conditions with this lock and the Reactor lock.
00872 
00873   if (!found)
00874     {
00875       if (this->activate_svc_handler (sh) == -1)
00876         {
00877           // If an error occurs while activating the handler, the
00878           // <activate_svc_handler> method will close the handler.
00879           // This in turn will remove this entry from the internal
00880           // table.
00881 
00882           // Synchronization is required here as the setting of the
00883           // handler to zero must be done atomically with the users of
00884           // the cache.
00885           ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
00886 
00887           // Reset handler.
00888           sh = 0;
00889 
00890           return -1;
00891         }
00892     }
00893 
00894   return 0;
00895 }
00896 
00897 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00898 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler
00899 (SVC_HANDLER *&sh,
00900  SVC_HANDLER *&sh_copy,
00901  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00902  ACE_Time_Value *timeout,
00903  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00904  int reuse_addr,
00905  int flags,
00906  int perms)
00907 {
00908   int found = 0;
00909 
00910   // This artificial scope is required since we need to let go of the
00911   // lock *before* registering the newly created handler with the
00912   // Reactor.
00913   {
00914     // Synchronization is required here as the setting of the
00915     // recyclable state must be done atomically with the finding and
00916     // binding of the service handler in the cache.
00917     ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
00918 
00919     int result = this->connect_svc_handler_i (sh,
00920                                               remote_addr,
00921                                               timeout,
00922                                               local_addr,
00923                                               reuse_addr,
00924                                               flags,
00925                                               perms,
00926                                               found);
00927     sh_copy = sh;
00928 
00929     if (result != 0)
00930       return result;
00931 
00932   }
00933 
00934   // If it is a new connection, activate it.
00935   //
00936   // Note: This activation is outside the scope of the lock of the
00937   // cached connector.  This is necessary to avoid subtle deadlock
00938   // conditions with this lock and the Reactor lock.
00939 
00940   if (!found)
00941     {
00942       if (this->activate_svc_handler (sh_copy) == -1)
00943         {
00944           // If an error occurs while activating the handler, the
00945           // <activate_svc_handler> method will close the handler.
00946           // This in turn will remove this entry from the internal
00947           // table.
00948 
00949           // Synchronization is required here as the setting of the
00950           // handler to zero must be done atomically with the users of
00951           // the cache.
00952           ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
00953 
00954           // Reset handler.
00955           sh = 0;
00956           sh_copy = 0;
00957 
00958           return -1;
00959         }
00960     }
00961 
00962   return 0;
00963 }
00964 
00965 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
00966 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler_i
00967 (SVC_HANDLER *&sh,
00968  const ACE_PEER_CONNECTOR_ADDR &remote_addr,
00969  ACE_Time_Value *timeout,
00970  const ACE_PEER_CONNECTOR_ADDR &local_addr,
00971  int reuse_addr,
00972  int flags,
00973  int perms,
00974  int& found)
00975 {
00976   CONNECTION_MAP_ENTRY *entry = 0;
00977 
00978   // Check if the user passed a hint svc_handler
00979   if (sh != 0)
00980     {
00981       int result = this->check_hint_i (sh,
00982                                        remote_addr,
00983                                        timeout,
00984                                        local_addr,
00985                                        reuse_addr,
00986                                        flags,
00987                                        perms,
00988                                        entry,
00989                                        found);
00990       if (result != 0)
00991         return result;
00992     }
00993 
00994   // If not found
00995   if (!found)
00996     {
00997       int result = this->find_or_create_svc_handler_i (sh,
00998                                                        remote_addr,
00999                                                        timeout,
01000                                                        local_addr,
01001                                                        reuse_addr,
01002                                                        flags,
01003                                                        perms,
01004                                                        entry,
01005                                                        found);
01006       if (result != 0)
01007         return result;
01008     }
01009 
01010   // For all successful cases: mark the <svc_handler> in the cache
01011   // as being <in_use>.  Therefore recyclable is BUSY.
01012   entry->ext_id_.recycle_state (ACE_RECYCLABLE_BUSY);
01013 
01014   // And increment the refcount
01015   entry->ext_id_.increment ();
01016 
01017   return 0;
01018 }
01019 
01020 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01021 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache (const void *recycling_act)
01022 {
01023   // Synchronization is required here as the setting of the recyclable
01024   // state must be done atomically with respect to other threads that
01025   // are querying the cache.
01026   ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
01027 
01028   return this->cache_i (recycling_act);
01029 }
01030 
01031 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01032 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache_i (const void *recycling_act)
01033 {
01034   // The wonders and perils of ACT
01035   CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
01036 
01037   // Mark the <svc_handler> in the cache as not being <in_use>.
01038   // Therefore recyclable is IDLE.
01039   entry->ext_id_.recycle_state (ACE_RECYCLABLE_IDLE_AND_PURGABLE);
01040 
01041   return 0;
01042 }
01043 
01044 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01045 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state (const void *recycling_act,
01046                                                                                       ACE_Recyclable_State new_state)
01047 {
01048   // Synchronization is required here as the setting of the recyclable
01049   // state must be done atomically with respect to other threads that
01050   // are querying the cache.
01051   ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
01052 
01053   return this->recycle_state_i (recycling_act,
01054                                 new_state);
01055 }
01056 
01057 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01058 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state_i (const void *recycling_act,
01059                                                                                         ACE_Recyclable_State new_state)
01060 {
01061   // The wonders and perils of ACT
01062   CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
01063 
01064   // Mark the <svc_handler> in the cache as not being <in_use>.
01065   // Therefore recyclable is IDLE.
01066   entry->ext_id_.recycle_state (new_state);
01067 
01068   return 0;
01069 }
01070 
01071 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Recyclable_State
01072 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state (const void *recycling_act) const
01073 {
01074   // Const cast.
01075   SELF *fake_this = const_cast<SELF *> (this);
01076 
01077   // Synchronization is required here.
01078   ACE_GUARD_RETURN (MUTEX, ace_mon, *fake_this->lock_, ACE_RECYCLABLE_UNKNOWN);
01079 
01080   return this->recycle_state_i (recycling_act);
01081 }
01082 
01083 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Recyclable_State
01084 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state_i (const void *recycling_act) const
01085 {
01086   // The wonders and perils of ACT
01087   CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
01088 
01089   // Mark the <svc_handler> in the cache as not being <in_use>.
01090   // Therefore recyclable is IDLE.
01091   return entry->ext_id_.recycle_state ();
01092 }
01093 
01094 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01095 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge (const void *recycling_act)
01096 {
01097   // Excluded other threads from changing cache while we take this
01098   // entry out.
01099   ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
01100 
01101   return this->purge_i (recycling_act);
01102 }
01103 
01104 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01105 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge_i (const void *recycling_act)
01106 {
01107   // The wonders and perils of ACT
01108   CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
01109 
01110   return this->connection_map_.unbind (entry);
01111 }
01112 
01113 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01114 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::mark_as_closed (const void *recycling_act)
01115 {
01116   // Excluded other threads from changing cache while we take this
01117   // entry out.
01118   ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
01119 
01120   return this->mark_as_closed_i (recycling_act);
01121 }
01122 
01123 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01124 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::mark_as_closed_i (const void *recycling_act)
01125 {
01126   // The wonders and perils of ACT
01127   CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
01128 
01129   // Mark the <svc_handler> in the cache as CLOSED.
01130   entry->ext_id_.recycle_state (ACE_RECYCLABLE_CLOSED);
01131 
01132   return 0;
01133 }
01134 
01135 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01136 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cleanup_hint (const void *recycling_act,
01137                                                                                      void **act_holder)
01138 {
01139   // Excluded other threads from changing cache while we take this
01140   // entry out.
01141   ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1);
01142 
01143   return this->cleanup_hint_i (recycling_act,
01144                                act_holder);
01145 }
01146 
01147 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01148 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cleanup_hint_i (const void *recycling_act,
01149                                                                                        void **act_holder)
01150 {
01151   // Reset the <*act_holder> in the confines and protection of the
01152   // lock.
01153   if (act_holder)
01154     *act_holder = 0;
01155 
01156   // The wonders and perils of ACT
01157   CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
01158 
01159   // Decrement the refcount on the <svc_handler>.
01160   int refcount = entry->ext_id_.decrement ();
01161 
01162   // If the svc_handler state is closed and the refcount == 0, call
01163   // close() on svc_handler.
01164   if (entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED &&
01165       refcount == 0)
01166     {
01167       entry->int_id_->recycler (0, 0);
01168       entry->int_id_->close ();
01169       this->purge_i (entry);
01170     }
01171 
01172   return 0;
01173 }
01174 
01175 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Creation_Strategy<SVC_HANDLER> *
01176 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::creation_strategy (void) const
01177 {
01178   return this->creation_strategy_;
01179 }
01180 
01181 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Recycling_Strategy<SVC_HANDLER> *
01182 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycling_strategy (void) const
01183 {
01184   return this->recycling_strategy_;
01185 }
01186 
01187 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Concurrency_Strategy<SVC_HANDLER> *
01188 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::concurrency_strategy (void) const
01189 {
01190   return this->concurrency_strategy_;
01191 }
01192 
01193 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
01194 ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::find (
01195   REFCOUNTED_HASH_RECYCLABLE_ADDRESS &search_addr,
01196   CONNECTION_MAP_ENTRY *&entry)
01197 {
01198   typedef ACE_Hash_Map_Bucket_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDRESS,
01199                                        SVC_HANDLER *,
01200                                        ACE_Hash<REFCOUNTED_HASH_RECYCLABLE_ADDRESS>,
01201                                        ACE_Equal_To<REFCOUNTED_HASH_RECYCLABLE_ADDRESS>,
01202                                        ACE_Null_Mutex>
01203     CONNECTION_MAP_BUCKET_ITERATOR;
01204 
01205   CONNECTION_MAP_BUCKET_ITERATOR iterator (this->connection_map_,
01206                                            search_addr);
01207 
01208   CONNECTION_MAP_BUCKET_ITERATOR end (this->connection_map_,
01209                                       search_addr,
01210                                       1);
01211 
01212   for (;
01213        iterator != end;
01214        ++iterator)
01215     {
01216       REFCOUNTED_HASH_RECYCLABLE_ADDRESS &addr = (*iterator).ext_id_;
01217 
01218       if (addr.recycle_state () != ACE_RECYCLABLE_IDLE_AND_PURGABLE &&
01219           addr.recycle_state () != ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE)
01220         continue;
01221 
01222       if (addr.subject () != search_addr.subject ())
01223         continue;
01224 
01225       entry = &(*iterator);
01226       return 0;
01227     }
01228 
01229   return -1;
01230 }
01231 
01232 template <class SVC_HANDLER> void
01233 ACE_DLL_Strategy<SVC_HANDLER>::dump (void) const
01234 {
01235 #if defined (ACE_HAS_DUMP)
01236   ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::dump");
01237 #endif /* ACE_HAS_DUMP */
01238 }
01239 
01240 template <class SVC_HANDLER>
01241 ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy (void)
01242 {
01243   ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy");
01244 }
01245 
01246 
01247 template <class SVC_HANDLER> void
01248 ACE_Concurrency_Strategy<SVC_HANDLER>::dump (void) const
01249 {
01250 #if defined (ACE_HAS_DUMP)
01251   ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::dump");
01252 #endif /* ACE_HAS_DUMP */
01253 }
01254 
01255 template <class SVC_HANDLER>
01256 ACE_Reactive_Strategy<SVC_HANDLER>::~ACE_Reactive_Strategy (void)
01257 {
01258   ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::~ACE_Reactive_Strategy");
01259 }
01260 
01261 
01262 template <class SVC_HANDLER> void
01263 ACE_Reactive_Strategy<SVC_HANDLER>::dump (void) const
01264 {
01265 #if defined (ACE_HAS_DUMP)
01266   ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::dump");
01267 #endif /* ACE_HAS_DUMP */
01268 }
01269 
01270 template <class SVC_HANDLER>
01271 ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy (void)
01272 {
01273   ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy");
01274 }
01275 
01276 template <class SVC_HANDLER> void
01277 ACE_Thread_Strategy<SVC_HANDLER>::dump (void) const
01278 {
01279 #if defined (ACE_HAS_DUMP)
01280   ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::dump");
01281 #endif /* ACE_HAS_DUMP */
01282 }
01283 
01284 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
01285 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy (void)
01286 {
01287   ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy");
01288 
01289   // Close the underlying acceptor.
01290   this->peer_acceptor_.close ();
01291 }
01292 
01293 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
01294 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
01295 {
01296   ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
01297   return this->peer_acceptor_.get_handle ();
01298 }
01299 
01300 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
01301 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
01302 {
01303   ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
01304   return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
01305 }
01306 
01307 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
01308 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
01309 {
01310 #if defined (ACE_HAS_DUMP)
01311   ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
01312 #endif /* ACE_HAS_DUMP */
01313 }
01314 
01315 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
01316 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connect_Strategy (void)
01317 {
01318   ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connect_Strategy");
01319 }
01320 
01321 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_PEER_CONNECTOR &
01322 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connector (void) const
01323 {
01324   ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connector");
01325   return (ACE_PEER_CONNECTOR &) this->connector_;
01326 }
01327 
01328 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void
01329 ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump (void) const
01330 {
01331 #if defined (ACE_HAS_DUMP)
01332   ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump");
01333 #endif /* ACE_HAS_DUMP */
01334 }
01335 
01336 template <class SVC_HANDLER>
01337 ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy (void)
01338 {
01339   ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy");
01340 }
01341 
01342 template <class SVC_HANDLER> void
01343 ACE_Process_Strategy<SVC_HANDLER>::dump (void) const
01344 {
01345 #if defined (ACE_HAS_DUMP)
01346   ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::dump");
01347 #endif /* ACE_HAS_DUMP */
01348 }
01349 
01350 template <class SVC_HANDLER>
01351 ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy (void)
01352 {
01353   ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy");
01354 }
01355 
01356 template <class SVC_HANDLER> int
01357 ACE_Scheduling_Strategy<SVC_HANDLER>::suspend (void)
01358 {
01359   ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::suspend");
01360   return -1;
01361 }
01362 
01363 template <class SVC_HANDLER> int
01364 ACE_Scheduling_Strategy<SVC_HANDLER>::resume (void)
01365 {
01366   ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::resume");
01367   return -1;
01368 }
01369 
01370 template <class SVC_HANDLER> void
01371 ACE_Scheduling_Strategy<SVC_HANDLER>::dump (void) const
01372 {
01373 #if defined (ACE_HAS_DUMP)
01374   ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::dump");
01375 
01376   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01377   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01378 #endif /* ACE_HAS_DUMP */
01379 }
01380 
01381 template <class SVC_HANDLER> int
01382 ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend (void)
01383 {
01384   ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend");
01385   return this->reactor_->suspend_handlers ();
01386 }
01387 
01388 template <class SVC_HANDLER> int
01389 ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume (void)
01390 {
01391   ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume");
01392   return this->reactor_->resume_handlers ();
01393 }
01394 
01395 template <class SVC_HANDLER> void
01396 ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump (void) const
01397 {
01398 #if defined (ACE_HAS_DUMP)
01399   ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump");
01400 
01401   ACE_Scheduling_Strategy<SVC_HANDLER>::dump ();
01402 #endif /* ACE_HAS_DUMP */
01403 }
01404 
01405 template <class SVC_HANDLER> int
01406 ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend (void)
01407 {
01408   ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend");
01409   return this->thr_mgr_->suspend_all ();
01410 }
01411 
01412 template <class SVC_HANDLER> int
01413 ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume (void)
01414 {
01415   ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume");
01416   return this->thr_mgr_->resume_all ();
01417 }
01418 
01419 template <class SVC_HANDLER> void
01420 ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump (void) const
01421 {
01422 #if defined (ACE_HAS_DUMP)
01423   ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump");
01424 
01425   ACE_Scheduling_Strategy<SVC_HANDLER>::dump ();
01426 #endif /* ACE_HAS_DUMP */
01427 }
01428 
01429 template <class T>
01430 ACE_Refcounted_Hash_Recyclable<T>::~ACE_Refcounted_Hash_Recyclable (void)
01431 {
01432 }
01433 
01434 template <class SVC_HANDLER> void
01435 ACE_Singleton_Strategy<SVC_HANDLER>::dump (void) const
01436 {
01437 #if defined (ACE_HAS_DUMP)
01438   ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::dump");
01439 #endif /* ACE_HAS_DUMP */
01440 }
01441 
01442 template <class SVC_HANDLER>
01443 ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy (void)
01444 {
01445   ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy");
01446 }
01447 
01448 // Default behavior is to make a new SVC_HANDLER, passing in the
01449 // Thread_Manager (if any).
01450 
01451 template <class SVC_HANDLER> int
01452 ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh)
01453 {
01454   ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler");
01455 
01456   if (sh == 0)
01457     ACE_NEW_RETURN (sh, SVC_HANDLER (this->thr_mgr_), -1);
01458   sh->reactor (this->reactor_);
01459   return 0;
01460 }
01461 
01462 template <class SVC_HANDLER> void
01463 ACE_Creation_Strategy<SVC_HANDLER>::dump (void) const
01464 {
01465 #if defined (ACE_HAS_DUMP)
01466   ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::dump");
01467 #endif /* ACE_HAS_DUMP */
01468 }
01469 
01470 template <class SVC_HANDLER> int
01471 ACE_NOOP_Creation_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&)
01472 {
01473   ACE_TRACE ("ACE_NOOP_Creation_Strategy<SVC_HANDLER>::make_svc_handler");
01474   return 0;
01475 }
01476 
01477 template <class SVC_HANDLER> int
01478 ACE_NOOP_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *,
01479                                                                   void *)
01480 {
01481   ACE_TRACE ("ACE_NOOP_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler");
01482   return 0;
01483 }
01484 
01485 
01486 ACE_ALLOC_HOOK_DEFINE(ACE_Creation_Strategy)
01487 ACE_ALLOC_HOOK_DEFINE(ACE_Singleton_Strategy)
01488 ACE_ALLOC_HOOK_DEFINE(ACE_DLL_Strategy)
01489 ACE_ALLOC_HOOK_DEFINE(ACE_Concurrency_Strategy)
01490 ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy)
01491 ACE_ALLOC_HOOK_DEFINE(ACE_Connect_Strategy)
01492 ACE_ALLOC_HOOK_DEFINE(ACE_Process_Strategy)
01493 ACE_ALLOC_HOOK_DEFINE(ACE_Accept_Strategy)
01494 ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy)
01495 
01496 ACE_END_VERSIONED_NAMESPACE_DECL
01497 
01498 #endif /* ACE_STRATEGIES_T_CPP */

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