diff options
27 files changed, 815 insertions, 656 deletions
diff --git a/ChangeLog-98b b/ChangeLog-98b index 19febd39c4e..f70682e31c1 100644 --- a/ChangeLog-98b +++ b/ChangeLog-98b @@ -1,3 +1,24 @@ +Mon Sep 21 01:27:19 1998 Irfan Pyarali <irfan@cs.wustl.edu> + + * tests/Conn_Test.cpp: Fixed template instantiations. + + * ace/Strategies_T.cpp (ACE_Cached_Connect_Strategy): New methods + find_or_create_svc_handler_i and check_hint_i to simplify + connect_svc_handler. Also added _i methods to implement + non-locking versions. + + * ace/Strategies.h (ACE_Connection_Recycling_Strategy): + New methods: mark_as_close and cleanup_hint. + + * ace/Strategies: Added three new classes: ACE_Recyclable, + ACE_Hashable, and ACE_Refcountable. Also added + ACE_Refcounted_Hash_Recyclable. Deprecated ACE_Recyclable<T> and + ACE_Hash_Recyclable<T> + + * ace/Svc_Handler.h (cleanup_hint): Added new method. This can be + used by users when they are through with using the svc_handler + as a hint. + Mon Sep 21 00:40:00 CDT 1998 Chris Gill <cdgill@cs.wustl.edu> * examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.{h,cpp} diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c index 07243866396..bddacbcb170 100644 --- a/TAO/ChangeLog-98c +++ b/TAO/ChangeLog-98c @@ -1,3 +1,40 @@ +Mon Sep 21 01:38:46 1998 Irfan Pyarali <irfan@cs.wustl.edu> + + * performance-tests/Cubit/TAO/DII_Cubit/client.cpp (init_naming_service): + * performance-tests/Cubit/TAO/IDL_Cubit/Cubit_Client.cpp + (init_naming_service): Fixed initialization of Naming_Server. + + * orbsvcs/orbsvcs/IOR_Multicast.h (TAO_IOR_Multicast): Changed + char * to const char *. + + * orbsvcs/orbsvcs/Naming/Naming_Utils.h (TAO_Naming_Server): + Complete revamp of Naming_Server and Naming_Client. New + implementation is better with respect to functionality, memory + management and other indescribable things ;-) + + * orbsvcs/orbsvcs/Naming/CosNaming_i.cpp (TAO_NamingContext): + Deprecated init(). Also fixed some other simple stuff. + + * tao/IIOP_Object.cpp (IIOP_Object): Fixed initialization for + this->fwd_profile_lock_ptr_. + + * tao/IIOP_Object.i (reset_handler) and (~IIOP_Object): Added code + to cleanup hint svc_handler. + + * tao/ORB.cpp: Fixed template instantiations. + + * tao/GIOP: + * tao/Invocation.cpp + + Changed close to handle_close. + + * tao/Environment.cpp (print_exception): Check for zero exception + before printing. + + * tao/Connect.cpp (handle_close): Close socket but don't delete + instance. Instance will be deleted when all "hints" are + removed. Instance is deleted in close(). + Sun Sep 20 23:30:20 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> * tao/ORB: It is now possible to give an ACE_Time_Value to the diff --git a/TAO/orbsvcs/Naming_Service/Naming_Service.cpp b/TAO/orbsvcs/Naming_Service/Naming_Service.cpp index 41aed3838ad..b22a07be06f 100644 --- a/TAO/orbsvcs/Naming_Service/Naming_Service.cpp +++ b/TAO/orbsvcs/Naming_Service/Naming_Service.cpp @@ -20,18 +20,18 @@ ACE_RCSID(Naming_Service, Naming_Service, "$Id$") -// Default Constructor. + // Default Constructor. -TAO_Naming_Service::TAO_Naming_Service (void) - : ior_output_file_ (0), - pid_file_name_ (0) + TAO_Naming_Service::TAO_Naming_Service (void) + : ior_output_file_ (0), + pid_file_name_ (0) { } // Constructor taking command-line arguments. TAO_Naming_Service::TAO_Naming_Service (int argc, - char* argv[]) + char* argv[]) : ior_output_file_ (0), pid_file_name_ (0) { @@ -40,7 +40,7 @@ TAO_Naming_Service::TAO_Naming_Service (int argc, int TAO_Naming_Service::parse_args (int argc, - char *argv[]) + char *argv[]) { ACE_Get_Opt get_opts (argc, argv, "do:p:"); int c; @@ -80,7 +80,7 @@ TAO_Naming_Service::parse_args (int argc, // Initialize the state of the TAO_Naming_Service object int TAO_Naming_Service::init (int argc, - char* argv[]) + char* argv[]) { int result; CORBA::ORB_var orb; @@ -93,14 +93,12 @@ TAO_Naming_Service::init (int argc, "child_poa", TAO_TRY_ENV); TAO_CHECK_ENV; - + orb = this->orb_manager_.orb (); child_poa = this->orb_manager_.child_poa (); - + result = this->my_naming_server_.init (orb.in (), - child_poa.in (), - argc, - argv); + child_poa.in ()); TAO_CHECK_ENV; if (result == -1) return result; @@ -180,3 +178,4 @@ main (int argc, char* argv[]) TAO_ENDTRY; return 0; } + diff --git a/TAO/orbsvcs/orbsvcs/IOR_Multicast.cpp b/TAO/orbsvcs/orbsvcs/IOR_Multicast.cpp index 6af828d1c10..898b98e781e 100644 --- a/TAO/orbsvcs/orbsvcs/IOR_Multicast.cpp +++ b/TAO/orbsvcs/orbsvcs/IOR_Multicast.cpp @@ -16,7 +16,7 @@ TAO_IOR_Multicast::TAO_IOR_Multicast (void) { } -TAO_IOR_Multicast::TAO_IOR_Multicast (char * ior, +TAO_IOR_Multicast::TAO_IOR_Multicast (const char *ior, u_short port, const char *mcast_addr, TAO_Service_ID service_id) @@ -33,9 +33,9 @@ TAO_IOR_Multicast::~TAO_IOR_Multicast (void) } int -TAO_IOR_Multicast::init (char* ior, +TAO_IOR_Multicast::init (const char *ior, u_short port, - const char* mcast_addr, + const char *mcast_addr, TAO_Service_ID service_id) { this->service_id_ = service_id; diff --git a/TAO/orbsvcs/orbsvcs/IOR_Multicast.h b/TAO/orbsvcs/orbsvcs/IOR_Multicast.h index c80663a9993..5e9dfb36354 100644 --- a/TAO/orbsvcs/orbsvcs/IOR_Multicast.h +++ b/TAO/orbsvcs/orbsvcs/IOR_Multicast.h @@ -37,14 +37,14 @@ public: TAO_IOR_Multicast (void); // Default constructor - TAO_IOR_Multicast (char * ior, + TAO_IOR_Multicast (const char *ior, u_short port, const char *mcast_addr, TAO_Service_ID service_id); - int init (char* ior, + int init (const char *ior, u_short port, - const char* mcast_addr, + const char *mcast_addr, TAO_Service_ID service_id); // destructor @@ -73,7 +73,7 @@ private: ACE_INET_Addr mcast_addr_; // multicast address - char * ior_; + const char *ior_; // object reference to send in response to the multicast ACE_INET_Addr response_addr_; diff --git a/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp index 3674b5fe449..5d40fada498 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp @@ -30,19 +30,13 @@ TAO_NamingContext::TAO_NamingContext (PortableServer::POA_ptr poa, ACE_ERROR ((LM_ERROR, "%p\n", "TAO_NamingContext")); -} -int -TAO_NamingContext::init (void) -{ // Get the lock from the ORB, which knows what type is appropriate. // This method must be called AFTER the ORB has been initialized via // <CORBA::ORB_init> since otherwise <TAO_ORB_Core_instance> won't // work correctly... - ACE_ALLOCATOR_RETURN (this->lock_, - TAO_ORB_Core_instance ()->server_factory ()->create_servant_lock (), - -1); - return 0; + ACE_ALLOCATOR (this->lock_, + TAO_ORB_Core_instance ()->server_factory ()->create_servant_lock ()); } TAO_NamingContext::~TAO_NamingContext (void) @@ -465,33 +459,26 @@ TAO_NamingContext::new_context (CORBA::Environment &_env) { TAO_NamingContext *c = 0; - CosNaming::NamingContext_ptr result = - CosNaming::NamingContext::_nil (); + CosNaming::NamingContext_var result; ACE_NEW_THROW_RETURN (c, TAO_NamingContext (poa_.in ()), CORBA::NO_MEMORY (CORBA::COMPLETED_NO), - result); - if (c->init () == -1) - { - delete c; - TAO_THROW_RETURN (CORBA::INTERNAL (CORBA::COMPLETED_NO), - result); - } - + result._retn ()); TAO_TRY { result = c->_this (TAO_TRY_ENV); TAO_CHECK_ENV; - return result; + return result._retn (); } TAO_CATCHANY { delete c; - CORBA::release (result); - TAO_RETHROW_RETURN (CosNaming::NamingContext::_nil ()); + TAO_RETHROW_RETURN (result._retn ()); } TAO_ENDTRY; + + return result._retn (); } CosNaming::NamingContext_ptr @@ -696,6 +683,7 @@ TAO_NamingContext::list_helper (TAO_BindingIterator* &bind_iter, ACE_NEW_TRY_THROW (bind_iter, TAO_BindingIterator (hash_iter, this->poa_.in (), this->lock_), CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + TAO_CHECK_ENV; } TAO_CATCHANY { diff --git a/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h index 551d58629a6..9ad6d748e47 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h +++ b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h @@ -45,10 +45,6 @@ public: // Default constructor, which initializes the <size> of the table, // and sets a root flag. - int init (void); - // Initialize the lock. The ORB must be initialized when this - // constructor is called. - ~TAO_NamingContext (void); // destructor. diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.cpp b/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.cpp index e6f39dcd4e7..b750398841f 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.cpp @@ -1,23 +1,5 @@ // $Id$ -// ============================================================================ -// -// = LIBRARY -// TAO/orbsvcs/Naming_Service -// -// = FILENAME -// Naming_Utils.cpp -// -// = DESCRIPTION -// This class implements a Naming Server wrapper class that holds -// a Naming Context for TAO NameService. -// -// = AUTHOR -// Nagarajan Surendran <naga@cs.wustl.edu> -// Matthew Braun <mjb2@cec.wustl.edu> -// -// ============================================================================ - #include "orbsvcs/CosNamingC.h" #include "tao/corba.h" #include "Naming_Utils.h" @@ -25,42 +7,43 @@ ACE_RCSID(Naming, Naming_Utils, "$Id$") -// Default constructor - TAO_Naming_Server::TAO_Naming_Server (void) - : ior_multicast_ (0), - naming_context_name_ (CORBA::string_dup ("NameService")) + : naming_context_impl_ (0), + naming_context_ (), + ior_multicast_ (0), + naming_service_ior_ () { } -// Constructor which takes an ORB and POA. - TAO_Naming_Server::TAO_Naming_Server (CORBA::ORB_ptr orb, - PortableServer::POA_ptr child_poa, - int argc, - char **argv) + PortableServer::POA_ptr poa, + ACE_Time_Value *timeout, + int resolve_for_existing_naming_service) + : naming_context_impl_ (0), + naming_context_ (), + ior_multicast_ (0), + naming_service_ior_ () { - if (this->init (orb, child_poa, argc, argv) == -1) + if (this->init (orb, + poa, + timeout, + resolve_for_existing_naming_service) == -1) ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "TAO_Naming_Server::init")); } -// Function to locate (or create if necessary) a name service under -// the passed ORB and POA - int TAO_Naming_Server::init (CORBA::ORB_ptr orb, - PortableServer::POA_ptr child_poa, - int argc, - char **argv) + PortableServer::POA_ptr poa, + ACE_Time_Value *timeout, + int resolve_for_existing_naming_service) { - CORBA::Object_var naming_obj = - // @@ Irfan, here is where we could put a smaller bound on the - // amount of time that we're willing to wait to resolve the - // "NameService." - orb->resolve_initial_references ("NameService"); + CORBA::Object_var naming_obj; + + if (resolve_for_existing_naming_service) + naming_obj = orb->resolve_initial_references ("NameService", timeout); if (CORBA::is_nil (naming_obj.in ())) { @@ -68,9 +51,7 @@ TAO_Naming_Server::init (CORBA::ORB_ptr orb, ACE_DEBUG ((LM_DEBUG, "\nNameService not resolved, so we'll become a NameService\n")); return this->init_new_naming (orb, - child_poa, - argc, - argv); + poa); } else { @@ -78,8 +59,6 @@ TAO_Naming_Server::init (CORBA::ORB_ptr orb, ACE_DEBUG ((LM_DEBUG, "\nNameService found!\n")); - if (this->naming_context_impl_.init () == -1) - return -1; TAO_TRY { this->naming_context_ = @@ -87,225 +66,111 @@ TAO_Naming_Server::init (CORBA::ORB_ptr orb, TAO_TRY_ENV); TAO_CHECK_ENV; - CORBA::String_var str = + this->naming_service_ior_ = orb->object_to_string (naming_obj.in (), TAO_TRY_ENV); TAO_CHECK_ENV; - - this->naming_service_ior_ = str.in (); - this->naming_context_name_ = CORBA::string_dup (""); } TAO_CATCHANY { TAO_TRY_ENV.print_exception ("TAO_Naming_Server::init"); } TAO_ENDTRY; - - // @@ Irfan, must we actually dynamically allocate the - // <naming_ior>? - char *naming_ior = - ACE_OS::strdup (this->naming_service_ior_.in ()); - u_short port = - TAO_ORB_Core_instance ()->orb_params ()->name_service_port (); - - ACE_NEW_RETURN (this->ior_multicast_, - TAO_IOR_Multicast (naming_ior, - port, - ACE_DEFAULT_MULTICAST_ADDR, - TAO_SERVICEID_NAMESERVICE), - -1); } return 0; } -// Function to initialize the name server object under the passed ORB -// and POA. int TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, - PortableServer::POA_ptr child_poa, - int argc, - char **argv) + PortableServer::POA_ptr poa) { - // Initialize our <TAO_NamingContext> instance. - if (this->naming_context_impl_.init () == -1) - return -1; + ACE_NEW_RETURN (this->naming_context_impl_, + TAO_NamingContext (poa, + ACE_DEFAULT_MAP_SIZE, + 1), + -1); - // Parse command-line arguments to determine if this name server - // instance is part of a naming tree that resides under the default - // name server. - ACE_Arg_Shifter args (argc, argv); - - while (args.is_anything_left ()) + TAO_TRY { - char *current_arg = args.get_current (); + PortableServer::ObjectId_var id = + PortableServer::string_to_ObjectId ("NameService"); + + poa->activate_object_with_id (id.in (), + this->naming_context_impl_, + TAO_TRY_ENV); - if (ACE_OS::strcmp (current_arg, "-NScontextname") == 0) - { - args.consume_arg (); - - if (args.is_parameter_next ()) - { - this->naming_context_name_ = - CORBA::string_dup (args.get_current ()); - args.consume_arg (); - } - } - else - args.ignore_arg (); - } + TAO_CHECK_ENV; - TAO_TRY - { - // Check if this invocation is creating a naming context - // different from the default NameService context, if not, - // instantiate a name service, and listen on multicast port. - if (ACE_OS::strcmp (this->naming_context_name_.in (), - "NameService") == 0) - { - // Get the naming context ptr to NameService and register - // with the POA. - this->naming_context_ = - this->naming_context_impl_._this (TAO_TRY_ENV); - TAO_CHECK_ENV; + this->naming_context_ = + this->naming_context_impl_->_this (TAO_TRY_ENV); + TAO_CHECK_ENV; - PortableServer::ObjectId_var id = - PortableServer::string_to_ObjectId ("NameService"); - - child_poa->activate_object_with_id (id.in (), - &this->naming_context_impl_, - TAO_TRY_ENV); - TAO_CHECK_ENV; - - // Stringify the objref we'll be implementing, and print it - // to stdout. Someone will take that string and give it to - // a client. Then release the object. - CORBA::Object_var obj = - child_poa->id_to_reference (id.in (), - TAO_TRY_ENV); - TAO_CHECK_ENV; - - this->naming_service_ior_= - orb->object_to_string (obj.in (), - TAO_TRY_ENV); - TAO_CHECK_ENV; - - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "NameService IOR is <%s>\n", - this->naming_service_ior_.in ())); - + + // Stringify the objref we'll be implementing, and print it to + // stdout. Someone will take that string and give it to a + // client. Then release the object. + CORBA::Object_var obj = + poa->id_to_reference (id.in (), + TAO_TRY_ENV); + TAO_CHECK_ENV; + + this->naming_service_ior_= + orb->object_to_string (obj.in (), + TAO_TRY_ENV); + TAO_CHECK_ENV; + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "NameService IOR is <%s>\n", + this->naming_service_ior_.in ())); + #if defined (ACE_HAS_IP_MULTICAST) - // Get reactor instance from TAO. - ACE_Reactor *reactor = - TAO_ORB_Core_instance ()->reactor (); + // Get reactor instance from TAO. + ACE_Reactor *reactor = + TAO_ORB_Core_instance ()->reactor (); - // First, see if the user has given us a multicast port number - // for the name service on the command-line; - u_short port = - TAO_ORB_Core_instance ()->orb_params ()->name_service_port (); - - if (port == 0) - { - const char *port_number = - ACE_OS::getenv ("NameServicePort"); - - if (port_number != 0) - port = ACE_OS::atoi (port_number); - } - - if (port == 0) - port = TAO_DEFAULT_NAME_SERVER_REQUEST_PORT; - - char *naming_ior = ACE_OS::strdup (this->naming_service_ior_.in ()); - - // Instantiate a server which will receive requests for an ior - ACE_NEW_RETURN (this->ior_multicast_, - TAO_IOR_Multicast (naming_ior, - port, - ACE_DEFAULT_MULTICAST_ADDR, - TAO_SERVICEID_NAMESERVICE), - -1); + // First, see if the user has given us a multicast port number + // for the name service on the command-line; + u_short port = + TAO_ORB_Core_instance ()->orb_params ()->name_service_port (); - // Register event handler for the ior multicast. - if (reactor->register_handler (this->ior_multicast_, - ACE_Event_Handler::READ_MASK) == -1) - { - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "cannot register Event handler\n")); - } - else - { - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "The multicast server setup is done.\n")); - } -#endif /* ACE_HAS_IP_MULTICAST */ - } + if (port == 0) + { + const char *port_number = + ACE_OS::getenv ("NameServicePort"); + + if (port_number != 0) + port = ACE_OS::atoi (port_number); + } + + if (port == 0) + port = TAO_DEFAULT_NAME_SERVER_REQUEST_PORT; + + // Instantiate a server which will receive requests for an ior + ACE_NEW_RETURN (this->ior_multicast_, + TAO_IOR_Multicast (this->naming_service_ior_.in (), + port, + ACE_DEFAULT_MULTICAST_ADDR, + TAO_SERVICEID_NAMESERVICE), + -1); + + // Register event handler for the ior multicast. + if (reactor->register_handler (this->ior_multicast_, + ACE_Event_Handler::READ_MASK) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "cannot register Event handler\n")); + return -1; + } else - { - // We are instantiating a name service to manage a naming - // context other than the default NameService context. We - // need to verify that all contexts in the compound name - // exist (if we are passed a compound naming context). Any - // missing contexts will be created and bound into the - // naming service utilized by this name server instance. - // Finally, this name server will bind the context that it's - // managing into it's parent's context. - - CORBA::Object_var default_ns = - orb->resolve_initial_references ("NameService"); - - if (CORBA::is_nil (default_ns.in ())) - ACE_ERROR ((LM_ERROR, - "%p\n", - "NameService")); - - CosNaming::NamingContext_var default_ctx = - CosNaming::NamingContext::_narrow (default_ns.in (), - TAO_TRY_ENV); - TAO_CHECK_ENV; - - // Temporary hack, to see if this works as expected. Need - // to add code to walk the naming tree from root to the - // context represented by this server. - PortableServer::ObjectId_var id = - PortableServer::string_to_ObjectId (this->naming_context_name_.in ()); - - child_poa->activate_object_with_id (id.in (), - &naming_context_impl_, - TAO_TRY_ENV); - TAO_CHECK_ENV; - - // Stringify the objref we'll be implementing, and print it to - // stdout. Someone will take that string and give it to a - // client. Then release the object. - CORBA::Object_var obj = - child_poa->id_to_reference (id.in (), - TAO_TRY_ENV); - TAO_CHECK_ENV; - - this->naming_service_ior_= - orb->object_to_string (obj.in (), - TAO_TRY_ENV); - TAO_CHECK_ENV; - - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "NameService IOR is <%s>\n", - this->naming_service_ior_.in ())); - - // Bind our context into the default name server. - CosNaming::Name ctx_name (1); - ctx_name.length (1); - ctx_name[0].id = CORBA::string_dup (naming_context_name_.in ()); - - default_ctx->bind_context (ctx_name, - naming_context_impl_._this (TAO_TRY_ENV), - TAO_TRY_ENV); - TAO_CHECK_ENV; - } + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "The multicast server setup is done.\n")); + } +#endif /* ACE_HAS_IP_MULTICAST */ } TAO_CATCHANY { @@ -321,7 +186,7 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, TAO_NamingContext & TAO_Naming_Server::get_naming_context (void) { - return naming_context_impl_ ; + return *this->naming_context_impl_; } CORBA::String @@ -333,22 +198,21 @@ TAO_Naming_Server::naming_service_ior (void) // Returns a pointer to the NamingContext. CosNaming::NamingContext_ptr -TAO_Naming_Server::operator -> (void) const +TAO_Naming_Server::operator-> (void) const { return this->naming_context_.ptr (); } -// Destructor. - TAO_Naming_Server::~TAO_Naming_Server (void) { if (this->ior_multicast_ != 0) { TAO_ORB_Core_instance ()->reactor ()->remove_handler (this->ior_multicast_, - ACE_Event_Handler::READ_MASK); + ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); delete this->ior_multicast_; } + delete this->naming_context_impl_; } // Returns a pointer to the NamingContext. @@ -368,9 +232,7 @@ TAO_Naming_Client::get_context (void) const } int -TAO_Naming_Client::init (CORBA::ORB_ptr orb, - int argc, - char *argv[]) +TAO_Naming_Client::init (CORBA::ORB_ptr orb) { TAO_TRY { diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.h b/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.h index d941551be20..ecea3afc753 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.h +++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Utils.h @@ -30,50 +30,38 @@ class TAO_ORBSVCS_Export TAO_Naming_Server { // = TITLE - // Defines a wrapper class that holds a Naming Context - // implementation for a TAO "NamingService" naming context. + // + // Defines a wrapper class that holds the root Naming Context. // // = DESCRIPTION - // This class takes an ORB and POA reference and activates the - // NamingService naming context object under that. It also - // defines the operator-> so that <NamingContext> functions like - // <bind>, <unbind> .. can be called on a <NameServer> object. - // This class is intended to simplify programs that want to play - // the role of a Naming Service servers. To simplify programs - // that want to play the role of Naming Service clients, use - // <TAO_Naming_Client>. + // + // This class either finds an existing Naming Service or creates + // one. It also defines the operator-> so that <NamingContext> + // functions like <bind>, <unbind> .. can be called on a + // <NameServer> object. This class is intended to simplify + // programs that want to play the role of a Naming Service + // servers. To simplify programs that want to play the role of + // Naming Service clients, use <TAO_Naming_Client>. public: - // = Initialization and termination methods. - TAO_Naming_Server (void); - //Default constructor. + // Default constructor. TAO_Naming_Server (CORBA::ORB_ptr orb, - PortableServer::POA_ptr root_poa, - int argc = 0, - char **argv = 0); - // Takes the POA under which to register the Naming Service - // implementation object. The <argc> and <argv> commmand-line - // arguments are parsed to determine if this name server instance is - // part of a naming tree that resides under the default name server. + PortableServer::POA_ptr poa, + ACE_Time_Value *timeout = 0, + int resolve_for_existing_naming_service = 1); + // Either find an existing Naming Service or creates one. Takes the + // POA under which to register the Naming Service implementation + // object. int init (CORBA::ORB_ptr orb, - PortableServer::POA_ptr root_poa, - int argc = 0, - char **argv = 0); - // Locate a name server under the given ORB and POA. If no name - // server can be resolved, create a new name server. + PortableServer::POA_ptr poa, + ACE_Time_Value *timeout = 0, + int resolve_for_existing_naming_service = 1); + // Either find an existing Naming Service or creates one. Takes the + // POA under which to register the Naming Service implementation + // object. - int init_new_naming (CORBA::ORB_ptr orb, - PortableServer::POA_ptr root_poa, - int argc = 0, - char **argv = 0); - // Initialize a new name server under the given ORB and POA, even - // if one already exists. The <argc> and <argv> commmand-line - // arguments are parsed to determine if this name server instance is - // part of a naming tree that resides under the default name - // server. - ~TAO_Naming_Server (void); // Destructor. @@ -87,12 +75,13 @@ public: CosNaming::NamingContext_ptr operator-> (void) const; // Returns a <NamingContext_ptr>. -private: - // @@ Marina, can you please revise this to use dynamic allocation - // rather than be allocated in the class. This will make sure that - // we follow a consistent policy for managing the memory of our - // NamingContexts... - TAO_NamingContext naming_context_impl_; +protected: + + int init_new_naming (CORBA::ORB_ptr orb, + PortableServer::POA_ptr root_poa); + // Initialize a new name server under the given ORB and POA. + + TAO_NamingContext *naming_context_impl_; // Naming context implementation for "NameService". CosNaming::NamingContext_var naming_context_; @@ -103,19 +92,17 @@ private: CORBA::String_var naming_service_ior_; // The IOR string of the naming service. - - CORBA::String_var naming_context_name_; - // Name of the naming context (if different than - // "NameService"). }; class TAO_ORBSVCS_Export TAO_Naming_Client { // = TITLE + // // Defines a wrapper class that simplifies initialization and // access to a <NamingContext>. // // = DESCRIPTION + // // This class takes an ORB reference and contacts the // NamingService naming context object under that. It also // defines the operator-> so that <NamingContext> functions like @@ -124,18 +111,11 @@ class TAO_ORBSVCS_Export TAO_Naming_Client // the role of a Naming Service clients. public: - // = Initialization and termination methods. - TAO_Naming_Client (void); - //Default constructor. + // Default constructor. - int init (CORBA::ORB_ptr orb, - int argc = 0, - char **argv = 0); - // Initialize the name server under the given ORB and POA. The - // <argc> and <argv> commmand-line arguments are parsed to determine - // if this name server instance is part of a naming tree that - // resides under the default name server. + int init (CORBA::ORB_ptr orb); + // Initialize the name server. ~TAO_Naming_Client (void); // Destructor. @@ -146,7 +126,7 @@ public: CosNaming::NamingContext_ptr get_context (void) const; // Returns the NamingContext -private: +protected: CosNaming::NamingContext_var naming_context_; // NamingContext ptr. }; diff --git a/TAO/performance-tests/Cubit/TAO/DII_Cubit/client.cpp b/TAO/performance-tests/Cubit/TAO/DII_Cubit/client.cpp index 87ca3963316..9cf30b229a3 100644 --- a/TAO/performance-tests/Cubit/TAO/DII_Cubit/client.cpp +++ b/TAO/performance-tests/Cubit/TAO/DII_Cubit/client.cpp @@ -332,7 +332,7 @@ DII_Cubit_Client::init_naming_service (void) TAO_TRY { // Initialize the naming services - if (my_name_client_.init (orb_var_.in (), argc_, argv_) != 0) + if (my_name_client_.init (orb_var_.in ()) != 0) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize " "the TAO_Naming_Client. \n"), diff --git a/TAO/performance-tests/Cubit/TAO/IDL_Cubit/Cubit_Client.cpp b/TAO/performance-tests/Cubit/TAO/IDL_Cubit/Cubit_Client.cpp index 934eb5b5dbb..b7af1860af0 100644 --- a/TAO/performance-tests/Cubit/TAO/IDL_Cubit/Cubit_Client.cpp +++ b/TAO/performance-tests/Cubit/TAO/IDL_Cubit/Cubit_Client.cpp @@ -1020,7 +1020,7 @@ Cubit_Client::init_naming_service (void) */ // Initialize the naming services - if (my_name_client_.init (orb_.in (), argc_, argv_) != 0) + if (my_name_client_.init (orb_.in ()) != 0) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to initialize " "the TAO_Naming_Client. \n"), diff --git a/TAO/tao/Connect.cpp b/TAO/tao/Connect.cpp index 812bc1f0fbd..a1aa8ffc6af 100644 --- a/TAO/tao/Connect.cpp +++ b/TAO/tao/Connect.cpp @@ -479,7 +479,7 @@ TAO_Server_Connection_Handler::send_error (CORBA::ULong request_id, ACE_DEBUG ((LM_DEBUG,"(%P|%t) closing conn %d after fault %p\n", this->peer().get_handle (), "TAO_Server_ConnectionHandler::send_error")); - this->close (); + this->handle_close (); return; } TAO_ENDTRY; @@ -589,7 +589,7 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) ACE_ERROR ((LM_ERROR, "(%P|%t) exception thrown " "but client is not waiting a response\n")); - this->close (); + this->handle_close (); result = -1; } return result; @@ -603,7 +603,7 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) "(%P|%t) closing conn %d after fault %p\n", this->peer().get_handle (), "TAO_Server_ConnectionHandler::handle_input")); - this->close (); + this->handle_close (); return -1; } TAO_ENDTRY; @@ -621,7 +621,7 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) "(%P|%t) %s: closing conn, no exception, " "but expecting response\n", "TAO_Server_ConnectionHandler::handle_input")); - this->close (); + this->handle_close (); return -1; } } @@ -634,7 +634,7 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) "(%P|%t) %s: closing conn, no exception, " "but expecting response\n", "TAO_Server_ConnectionHandler::handle_input")); - this->close (); + this->handle_close (); return -1; } @@ -967,7 +967,20 @@ TAO_Client_Connection_Handler::handle_close (ACE_HANDLE handle, handle, rm)); - return BASECLASS::handle_close (handle, rm); + if (this->recycler ()) + this->recycler ()->mark_as_closed (this->recycling_act ()); + + this->shutdown (); + + return 0; +} + +int +TAO_Client_Connection_Handler::close (u_long flags) +{ + this->destroy (); + + return 0; } #define TAO_SVC_TUPLE ACE_Svc_Tuple<TAO_Client_Connection_Handler> diff --git a/TAO/tao/Connect.h b/TAO/tao/Connect.h index 6fb6f8e0015..ab0cfac8707 100644 --- a/TAO/tao/Connect.h +++ b/TAO/tao/Connect.h @@ -58,8 +58,12 @@ public: virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); // Called when a a response from a twoway invocation is available. - virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); - // Perform appropriate closing of the connection. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Perform appropriate closing. + + virtual int close (u_long flags = 0); + // Object termination hook. private: typedef TAO_SVC_HANDLER BASECLASS; @@ -154,9 +158,9 @@ protected: // Reads a message from the <peer()>, dispatching and servicing it // appropriately. - virtual int handle_close (ACE_HANDLE, - ACE_Reactor_Mask); - // Perform appropriate closing of the connection. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Perform appropriate closing. TAO_ORB_Core *orb_core_; // Cache the ORB Core to minimize diff --git a/TAO/tao/Environment.cpp b/TAO/tao/Environment.cpp index 8a4090584f2..43f60951209 100644 --- a/TAO/tao/Environment.cpp +++ b/TAO/tao/Environment.cpp @@ -144,40 +144,46 @@ void CORBA::Environment::print_exception (const char *info, FILE *) const { - const char *id = this->exception_->_id (); - - ACE_DEBUG ((LM_ERROR, "(%P|%t) EXCEPTION, %s\n", info)); - - // @@ get rid of this logic, and rely on some member function on - // Exception to say if it's user or system exception. - - if (this->exception_type () == CORBA::SYSTEM_EXCEPTION) + if (this->exception_) { - CORBA::SystemException *x2 = - CORBA_SystemException::_narrow (this->exception_); - - // @@ there are a other few "user exceptions" in the CORBA - // scope, they're not all standard/system exceptions ... really - // need to either compare exhaustively against all those IDs - // (yeech) or (preferably) to represent the exception type - // directly in the exception value so it can be queried. - - ACE_DEBUG ((LM_ERROR, - "(%P|%t) system exception, ID '%s'\n", - id)); - ACE_DEBUG ((LM_ERROR, - "(%P|%t) minor code = %x, completed = %s\n", - x2->minor (), - (x2->completion () == CORBA::COMPLETED_YES) ? "YES" : - (x2->completion () == CORBA::COMPLETED_NO) ? "NO" : - (x2->completion () == CORBA::COMPLETED_MAYBE) ? "MAYBE" : - "garbage")); + const char *id = this->exception_->_id (); + + ACE_DEBUG ((LM_ERROR, "(%P|%t) EXCEPTION, %s\n", info)); + + // @@ get rid of this logic, and rely on some member function on + // Exception to say if it's user or system exception. + + if (this->exception_type () == CORBA::SYSTEM_EXCEPTION) + { + CORBA::SystemException *x2 = + CORBA_SystemException::_narrow (this->exception_); + + // @@ there are a other few "user exceptions" in the CORBA + // scope, they're not all standard/system exceptions ... really + // need to either compare exhaustively against all those IDs + // (yeech) or (preferably) to represent the exception type + // directly in the exception value so it can be queried. + + ACE_DEBUG ((LM_ERROR, + "(%P|%t) system exception, ID '%s'\n", + id)); + ACE_DEBUG ((LM_ERROR, + "(%P|%t) minor code = %x, completed = %s\n", + x2->minor (), + (x2->completion () == CORBA::COMPLETED_YES) ? "YES" : + (x2->completion () == CORBA::COMPLETED_NO) ? "NO" : + (x2->completion () == CORBA::COMPLETED_MAYBE) ? "MAYBE" : + "garbage")); + } + else + // @@ we can use the exception's typecode to dump all the data + // held within it ... + + ACE_DEBUG ((LM_ERROR, + "(%P|%t) user exception, ID '%s'\n", + id)); } else - // @@ we can use the exception's typecode to dump all the data - // held within it ... - ACE_DEBUG ((LM_ERROR, - "(%P|%t) user exception, ID '%s'\n", - id)); + "(%P|%t) no exception\n")); } diff --git a/TAO/tao/GIOP.cpp b/TAO/tao/GIOP.cpp index f5041d7b3ce..863bc03d8da 100644 --- a/TAO/tao/GIOP.cpp +++ b/TAO/tao/GIOP.cpp @@ -287,7 +287,7 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, ACE_DEBUG ((LM_DEBUG, "(%P|%t) closing conn %d after fault %p\n", peer.get_handle (), "GIOP::send_request")); - handler->close (); + handler->handle_close (); return 0; } else if (n == 0) @@ -297,7 +297,7 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, "(%P|%t) GIOP::send_request (): " "EOF, closing conn %d\n", peer.get_handle ())); - handler->close (); + handler->handle_close (); return 0; } iovcnt = 0; @@ -313,7 +313,7 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, ACE_DEBUG ((LM_DEBUG, "(%P|%t) closing conn %d after fault %p\n", peer.get_handle (), "GIOP::send_request")); - handler->close (); + handler->handle_close (); return 0; } else if (n == 0) @@ -323,7 +323,7 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, "(%P|%t) GIOP::send_request (): " "EOF, closing conn %d\n", peer.get_handle ())); - handler->close (); + handler->handle_close (); return 0; } iovcnt = 0; @@ -374,7 +374,7 @@ TAO_GIOP::close_connection (TAO_Client_Connection_Handler *&handler, handler->peer ().send (close_message, TAO_GIOP_HEADER_LEN); ACE_HANDLE which = handler->peer ().get_handle (); - handler->close (); + handler->handle_close (); handler = 0; ACE_DEBUG ((LM_DEBUG, "(%P|%t) shut down socket %d\n", which)); @@ -406,7 +406,7 @@ TAO_GIOP::send_error (TAO_Client_Connection_Handler *&handler) TAO_GIOP_HEADER_LEN); handler->peer ().send_n (error_message, TAO_GIOP_HEADER_LEN); ACE_HANDLE which = handler->peer ().get_handle (); - handler->close (); + handler->handle_close (); handler = 0; if (TAO_orbdebug) ACE_DEBUG ((LM_DEBUG, "(%P|%t) aborted socket %d\n", which)); diff --git a/TAO/tao/IIOP_Object.cpp b/TAO/tao/IIOP_Object.cpp index 17f7a5d79be..b00ead1c4c3 100644 --- a/TAO/tao/IIOP_Object.cpp +++ b/TAO/tao/IIOP_Object.cpp @@ -338,6 +338,8 @@ IIOP_Object::IIOP_Object (const char *host, refcount_ (1), handler_ (0) { + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } // Constructor. It will usually be used by the server side. @@ -351,9 +353,8 @@ IIOP_Object::IIOP_Object (char *repository_id, refcount_ (1), handler_ (0) { - this->fwd_profile_lock_ptr_ = TAO_ORB_Core_instance () - ->client_factory () - ->create_iiop_profile_lock (); + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } // THREADING NOTE: Code below this point is of course thread-safe (at diff --git a/TAO/tao/IIOP_Object.i b/TAO/tao/IIOP_Object.i index ffa50e0f1f7..eed11414d1a 100644 --- a/TAO/tao/IIOP_Object.i +++ b/TAO/tao/IIOP_Object.i @@ -40,6 +40,10 @@ IIOP_Object::~IIOP_Object (void) assert (this->refcount_ == 0); delete this->fwd_profile_; delete this->fwd_profile_lock_ptr_; + + // Cleanup hint + if (this->handler_ != 0) + this->handler_->cleanup_hint (); } ACE_INLINE @@ -52,9 +56,8 @@ IIOP_Object::IIOP_Object (char *repository_id) first_locate_request_ (0), handler_ (0) { - this->fwd_profile_lock_ptr_ = TAO_ORB_Core_instance () - ->client_factory () - ->create_iiop_profile_lock (); + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } ACE_INLINE @@ -69,9 +72,8 @@ IIOP_Object::IIOP_Object (char *repository_id, first_locate_request_ (0), handler_ (0) { - this->fwd_profile_lock_ptr_ = TAO_ORB_Core_instance () - ->client_factory () - ->create_iiop_profile_lock (); + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } @@ -155,6 +157,7 @@ IIOP_Object::handler (void) ACE_INLINE void IIOP_Object::reset_handler (void) { + this->handler_->cleanup_hint (); this->handler_ = 0; } diff --git a/TAO/tao/Invocation.cpp b/TAO/tao/Invocation.cpp index cab4335662f..f91113947b2 100644 --- a/TAO/tao/Invocation.cpp +++ b/TAO/tao/Invocation.cpp @@ -370,7 +370,7 @@ TAO_GIOP_Invocation::invoke (CORBA::Boolean is_roundtrip, // Send Request, return on error or if we're done if (this->data_->handler ()->send_request (this->out_stream_, - is_roundtrip) == -1) + is_roundtrip) == -1) { // send_request () closed the connection; we just set the // handler to 0 here. @@ -423,7 +423,7 @@ TAO_GIOP_Invocation::close_connection (void) // resets the flag of the first call locate request to true } - this->data_->handler ()->close (); + this->data_->handler ()->handle_close (); this->data_->reset_handler (); return TAO_GIOP_LOCATION_FORWARD; } @@ -1038,8 +1038,7 @@ TAO_GIOP_Locate_Request_Invocation::invoke (CORBA::Environment &env) { // Send Request, return on error or if we're done - if (this->data_->handler ()->send_request (this->out_stream_, - 1) == -1) + if (this->data_->handler ()->send_request (this->out_stream_, 1) == -1) { // send_request () closed the connection; we just set the // handler to 0 here. diff --git a/TAO/tao/ORB.cpp b/TAO/tao/ORB.cpp index faa616f56ff..21468128b64 100644 --- a/TAO/tao/ORB.cpp +++ b/TAO/tao/ORB.cpp @@ -865,9 +865,9 @@ operator>>(TAO_InputCDR& cdr, TAO_opaque& x) // **************************************************************** -#define TAO_HASH_ADDR ACE_Hash_Addr<ACE_INET_Addr> -#define TAO_RECYCLABLE_ADDR ACE_Recyclable<TAO_HASH_ADDR> -#define TAO_HASH_RECYCLABLE_ADDR ACE_Hash_Recyclable<TAO_HASH_ADDR> +#define CACHED_CONNECT_STRATEGY ACE_Cached_Connect_Strategy<Svc_Handler, ACE_SOCK_CONNECTOR, ACE_SYNCH_MUTEX> +#define HASH_ADDR CACHED_CONNECT_STRATEGY::HASH_ADDRESS +#define REFCOUNTED_HASH_RECYCLABLE_ADDR CACHED_CONNECT_STRATEGY::REFCOUNTED_HASH_RECYCLABLE_ADDRESS #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) @@ -877,18 +877,18 @@ template class TAO_Unbounded_Sequence<CORBA::Octet>; template class ACE_Dynamic_Service<TAO_Server_Strategy_Factory>; template class ACE_Dynamic_Service<TAO_Client_Strategy_Factory>; -template class ACE_Cached_Connect_Strategy<TAO_Client_Connection_Handler, TAO_SOCK_CONNECTOR, TAO_Cached_Connector_Lock>; +template class CACHED_CONNECT_STRATEGY; template class ACE_Guard<TAO_Cached_Connector_Lock>; template class ACE_Atomic_Op<ACE_SYNCH_MUTEX, u_int>; -template class ACE_Hash_Map_Entry<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *>; -template class ACE_Hash_Map_Manager<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Iterator_Base<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Manager<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; -template class ACE_Hash_Map_Iterator_Base<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; -template class ACE_Hash_Map_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; +template class ACE_Hash_Map_Entry<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *>; +template class ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; +template class ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; +template class ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; +template class ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX>; +template class ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; +template class ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; +template class ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; +template class ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) @@ -898,17 +898,17 @@ template class ACE_Hash_Map_Reverse_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Clien #pragma instantiate ACE_Dynamic_Service<TAO_Server_Strategy_Factory> #pragma instantiate ACE_Dynamic_Service<TAO_Client_Strategy_Factory> -#pragma instantiate ACE_Cached_Connect_Strategy<TAO_Client_Connection_Handler, TAO_SOCK_CONNECTOR, TAO_Cached_Connector_Lock> +#pragma instantiate CACHED_CONNECT_STRATEGY #pragma instantiate ACE_Guard<TAO_Cached_Connector_Lock> #pragma instantiate ACE_Atomic_Op<ACE_SYNCH_MUTEX, u_int> -//#pragma instantiate TAO_HASH_RECYCLABLE_ADDR -#pragma instantiate ACE_Hash_Map_Entry<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *> -#pragma instantiate ACE_Hash_Map_Manager<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Base<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Manager<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Base<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> +//#pragma instantiate REFCOUNTED_HASH_RECYCLABLE_ADDR +#pragma instantiate ACE_Hash_Map_Entry<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *> +#pragma instantiate ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, TAO_Client_Connection_Handler *, ACE_SYNCH_NULL_MUTEX> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/ace/Strategies.h b/ace/Strategies.h index ec95bf7e2e5..03bd8d2d71d 100644 --- a/ace/Strategies.h +++ b/ace/Strategies.h @@ -96,11 +96,78 @@ public: virtual int cache (const void *recycling_act) = 0; // Add to cache. + virtual int mark_as_closed (const void *recycling_act) = 0; + // Mark as closed. + + virtual int cleanup_hint (const void *recycling_act) = 0; + // Cleanup as hint. + protected: ACE_Connection_Recycling_Strategy (void); // Default ctor. }; +class ACE_Export ACE_Recyclable +{ +public: + enum State + { + IDLE, + BUSY, + CLOSED, + UNKNOWN + }; + + virtual ~ACE_Recyclable (void); + // Destructor. + + // = Set/Get the recyclable bit + State state (void) const; + void state (State new_state); + +protected: + ACE_Recyclable (State initial_state); + // Protected constructor. + + State state_; + // Our state. +}; + +class ACE_Export ACE_Hashable +{ +public: + virtual ~ACE_Hashable (void); + // Destructor. + + virtual u_long hash (void) const = 0; + // Computes and returns hash value. + +protected: + ACE_Hashable (void); + // Protected constructor. +}; + +class ACE_Export ACE_Refcountable +{ +public: + virtual ~ACE_Refcountable (void); + // Destructor. + + // = Increment/Decrement refcount + int increment (void); + int decrement (void); + + int refcount (void) const; + // Returns the current refcount. + +protected: + ACE_Refcountable (int refcount); + // Protected constructor. + + int refcount_; + // Current refcount. +}; + // This needs to come here to avoid circular dependencies. #include "ace/Strategies_T.h" diff --git a/ace/Strategies.i b/ace/Strategies.i index bcc6318f9da..a0ef94ea2da 100644 --- a/ace/Strategies.i +++ b/ace/Strategies.i @@ -12,3 +12,66 @@ ACE_INLINE ACE_Connection_Recycling_Strategy::ACE_Connection_Recycling_Strategy (void) { } + +ACE_INLINE +ACE_Recyclable::ACE_Recyclable (ACE_Recyclable::State initial_state) + : state_ (initial_state) +{ +} + +ACE_INLINE +ACE_Recyclable::~ACE_Recyclable (void) +{ +} + +ACE_INLINE ACE_Recyclable::State +ACE_Recyclable::state (void) const +{ + return this->state_; +} + +ACE_INLINE void +ACE_Recyclable::state (ACE_Recyclable::State new_state) +{ + this->state_ = new_state; +} + +ACE_INLINE +ACE_Hashable::ACE_Hashable (void) +{ +} + +ACE_INLINE +ACE_Hashable::~ACE_Hashable (void) +{ +} + +ACE_INLINE +ACE_Refcountable::ACE_Refcountable (int refcount) + : refcount_ (refcount) +{ +} + +ACE_INLINE +ACE_Refcountable::~ACE_Refcountable (void) +{ +} + +ACE_INLINE int +ACE_Refcountable::increment (void) +{ + return ++this->refcount_; +} + +ACE_INLINE int +ACE_Refcountable::decrement (void) +{ + return --this->refcount_; +} + +ACE_INLINE int +ACE_Refcountable::refcount (void) const +{ + return this->refcount_; +} + diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp index 170af695e00..9d036e2b9ec 100644 --- a/ace/Strategies_T.cpp +++ b/ace/Strategies_T.cpp @@ -459,6 +459,135 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::open return 0; } +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> void +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::check_hint_i + (SVC_HANDLER *&sh, + HASH_ADDRESS &search_addr, + CONNECTION_MAP_ENTRY *&entry, + int &found) +{ + 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_.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_->close (); + } + + // 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_ == search_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; +} + +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, + HASH_ADDRESS &search_addr, + CONNECTION_MAP_ENTRY *&entry, + int &found) +{ + // 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->connection_cache_.find (search_addr, entry) == -1) + { + // Set the flag + found = 0; + + // Create a new svc_handler + if (this->make_svc_handler (sh) == -1) + return -1; + + // Actively establish the connection. This is a timed blocking + // connect. + if (this->CONNECT_STRATEGY::connect_svc_handler (sh, + 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; + return -1; + } + else + { + // Insert the new SVC_HANDLER instance into the cache. + if (this->connection_cache_.bind (search_addr, + sh, + entry) == -1) + return -1; + + // 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>::connect_svc_handler (SVC_HANDLER *&sh, @@ -478,105 +607,40 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_s CONNECTION_MAP_ENTRY *entry = 0; // Create the search key - ADDRESS search_addr (remote_addr); + HASH_ADDRESS search_addr (remote_addr); // Synchronization is required here as the setting of the - // recyclable bit must be done atomically with the finding and + // 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); // Check if the user passed a hint svc_handler if (sh != 0) - { - // If so, see if it is connected to the correct address and is - // recyclable - entry = (CONNECTION_MAP_ENTRY *) sh->recycling_act (); - if (entry->ext_id_ == search_addr) - { - // Set the flag - found = 1; - - // Tell the <svc_handler> that it should prepare itself for - // being recycled. - this->prepare_for_recycling (sh); - } - else - { - // If <sh> is not connected to the correct address or is - // busy, we will not use it. - sh = 0; - } - } + this->check_hint_i (sh, search_addr, entry, found); // If not found if (!found) { - // 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->connection_cache_.find (search_addr, entry) == -1) - { - // Set the flag - found = 0; - - // Create a new svc_handler - if (this->make_svc_handler (sh) == -1) - return -1; - - // Actively establish the connection. This is a timed - // blocking connect. - if (this->CONNECT_STRATEGY::connect_svc_handler (sh, - 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; - return -1; - } - else - { - // - // Insert the new SVC_HANDLER instance into the cache. - // - // Create the key - ADDRESS server_addr (remote_addr); - if (this->connection_cache_.bind (server_addr, - sh, - entry) == -1) - return -1; - - // 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); - } + int result = this->find_or_create_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + search_addr, + 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 0. - entry->ext_id_.recyclable (0); + // as being <in_use>. Therefore recyclable is BUSY. + entry->ext_id_.state (ACE_Recyclable::BUSY); + + // And increment the refcount + entry->ext_id_.increment (); } // If it is a new connection, activate it. @@ -599,16 +663,22 @@ 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 - // bit must be done atomically with respect to other threads that + // 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 1. - entry->ext_id_.recyclable (1); + // Therefore recyclable is IDLE. + entry->ext_id_.state (ACE_Recyclable::IDLE); return 0; } @@ -619,13 +689,69 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge (co // 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_cache_.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_.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) +{ + // 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); +} + +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) +{ + // 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_.state () == ACE_Recyclable::CLOSED && + refcount == 0) + entry->int_id_->close (); + + return 0; +} + template <class SVC_HANDLER> void ACE_DLL_Strategy<SVC_HANDLER>::dump (void) const { diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h index 5c17c90f112..b5514295ea5 100644 --- a/ace/Strategies_T.h +++ b/ace/Strategies_T.h @@ -686,59 +686,6 @@ public: // This is a no-op. }; -template <class T> -class ACE_Recyclable -{ -public: - - // = Initialization methods. - ACE_Recyclable (void); - // Default constructor. - - ACE_Recyclable (const T &t, int recyclable = 0); - // Constructor. - - ~ACE_Recyclable (void); - // Destructor. - - int operator== (const ACE_Recyclable<T> &rhs) const; - // Compares two values. - - // = Set/Get the recyclable bit - int recyclable (void) const; - void recyclable (int new_value); - -protected: - int recyclable_; - // We need to know if the <T> is "in-use". If it is, we can - // operator==() can skip the comparison. - - T t_; - // The underlying class. -}; - -template <class T> -class ACE_Hash_Recyclable : public ACE_Recyclable<T> -{ -public: - - // = Initialization methods. - ACE_Hash_Recyclable (void); - // Default constructor. - - ACE_Hash_Recyclable (const T &t, int recyclable = 0); - // Constructor. - - ~ACE_Hash_Recyclable (void); - // Destructor. - - u_long hash (void) const; - // Computes and returns hash value. - - int operator== (const ACE_Recyclable<T> &rhs) const; - // Compares two values. -}; - template <class ADDR_T> class ACE_Hash_Addr { @@ -780,6 +727,33 @@ private: // The underlying address. }; +template <class T> +class ACE_Refcounted_Hash_Recyclable : public ACE_Refcountable, + public ACE_Hashable, + public ACE_Recyclable +{ +public: + ACE_Refcounted_Hash_Recyclable (void); + // Default constructor. + + ACE_Refcounted_Hash_Recyclable (const T &t, + int refcount = 0, + ACE_Recyclable::State state = ACE_Recyclable::UNKNOWN); + // Constructor. + + virtual ~ACE_Refcounted_Hash_Recyclable (void); + // Destructor + + u_long hash (void) const; + // Computes and returns hash value. + + int operator== (const ACE_Refcounted_Hash_Recyclable<T> &rhs) const; + // Compares two instances. + +protected: + T t_; +}; + template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> class ACE_Cached_Connect_Strategy : public ACE_Connection_Recycling_Strategy, public ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> { @@ -868,7 +842,12 @@ public: virtual int cache (const void *recycling_act); // Add to cache. -private: + virtual int mark_as_closed (const void *recycling_act); + // Mark as closed. + + virtual int cleanup_hint (const void *recycling_act); + // Cleanup hint. + // = Define some useful typedefs. typedef ACE_Creation_Strategy<SVC_HANDLER> CREATION_STRATEGY; @@ -883,16 +862,47 @@ private: // = Typedefs for managing the map typedef ACE_Hash_Addr<ACE_PEER_CONNECTOR_ADDR> - ADDRESS; - typedef ACE_Hash_Recyclable<ADDRESS> - RECYCLABLE_ADDRESS; - typedef ACE_Hash_Map_Manager <RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex> + HASH_ADDRESS; + typedef ACE_Refcounted_Hash_Recyclable<HASH_ADDRESS> + REFCOUNTED_HASH_RECYCLABLE_ADDRESS; + typedef ACE_Hash_Map_Manager <REFCOUNTED_HASH_RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex> CONNECTION_MAP; - typedef ACE_Hash_Map_Iterator <RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex> + typedef ACE_Hash_Map_Iterator <REFCOUNTED_HASH_RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex> CONNECTION_MAP_ITERATOR; - typedef ACE_Hash_Map_Entry<RECYCLABLE_ADDRESS, SVC_HANDLER *> + typedef ACE_Hash_Map_Entry<REFCOUNTED_HASH_RECYCLABLE_ADDRESS, SVC_HANDLER *> CONNECTION_MAP_ENTRY; +protected: + + virtual int purge_i (const void *recycling_act); + // Remove from cache (non-locking version). + + virtual int cache_i (const void *recycling_act); + // Add to cache (non-locking version). + + virtual int mark_as_closed_i (const void *recycling_act); + // Mark as closed (non-locking version). + + virtual int cleanup_hint_i (const void *recycling_act); + // Cleanup hint. + + // = Helpers + void check_hint_i (SVC_HANDLER *&sh, + HASH_ADDRESS &search_addr, + CONNECTION_MAP_ENTRY *&entry, + int &found); + + int 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, + HASH_ADDRESS &search_addr, + CONNECTION_MAP_ENTRY *&entry, + int &found); + CONNECTION_MAP connection_cache_; // Table that maintains the cache of connected <SVC_HANDLER>s. diff --git a/ace/Strategies_T.i b/ace/Strategies_T.i index 026d3afc899..cdd1188ec5b 100644 --- a/ace/Strategies_T.i +++ b/ace/Strategies_T.i @@ -368,72 +368,43 @@ ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume (void) } template <class T> ASYS_INLINE -ACE_Recyclable<T>::ACE_Recyclable (void) - : recyclable_ (0), - t_ (T ()) +ACE_Refcounted_Hash_Recyclable<T>::ACE_Refcounted_Hash_Recyclable (void) + : ACE_Refcountable (0), + ACE_Hashable (), + ACE_Recyclable (ACE_Recyclable::UNKNOWN), + t_ () { } template <class T> ASYS_INLINE -ACE_Recyclable<T>::ACE_Recyclable (const T &t, int recyclable) - : recyclable_ (recyclable), +ACE_Refcounted_Hash_Recyclable<T>::ACE_Refcounted_Hash_Recyclable (const T &t, + int refcount, + ACE_Recyclable::State state) + : ACE_Refcountable (refcount), + ACE_Hashable (), + ACE_Recyclable (state), t_ (t) { } template <class T> ASYS_INLINE -ACE_Recyclable<T>::~ACE_Recyclable (void) -{ -} - -template <class T> ASYS_INLINE int -ACE_Recyclable<T>::operator== (const ACE_Recyclable<T> &rhs) const -{ - if (!this->recyclable ()) - return 0; - else - return this->t_ == rhs.t_; -} - -template <class T> ASYS_INLINE int -ACE_Recyclable<T>::recyclable (void) const -{ - return this->recyclable_; -} - -template <class T> ASYS_INLINE void -ACE_Recyclable<T>::recyclable (int new_value) -{ - this->recyclable_ = new_value; -} - -template <class T> ASYS_INLINE -ACE_Hash_Recyclable<T>::ACE_Hash_Recyclable (void) - : ACE_Recyclable<T> () -{ -} - -template <class T> ASYS_INLINE -ACE_Hash_Recyclable<T>::ACE_Hash_Recyclable (const T &t, int recyclable) - : ACE_Recyclable<T> (t, recyclable) -{ -} - -template <class T> ASYS_INLINE -ACE_Hash_Recyclable<T>::~ACE_Hash_Recyclable (void) +ACE_Refcounted_Hash_Recyclable<T>::~ACE_Refcounted_Hash_Recyclable (void) { } template <class T> ASYS_INLINE u_long -ACE_Hash_Recyclable<T>::hash (void) const +ACE_Refcounted_Hash_Recyclable<T>::hash (void) const { return this->t_.hash (); } -template <class T> ASYS_INLINE int -ACE_Hash_Recyclable<T>::operator== (const ACE_Recyclable<T> &rhs) const +template <class T> ASYS_INLINE int +ACE_Refcounted_Hash_Recyclable<T>::operator== (const ACE_Refcounted_Hash_Recyclable<T> &rhs) const { - return ACE_Recyclable<T>::operator== (rhs); + if (this->state () != ACE_Recyclable::IDLE) + return 0; + else + return this->t_ == rhs.t_; } template<class ADDR_T> ASYS_INLINE diff --git a/ace/Svc_Handler.cpp b/ace/Svc_Handler.cpp index 83a993b5bf7..7d7cc779d61 100644 --- a/ace/Svc_Handler.cpp +++ b/ace/Svc_Handler.cpp @@ -156,6 +156,17 @@ ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown (void) } template <PR_ST_1, ACE_SYNCH_DECL> void +ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::cleanup_hint (void) +{ + ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown"); + + // Remove as hint. + if (this->recycler ()) + this->recycler ()->cleanup_hint (this->recycling_act_); + +} + +template <PR_ST_1, ACE_SYNCH_DECL> void ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump (void) const { ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump"); diff --git a/ace/Svc_Handler.h b/ace/Svc_Handler.h index d04ca2db879..4bec5635ba8 100644 --- a/ace/Svc_Handler.h +++ b/ace/Svc_Handler.h @@ -61,6 +61,10 @@ public: // instead of closing it. If the object does not have a recycler, // it will be closed. + virtual void cleanup_hint (void); + // When the svc_handle is no longer needed around as a hint, call + // this method. + // = Dynamic linking hooks. virtual int init (int argc, ASYS_TCHAR *argv[]); // Default version does no work and returns -1. Must be overloaded diff --git a/tests/Conn_Test.cpp b/tests/Conn_Test.cpp index 9baa529c4b8..78b3fa74e36 100644 --- a/tests/Conn_Test.cpp +++ b/tests/Conn_Test.cpp @@ -697,29 +697,28 @@ main (int argc, ASYS_TCHAR *argv[]) return 0; } -#define HASH_ADDR ACE_Hash_Addr<ACE_INET_Addr> -#define RECYCLABLE_ADDR ACE_Recyclable<HASH_ADDR> -#define HASH_RECYCLABLE_ADDR ACE_Hash_Recyclable<HASH_ADDR> +#define CACHED_CONNECT_STRATEGY ACE_Cached_Connect_Strategy<Svc_Handler, ACE_SOCK_CONNECTOR, ACE_SYNCH_MUTEX> +#define HASH_ADDR CACHED_CONNECT_STRATEGY::HASH_ADDRESS +#define REFCOUNTED_HASH_RECYCLABLE_ADDR CACHED_CONNECT_STRATEGY::REFCOUNTED_HASH_RECYCLABLE_ADDRESS #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Cached_Connect_Strategy<Svc_Handler, ACE_SOCK_CONNECTOR, ACE_SYNCH_MUTEX>; +template class CACHED_CONNECT_STRATEGY; template class HASH_ADDR; -template class RECYCLABLE_ADDR; -template class HASH_RECYCLABLE_ADDR; +template class REFCOUNTED_HASH_RECYCLABLE_ADDR; template class ACE_NOOP_Creation_Strategy<Svc_Handler>; template class ACE_Concurrency_Strategy<Svc_Handler>; template class ACE_Connect_Strategy<Svc_Handler, ACE_SOCK_CONNECTOR>; template class ACE_Connector<Svc_Handler, ACE_SOCK_CONNECTOR>; template class ACE_Creation_Strategy<Svc_Handler>; -template class ACE_Hash_Map_Entry<HASH_RECYCLABLE_ADDR, Svc_Handler *>; -template class ACE_Hash_Map_Manager<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Base<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; -template class ACE_Hash_Map_Reverse_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; -template class ACE_Hash_Map_Manager<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator_Base<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Entry<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *>; +template class ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; template class ACE_LOCK_SOCK_Acceptor<ACCEPTOR_LOCKING>; template class ACE_Oneshot_Acceptor<Svc_Handler, LOCK_SOCK_ACCEPTOR>; template class ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *>; @@ -742,24 +741,23 @@ template class ACE_Unbounded_Queue<ACE_Thread_Descriptor*>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Cached_Connect_Strategy<Svc_Handler, ACE_SOCK_CONNECTOR, ACE_SYNCH_MUTEX> +#pragma instantiate CACHED_CONNECT_STRATEGY #pragma instantiate HASH_ADDR -#pragma instantiate RECYCLABLE_ADDR -#pragma instantiate HASH_RECYCLABLE_ADDR +#pragma instantiate REFCOUNTED_HASH_RECYCLABLE_ADDR #pragma instantiate ACE_NOOP_Creation_Strategy<Svc_Handler> #pragma instantiate ACE_Concurrency_Strategy<Svc_Handler> #pragma instantiate ACE_Connect_Strategy<Svc_Handler, ACE_SOCK_CONNECTOR> #pragma instantiate ACE_Connector<Svc_Handler, ACE_SOCK_CONNECTOR> #pragma instantiate ACE_Creation_Strategy<Svc_Handler> -#pragma instantiate ACE_Hash_Map_Entry<HASH_RECYCLABLE_ADDR, Svc_Handler *> -#pragma instantiate ACE_Hash_Map_Manager<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Iterator_Base<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Manager<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Base<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Entry<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *> +#pragma instantiate ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Manager<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator_Base<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> #pragma instantiate ACE_LOCK_SOCK_Acceptor<ACCEPTOR_LOCKING> #pragma instantiate ACE_Oneshot_Acceptor<Svc_Handler, LOCK_SOCK_ACCEPTOR> #pragma instantiate ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *> |