diff options
Diffstat (limited to 'ACE/ace/Strategies_T.cpp')
-rw-r--r-- | ACE/ace/Strategies_T.cpp | 1499 |
1 files changed, 1499 insertions, 0 deletions
diff --git a/ACE/ace/Strategies_T.cpp b/ACE/ace/Strategies_T.cpp new file mode 100644 index 00000000000..0eadf2ce616 --- /dev/null +++ b/ACE/ace/Strategies_T.cpp @@ -0,0 +1,1499 @@ +// $Id$ + +#ifndef ACE_STRATEGIES_T_CPP +#define ACE_STRATEGIES_T_CPP + +#include "ace/Strategies_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Service_Repository.h" +#include "ace/Service_Types.h" +#include "ace/Thread_Manager.h" +#include "ace/WFMO_Reactor.h" +#include "ace/ACE.h" +#include "ace/OS_NS_dlfcn.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_Errno.h" +#if defined (ACE_OPENVMS) +# include "ace/Lib_Find.h" +#endif + +#if !defined (__ACE_INLINE__) +#include "ace/Strategies_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template<class SVC_HANDLER> +ACE_Recycling_Strategy<SVC_HANDLER>::~ACE_Recycling_Strategy (void) +{ +} + +template<class SVC_HANDLER> int +ACE_Recycling_Strategy<SVC_HANDLER>::assign_recycler (SVC_HANDLER *svc_handler, + ACE_Connection_Recycling_Strategy *recycler, + const void *recycling_act) +{ + svc_handler->recycler (recycler, recycling_act); + return 0; +} + +template<class SVC_HANDLER> int +ACE_Recycling_Strategy<SVC_HANDLER>::prepare_for_recycling (SVC_HANDLER *svc_handler) +{ + return svc_handler->recycle (); +} + +template <class SVC_HANDLER> +ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy (void) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy"); + if (this->delete_svc_handler_ != 0) + delete this->svc_handler_; +} + +// Create a Singleton SVC_HANDLER by always returning the same +// SVC_HANDLER. + +template <class SVC_HANDLER> int +ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler"); + sh = this->svc_handler_; + return 0; +} + +template <class SVC_HANDLER> int +ACE_Singleton_Strategy<SVC_HANDLER>::open (SVC_HANDLER *sh, + ACE_Thread_Manager *) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::open"); + + if (this->delete_svc_handler_ + && this->svc_handler_ != 0) + delete this->svc_handler_; + + // If <sh> is NULL then create a new <SVC_HANDLER>. + if (sh == 0) + { + ACE_NEW_RETURN (this->svc_handler_, + SVC_HANDLER, + -1); + this->delete_svc_handler_ = 1; + } + else + { + this->svc_handler_ = sh; + this->delete_svc_handler_ = 0; + } + + return 0; +} + +template <class SVC_HANDLER> int +ACE_DLL_Strategy<SVC_HANDLER>::open (const ACE_TCHAR dll_name[], + const ACE_TCHAR factory_function[], + const ACE_TCHAR svc_name[], + ACE_Service_Repository *svc_rep, + ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::open"); + this->inherited::open (thr_mgr); + ACE_OS::strcpy (this->dll_name_, dll_name); + ACE_OS::strcpy (this->factory_function_, factory_function); + ACE_OS::strcpy (this->svc_name_, svc_name); + this->svc_rep_ = svc_rep; + return 0; +} + +// Create a SVC_HANDLER by dynamically linking it from a DLL. + +template <class SVC_HANDLER> int +ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler"); + + // Open the shared library. + ACE_SHLIB_HANDLE handle = ACE_OS::dlopen (this->dll_name_); + + // Extract the factory function. +#if defined (ACE_OPENVMS) + SVC_HANDLER *(*factory)(void) = + (SVC_HANDLER *(*)(void)) ACE::ldsymbol (handle, + this->factory_function_); +#else + SVC_HANDLER *(*factory)(void) = + (SVC_HANDLER *(*)(void)) ACE_OS::dlsym (handle, + this->factory_function_); +#endif + + // Call the factory function to obtain the new SVC_Handler (should + // use RTTI here when it becomes available...) + SVC_HANDLER *svc_handler = 0; + + ACE_ALLOCATOR_RETURN (svc_handler, (*factory)(), -1); + + if (svc_handler != 0) + { + // Create an ACE_Service_Type containing the SVC_Handler and + // insert into this->svc_rep_; + + ACE_Service_Type_Impl *stp = 0; + ACE_NEW_RETURN (stp, + ACE_Service_Object_Type (svc_handler, + this->svc_name_), + -1); + + ACE_Service_Type *srp = 0; + + ACE_NEW_RETURN (srp, + ACE_Service_Type (this->svc_name_, + stp, + handle, + 1), + -1); + if (srp == 0) + { + delete stp; + errno = ENOMEM; + return -1; + } + + if (this->svc_rep_->insert (srp) == -1) + return -1; + // @@ Somehow, we need to deal with this->thr_mgr_... + } + + sh = svc_handler; + return 0; +} + +// Default behavior is to activate the SVC_HANDLER by calling it's +// open() method, which allows the SVC_HANDLER to determine its own +// concurrency strategy. + +template <class SVC_HANDLER> int +ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler"); + + int result = 0; + + // See if we should enable non-blocking I/O on the <svc_handler>'s + // peer. + if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0) + { + if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1) + result = -1; + } + // Otherwise, make sure it's disabled by default. + else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1) + result = -1; + + if (result == 0 && svc_handler->open (arg) == -1) + result = -1; + + if (result == -1) + svc_handler->close (0); + + return result; +} + +template <class SVC_HANDLER> int +ACE_Reactive_Strategy<SVC_HANDLER>::open (ACE_Reactor *reactor, + ACE_Reactor_Mask mask, + int flags) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::open"); + this->reactor_ = reactor; + this->mask_ = mask; + this->flags_ = flags; + + // Must have a <Reactor> + if (this->reactor_ == 0) + return -1; + else + return 0; +} + +template <class SVC_HANDLER> int +ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler"); + + int result = 0; + + if (this->reactor_ == 0) + result = -1; + + // Register with the Reactor with the appropriate <mask>. + else if (this->reactor_->register_handler (svc_handler, this->mask_) == -1) + result = -1; + + // If the implementation of the reactor uses event associations + else if (this->reactor_->uses_event_associations ()) + { + // If we don't have non-block on, it won't work with + // WFMO_Reactor + // This maybe too harsh + // if (!ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK)) + // goto failure; + if (svc_handler->open (arg) != -1) + return 0; + else + result = -1; + } + else + // Call up to our parent to do the SVC_HANDLER initialization. + return this->inherited::activate_svc_handler (svc_handler, arg); + + if (result == -1) + svc_handler->close (0); + + return result; +} + +template <class SVC_HANDLER> int +ACE_Thread_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr, + long thr_flags, + int n_threads, + int flags) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::open"); + this->thr_mgr_ = thr_mgr; + this->n_threads_ = n_threads; + this->thr_flags_ = thr_flags; + this->flags_ = flags; + + // Must have a thread manager! + if (this->thr_mgr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("error: must have a non-NULL thread manager\n")), + -1); + else + return 0; +} + +template <class SVC_HANDLER> int +ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler"); + // Call up to our parent to do the SVC_HANDLER initialization. + if (this->inherited::activate_svc_handler (svc_handler, + arg) == -1) + return -1; + else + // Turn the <svc_handler> into an active object (if it isn't + // already one as a result of the first activation...) + return svc_handler->activate (this->thr_flags_, + this->n_threads_); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int reuse_addr) +{ + this->reuse_addr_ = reuse_addr; + this->peer_acceptor_addr_ = local_addr; + if (this->peer_acceptor_.open (local_addr, + reuse_addr) == -1) + return -1; + + // Set the peer acceptor's handle into non-blocking mode. This is a + // safe-guard against the race condition that can otherwise occur + // between the time when <select> indicates that a passive-mode + // socket handle is "ready" and when we call <accept>. During this + // interval, the client can shutdown the connection, in which case, + // the <accept> call can hang! + this->peer_acceptor_.enable (ACE_NONBLOCK); + return 0; +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + int reuse_addr, + ACE_Reactor *reactor) + : reactor_ (reactor) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy"); + + if (this->open (local_addr, reuse_addr) == -1) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("open"))); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler + (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler"); + + // Try to find out if the implementation of the reactor that we are + // using requires us to reset the event association for the newly + // created handle. This is because the newly created handle will + // inherit the properties of the listen handle, including its event + // associations. + int reset_new_handle = this->reactor_->uses_event_associations (); + + if (this->peer_acceptor_.accept (svc_handler->peer (), // stream + 0, // remote address + 0, // timeout + 1, // restart + reset_new_handle // reset new handler + ) == -1) + { + // Ensure that errno is preserved in case the svc_handler + // close() method resets it + ACE_Errno_Guard error(errno); + + // Close down handler to avoid memory leaks. + svc_handler->close (0); + + return -1; + } + else + return 0; +} + +template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int +ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler"); + + return this->connector_.connect (sh->peer (), + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int +ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler +(SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler"); + + int const result = + this->connector_.connect (sh->peer (), + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); + sh_copy = sh; + return result; +} + +template <class SVC_HANDLER> int +ACE_Process_Strategy<SVC_HANDLER>::open (size_t n_processes, + ACE_Event_Handler *acceptor, + ACE_Reactor *reactor, + int avoid_zombies) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::open"); + this->n_processes_ = n_processes; + this->acceptor_ = acceptor; + this->reactor_ = reactor; + this->flags_ = avoid_zombies; + + return 0; +} + +template <class SVC_HANDLER> int +ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler"); + + // If <flags_> is non-0 then we won't create zombies. + switch (ACE::fork (ACE_LIB_TEXT ("child"), this->flags_)) + { + case -1: + { + ACE_Errno_Guard error (errno); + svc_handler->destroy (); + } + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("fork")), + -1); + /* NOTREACHED */ + case 0: // In child process. + + // Close down the SOCK_Acceptor's handle since we don't need to + // keep it open. + if (this->acceptor_ != 0) + // Ignore the return value here... + (void) this->reactor_->remove_handler (this->acceptor_, + ACE_Event_Handler::ACCEPT_MASK); + + // Call up to our ancestor in the inheritance to do the + // SVC_HANDLER initialization. + return this->inherited::activate_svc_handler (svc_handler, arg); + /* NOTREACHED */ + default: // In parent process. + // We need to close down the <SVC_HANDLER> here because it's + // running in the child. + svc_handler->destroy (); + return 0; + } +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::ACE_Cached_Connect_Strategy +(creation_strategy_type *cre_s, + ACE_Concurrency_Strategy<SVC_HANDLER> *con_s, + ACE_Recycling_Strategy<SVC_HANDLER> *rec_s, + MUTEX *lock, + int delete_lock) + : lock_ (lock), + delete_lock_ (delete_lock), + reverse_lock_ (0), + creation_strategy_ (0), + delete_creation_strategy_ (0), + concurrency_strategy_ (0), + delete_concurrency_strategy_ (0), + recycling_strategy_ (0), + delete_recycling_strategy_ (0) +{ + // Create a new lock if necessary. + if (this->lock_ == 0) + { + ACE_NEW (this->lock_, + MUTEX); + + this->delete_lock_ = 1; + } + + ACE_NEW (this->reverse_lock_, + REVERSE_MUTEX (*this->lock_)); + + if (this->open (cre_s, + con_s, + rec_s) == -1) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Cached_Connect_Strategy::ACE_Cached_Connect_Strategy"))); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::~ACE_Cached_Connect_Strategy (void) +{ + if (this->delete_lock_) + delete this->lock_; + + delete this->reverse_lock_; + + if (this->delete_creation_strategy_) + delete this->creation_strategy_; + this->delete_creation_strategy_ = 0; + this->creation_strategy_ = 0; + + if (this->delete_concurrency_strategy_) + delete this->concurrency_strategy_; + this->delete_concurrency_strategy_ = 0; + this->concurrency_strategy_ = 0; + + if (this->delete_recycling_strategy_) + delete this->recycling_strategy_; + this->delete_recycling_strategy_ = 0; + this->recycling_strategy_ = 0; + + // Close down all cached service handlers. + CONNECTION_MAP_ENTRY *entry = 0; + for (CONNECTION_MAP_ITERATOR iterator (connection_map_); + iterator.next (entry); + iterator.advance ()) + { + entry->int_id_->recycler (0, 0); + entry->int_id_->close (); + } +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::open +(creation_strategy_type *cre_s, + ACE_Concurrency_Strategy<SVC_HANDLER> *con_s, + ACE_Recycling_Strategy<SVC_HANDLER> *rec_s) +{ + // Initialize the creation strategy. + + // First we decide if we need to clean up. + if (this->creation_strategy_ != 0 && + this->delete_creation_strategy_ != 0 && + cre_s != 0) + { + delete this->creation_strategy_; + this->creation_strategy_ = 0; + this->delete_creation_strategy_ = 0; + } + + if (cre_s != 0) + this->creation_strategy_ = cre_s; + else if (this->creation_strategy_ == 0) + { + ACE_NEW_RETURN (this->creation_strategy_, + CREATION_STRATEGY, -1); + this->delete_creation_strategy_ = 1; + } + + // Initialize the concurrency strategy. + + if (this->concurrency_strategy_ != 0 && + this->delete_concurrency_strategy_ != 0 && + con_s != 0) + { + delete this->concurrency_strategy_; + this->concurrency_strategy_ = 0; + this->delete_concurrency_strategy_ = 0; + } + + if (con_s != 0) + this->concurrency_strategy_ = con_s; + else if (this->concurrency_strategy_ == 0) + { + ACE_NEW_RETURN (this->concurrency_strategy_, + CONCURRENCY_STRATEGY, -1); + this->delete_concurrency_strategy_ = 1; + } + + // Initialize the recycling strategy. + + if (this->recycling_strategy_ != 0 && + this->delete_recycling_strategy_ != 0 && + rec_s != 0) + { + delete this->recycling_strategy_; + this->recycling_strategy_ = 0; + this->delete_recycling_strategy_ = 0; + } + + if (rec_s != 0) + this->recycling_strategy_ = rec_s; + else if (this->recycling_strategy_ == 0) + { + ACE_NEW_RETURN (this->recycling_strategy_, + RECYCLING_STRATEGY, -1); + this->delete_recycling_strategy_ = 1; + } + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::make_svc_handler + (SVC_HANDLER *&sh) +{ + return this->creation_strategy_->make_svc_handler (sh); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::activate_svc_handler + (SVC_HANDLER *svc_handler) +{ + return this->concurrency_strategy_->activate_svc_handler (svc_handler); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::assign_recycler + (SVC_HANDLER *svc_handler, + ACE_Connection_Recycling_Strategy *recycler, + const void *recycling_act) +{ + return this->recycling_strategy_->assign_recycler (svc_handler, + recycler, + recycling_act); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::prepare_for_recycling + (SVC_HANDLER *svc_handler) +{ + return this->recycling_strategy_->prepare_for_recycling (svc_handler); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::check_hint_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + CONNECTION_MAP_ENTRY *&entry, + int &found) +{ + ACE_UNUSED_ARG (remote_addr); + ACE_UNUSED_ARG (timeout); + ACE_UNUSED_ARG (local_addr); + ACE_UNUSED_ARG (reuse_addr); + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (perms); + + found = 0; + + // Get the recycling act for the svc_handler + CONNECTION_MAP_ENTRY *possible_entry = (CONNECTION_MAP_ENTRY *) sh->recycling_act (); + + // Check to see if the hint svc_handler has been closed down + if (possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED) + { + // If close, decrement refcount + if (possible_entry->ext_id_.decrement () == 0) + { + // If refcount goes to zero, close down the svc_handler + possible_entry->int_id_->recycler (0, 0); + possible_entry->int_id_->close (); + this->purge_i (possible_entry); + } + + // Hint not successful + found = 0; + + // Reset hint + sh = 0; + } + + // If hint is not closed, see if it is connected to the correct + // address and is recyclable + else if ((possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE || + possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE) && + possible_entry->ext_id_.subject () == remote_addr) + { + // Hint successful + found = 1; + + // Tell the <svc_handler> that it should prepare itself for + // being recycled. + this->prepare_for_recycling (sh); + } + else + { + // This hint will not be used. + possible_entry->ext_id_.decrement (); + + // Hint not successful + found = 0; + + // If <sh> is not connected to the correct address or is busy, + // we will not use it. + sh = 0; + } + + if (found) + entry = possible_entry; + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::find_or_create_svc_handler_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + CONNECTION_MAP_ENTRY *&entry, + int &found) +{ + // Explicit type conversion + REFCOUNTED_HASH_RECYCLABLE_ADDRESS search_addr (remote_addr); + + // Try to find the address in the cache. Only if we don't find it + // do we create a new <SVC_HANDLER> and connect it with the server. + if (this->find (search_addr, entry) == -1) + { + // Set the flag + found = 0; + + // We need to use a temporary variable here since we are not + // allowed to change <sh> because other threads may use this + // when we let go of the lock during the OS level connect. + // + // Note that making a new svc_handler, connecting remotely, + // binding to the map, and assigning of the hint and recycler + // should be atomic to the outside world. + SVC_HANDLER *potential_handler = 0; + + // Create a new svc_handler + if (this->make_svc_handler (potential_handler) == -1) + return -1; + + // Actively establish the connection. This is a timed blocking + // connect. + if (this->new_connection (potential_handler, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms) == -1) + { + // If connect() failed because of timeouts, we have to + // reject the connection entirely. This is necessary since + // currently there is no way for the non-blocking connects + // to complete and for the <Connector> to notify the cache + // of the completion of connect(). + if (errno == EWOULDBLOCK) + errno = ENOTSUP; + + // Close the svc handler. + potential_handler->close (0); + + return -1; + } + else + { + // Insert the new SVC_HANDLER instance into the cache. + if (this->connection_map_.bind (search_addr, + potential_handler, + entry) == -1) + { + // Close the svc handler. + potential_handler->close (0); + + return -1; + } + + // Everything succeeded as planned. Assign <sh> to <potential_handler>. + sh = potential_handler; + + // Set the recycler and the recycling act + this->assign_recycler (sh, this, entry); + } + } + else + // We found a cached svc_handler. + { + // Set the flag + found = 1; + + // Get the cached <svc_handler> + sh = entry->int_id_; + + // Tell the <svc_handler> that it should prepare itself for + // being recycled. + this->prepare_for_recycling (sh); + } + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::new_connection +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + // Yow, Reverse Guard! Let go of the lock for the duration of the + // actual connect. This will allow other threads to hack on the + // connection cache while this thread creates the new connection. + ACE_GUARD_RETURN (REVERSE_MUTEX, ace_mon, *this->reverse_lock_, -1); + + return this->CONNECT_STRATEGY::connect_svc_handler (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + int found = 0; + + // This artificial scope is required since we need to let go of the + // lock *before* registering the newly created handler with the + // Reactor. + { + // Synchronization is required here as the setting of the + // recyclable state must be done atomically with the finding and + // binding of the service handler in the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + int result = this->connect_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + found); + if (result != 0) + return result; + + } + + // If it is a new connection, activate it. + // + // Note: This activation is outside the scope of the lock of the + // cached connector. This is necessary to avoid subtle deadlock + // conditions with this lock and the Reactor lock. + + if (!found) + { + if (this->activate_svc_handler (sh) == -1) + { + // If an error occurs while activating the handler, the + // <activate_svc_handler> method will close the handler. + // This in turn will remove this entry from the internal + // table. + + // Synchronization is required here as the setting of the + // handler to zero must be done atomically with the users of + // the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + // Reset handler. + sh = 0; + + return -1; + } + } + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler +(SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + int found = 0; + + // This artificial scope is required since we need to let go of the + // lock *before* registering the newly created handler with the + // Reactor. + { + // Synchronization is required here as the setting of the + // recyclable state must be done atomically with the finding and + // binding of the service handler in the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + int result = this->connect_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + found); + sh_copy = sh; + + if (result != 0) + return result; + + } + + // If it is a new connection, activate it. + // + // Note: This activation is outside the scope of the lock of the + // cached connector. This is necessary to avoid subtle deadlock + // conditions with this lock and the Reactor lock. + + if (!found) + { + if (this->activate_svc_handler (sh_copy) == -1) + { + // If an error occurs while activating the handler, the + // <activate_svc_handler> method will close the handler. + // This in turn will remove this entry from the internal + // table. + + // Synchronization is required here as the setting of the + // handler to zero must be done atomically with the users of + // the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + // Reset handler. + sh = 0; + sh_copy = 0; + + return -1; + } + } + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + int& found) +{ + CONNECTION_MAP_ENTRY *entry = 0; + + // Check if the user passed a hint svc_handler + if (sh != 0) + { + int result = this->check_hint_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + entry, + found); + if (result != 0) + return result; + } + + // If not found + if (!found) + { + int result = this->find_or_create_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + entry, + found); + if (result != 0) + return result; + } + + // For all successful cases: mark the <svc_handler> in the cache + // as being <in_use>. Therefore recyclable is BUSY. + entry->ext_id_.recycle_state (ACE_RECYCLABLE_BUSY); + + // And increment the refcount + entry->ext_id_.increment (); + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache (const void *recycling_act) +{ + // Synchronization is required here as the setting of the recyclable + // state must be done atomically with respect to other threads that + // are querying the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + return this->cache_i (recycling_act); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache_i (const void *recycling_act) +{ + // The wonders and perils of ACT + CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act; + + // Mark the <svc_handler> in the cache as not being <in_use>. + // Therefore recyclable is IDLE. + entry->ext_id_.recycle_state (ACE_RECYCLABLE_IDLE_AND_PURGABLE); + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state (const void *recycling_act, + ACE_Recyclable_State new_state) +{ + // Synchronization is required here as the setting of the recyclable + // state must be done atomically with respect to other threads that + // are querying the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + return this->recycle_state_i (recycling_act, + new_state); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state_i (const void *recycling_act, + ACE_Recyclable_State new_state) +{ + // The wonders and perils of ACT + CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act; + + // Mark the <svc_handler> in the cache as not being <in_use>. + // Therefore recyclable is IDLE. + entry->ext_id_.recycle_state (new_state); + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Recyclable_State +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state (const void *recycling_act) const +{ + // Const cast. + SELF *fake_this = const_cast<SELF *> (this); + + // Synchronization is required here. + ACE_GUARD_RETURN (MUTEX, ace_mon, *fake_this->lock_, ACE_RECYCLABLE_UNKNOWN); + + return this->recycle_state_i (recycling_act); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Recyclable_State +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycle_state_i (const void *recycling_act) const +{ + // The wonders and perils of ACT + CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act; + + // Mark the <svc_handler> in the cache as not being <in_use>. + // Therefore recyclable is IDLE. + return entry->ext_id_.recycle_state (); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge (const void *recycling_act) +{ + // Excluded other threads from changing cache while we take this + // entry out. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + return this->purge_i (recycling_act); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge_i (const void *recycling_act) +{ + // The wonders and perils of ACT + CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act; + + return this->connection_map_.unbind (entry); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::mark_as_closed (const void *recycling_act) +{ + // Excluded other threads from changing cache while we take this + // entry out. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + return this->mark_as_closed_i (recycling_act); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::mark_as_closed_i (const void *recycling_act) +{ + // The wonders and perils of ACT + CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act; + + // Mark the <svc_handler> in the cache as CLOSED. + entry->ext_id_.recycle_state (ACE_RECYCLABLE_CLOSED); + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cleanup_hint (const void *recycling_act, + void **act_holder) +{ + // Excluded other threads from changing cache while we take this + // entry out. + ACE_GUARD_RETURN (MUTEX, ace_mon, *this->lock_, -1); + + return this->cleanup_hint_i (recycling_act, + act_holder); +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cleanup_hint_i (const void *recycling_act, + void **act_holder) +{ + // Reset the <*act_holder> in the confines and protection of the + // lock. + if (act_holder) + *act_holder = 0; + + // The wonders and perils of ACT + CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act; + + // Decrement the refcount on the <svc_handler>. + int refcount = entry->ext_id_.decrement (); + + // If the svc_handler state is closed and the refcount == 0, call + // close() on svc_handler. + if (entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED && + refcount == 0) + { + entry->int_id_->recycler (0, 0); + entry->int_id_->close (); + this->purge_i (entry); + } + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Creation_Strategy<SVC_HANDLER> * +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::creation_strategy (void) const +{ + return this->creation_strategy_; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Recycling_Strategy<SVC_HANDLER> * +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::recycling_strategy (void) const +{ + return this->recycling_strategy_; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> ACE_Concurrency_Strategy<SVC_HANDLER> * +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::concurrency_strategy (void) const +{ + return this->concurrency_strategy_; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::find ( + REFCOUNTED_HASH_RECYCLABLE_ADDRESS &search_addr, + CONNECTION_MAP_ENTRY *&entry) +{ + typedef ACE_Hash_Map_Bucket_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDRESS, + SVC_HANDLER *, + ACE_Hash<REFCOUNTED_HASH_RECYCLABLE_ADDRESS>, + ACE_Equal_To<REFCOUNTED_HASH_RECYCLABLE_ADDRESS>, + ACE_Null_Mutex> + CONNECTION_MAP_BUCKET_ITERATOR; + + CONNECTION_MAP_BUCKET_ITERATOR iterator (this->connection_map_, + search_addr); + + CONNECTION_MAP_BUCKET_ITERATOR end (this->connection_map_, + search_addr, + 1); + + for (; + iterator != end; + ++iterator) + { + REFCOUNTED_HASH_RECYCLABLE_ADDRESS &addr = (*iterator).ext_id_; + + if (addr.recycle_state () != ACE_RECYCLABLE_IDLE_AND_PURGABLE && + addr.recycle_state () != ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE) + continue; + + if (addr.subject () != search_addr.subject ()) + continue; + + entry = &(*iterator); + return 0; + } + + return -1; +} + +template <class SVC_HANDLER> void +ACE_DLL_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> +ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy (void) +{ + ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy"); +} + + +template <class SVC_HANDLER> void +ACE_Concurrency_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> +ACE_Reactive_Strategy<SVC_HANDLER>::~ACE_Reactive_Strategy (void) +{ + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::~ACE_Reactive_Strategy"); +} + + +template <class SVC_HANDLER> void +ACE_Reactive_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> +ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy (void) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy"); +} + +template <class SVC_HANDLER> void +ACE_Thread_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy (void) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy"); + + // Close the underlying acceptor. + this->peer_acceptor_.close (); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR & +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> +ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connect_Strategy (void) +{ + ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::~ACE_Connect_Strategy"); +} + +template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_PEER_CONNECTOR & +ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connector (void) const +{ + ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connector"); + return (ACE_PEER_CONNECTOR &) this->connector_; +} + +template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void +ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> +ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy (void) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy"); +} + +template <class SVC_HANDLER> void +ACE_Process_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> +ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy"); +} + +template <class SVC_HANDLER> int +ACE_Scheduling_Strategy<SVC_HANDLER>::suspend (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::suspend"); + return -1; +} + +template <class SVC_HANDLER> int +ACE_Scheduling_Strategy<SVC_HANDLER>::resume (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::resume"); + return -1; +} + +template <class SVC_HANDLER> void +ACE_Scheduling_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend (void) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend"); + return this->reactor_->suspend_handlers (); +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume (void) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume"); + return this->reactor_->resume_handlers (); +} + +template <class SVC_HANDLER> void +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump"); + + ACE_Scheduling_Strategy<SVC_HANDLER>::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend (void) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend"); + return this->thr_mgr_->suspend_all (); +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume (void) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume"); + return this->thr_mgr_->resume_all (); +} + +template <class SVC_HANDLER> void +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump"); + + ACE_Scheduling_Strategy<SVC_HANDLER>::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template <class T> +ACE_Refcounted_Hash_Recyclable<T>::~ACE_Refcounted_Hash_Recyclable (void) +{ +} + +template <class SVC_HANDLER> void +ACE_Singleton_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> +ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy (void) +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy"); +} + +// Default behavior is to make a new SVC_HANDLER, passing in the +// Thread_Manager (if any). + +template <class SVC_HANDLER> int +ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler"); + + if (sh == 0) + ACE_NEW_RETURN (sh, SVC_HANDLER (this->thr_mgr_), -1); + sh->reactor (this->reactor_); + return 0; +} + +template <class SVC_HANDLER> void +ACE_Creation_Strategy<SVC_HANDLER>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template <class SVC_HANDLER> int +ACE_NOOP_Creation_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&) +{ + ACE_TRACE ("ACE_NOOP_Creation_Strategy<SVC_HANDLER>::make_svc_handler"); + return 0; +} + +template <class SVC_HANDLER> int +ACE_NOOP_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *, + void *) +{ + ACE_TRACE ("ACE_NOOP_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler"); + return 0; +} + + +ACE_ALLOC_HOOK_DEFINE(ACE_Creation_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Singleton_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_DLL_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Concurrency_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Connect_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Accept_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_STRATEGIES_T_CPP */ |