Strategies_T.cpp

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

Generated on Thu Nov 9 09:42:05 2006 for ACE by doxygen 1.3.6