// $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" #include "ace/Svc_Handler.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 ACE_Recycling_Strategy::~ACE_Recycling_Strategy (void) { } template int ACE_Recycling_Strategy::assign_recycler (SVC_HANDLER *svc_handler, ACE_Connection_Recycling_Strategy *recycler, const void *recycling_act) { svc_handler->recycler (recycler, recycling_act); return 0; } template int ACE_Recycling_Strategy::prepare_for_recycling (SVC_HANDLER *svc_handler) { return svc_handler->recycle (); } template ACE_Singleton_Strategy::~ACE_Singleton_Strategy (void) { ACE_TRACE ("ACE_Singleton_Strategy::~ACE_Singleton_Strategy"); if (this->delete_svc_handler_) delete this->svc_handler_; } // Create a Singleton SVC_HANDLER by always returning the same // SVC_HANDLER. template int ACE_Singleton_Strategy::make_svc_handler (SVC_HANDLER *&sh) { ACE_TRACE ("ACE_Singleton_Strategy::make_svc_handler"); sh = this->svc_handler_; return 0; } template int ACE_Singleton_Strategy::open (SVC_HANDLER *sh, ACE_Thread_Manager *) { ACE_TRACE ("ACE_Singleton_Strategy::open"); if (this->delete_svc_handler_) delete this->svc_handler_; // If is NULL then create a new . if (sh == 0) { ACE_NEW_RETURN (this->svc_handler_, SVC_HANDLER, -1); this->delete_svc_handler_ = true; } else { this->svc_handler_ = sh; this->delete_svc_handler_ = false; } return 0; } template int ACE_DLL_Strategy::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::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 int ACE_DLL_Strategy::make_svc_handler (SVC_HANDLER *&sh) { ACE_TRACE ("ACE_DLL_Strategy::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 int ACE_Concurrency_Strategy::activate_svc_handler (SVC_HANDLER *svc_handler, void *arg) { ACE_TRACE ("ACE_Concurrency_Strategy::activate_svc_handler"); int result = 0; // See if we should enable non-blocking I/O on the '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) // The connection was already made; so this close is a "normal" close // operation. svc_handler->close (NORMAL_CLOSE_OPERATION); return result; } template int ACE_Reactive_Strategy::open (ACE_Reactor *reactor, ACE_Reactor_Mask mask, int flags) { ACE_TRACE ("ACE_Reactive_Strategy::open"); this->reactor_ = reactor; this->mask_ = mask; this->flags_ = flags; // Must have a if (this->reactor_ == 0) return -1; else return 0; } template int ACE_Reactive_Strategy::activate_svc_handler (SVC_HANDLER *svc_handler, void *arg) { ACE_TRACE ("ACE_Reactive_Strategy::activate_svc_handler"); int result = 0; if (this->reactor_ == 0) result = -1; // Register with the Reactor with the appropriate . 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) // The connection was already made; so this close is a "normal" close // operation. svc_handler->close (NORMAL_CLOSE_OPERATION); return result; } template int ACE_Thread_Strategy::open (ACE_Thread_Manager *thr_mgr, long thr_flags, int n_threads, int flags) { ACE_TRACE ("ACE_Thread_Strategy::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) ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("error: must have a non-NULL thread manager\n")), -1); else return 0; } template int ACE_Thread_Strategy::activate_svc_handler (SVC_HANDLER *svc_handler, void *arg) { ACE_TRACE ("ACE_Thread_Strategy::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 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 int ACE_Accept_Strategy::open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, bool 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