diff options
-rw-r--r-- | TAO/ChangeLog | 41 | ||||
-rw-r--r-- | TAO/tao/IIOP_Connector.cpp | 4 | ||||
-rw-r--r-- | TAO/tao/Invocation_Endpoint_Selectors.cpp | 4 | ||||
-rw-r--r-- | TAO/tao/Leader_Follower.cpp | 8 | ||||
-rw-r--r-- | TAO/tao/Profile_Transport_Resolver.h | 6 | ||||
-rw-r--r-- | TAO/tao/Profile_Transport_Resolver.inl | 2 | ||||
-rw-r--r-- | TAO/tao/Resource_Factory.h | 4 | ||||
-rw-r--r-- | TAO/tao/Thread_Lane_Resources.cpp | 12 | ||||
-rw-r--r-- | TAO/tao/Transport_Connector.cpp | 29 | ||||
-rw-r--r-- | TAO/tao/default_resource.cpp | 46 | ||||
-rw-r--r-- | TAO/tao/default_resource.h | 5 |
11 files changed, 129 insertions, 32 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index a8e5f2da0ed..0dcd4c646a7 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,44 @@ +Mon Mar 07 16:37:25 (IST) 2005 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Resource_Factory.h: + * tao/default_resource.cpp: + * tao/default_resource.h: + + Added a new strategy to decide whether the ORB should continue + to shutdown when waiting for outstanding replies. The name of + the resource factory option is "-ORBDropRepliesonShutdown", + which when on would drop replies when the ORB is shutting down + and wait for replies when turned off. + + * tao/Leader_Follower.cpp: + * tao/Thread_Lane_Resources.cpp: + + Use the above strategy to wakeup threads if they are waiting for + replies. + + * tao/Transport_Connector.cpp: + + Fixed a race condition and a subtle problem. If a thread waits + for connection completion, and if the ORB is shutdown (with the + strategy turned on), it is possible for the thread to exit the + LF without accepting the connection. This creates a problem when + the reactor is shutdown since there is a dangling reference to a + connection handler which might have been closed completely. To + get around this problem, we do a check to see if a connection + has been completed, and if not we clear the reactor of the + dangling reference. + + * tao/Profile_Transport_Resolver.h (blocked_connect): + * tao/Profile_Transport_Resolver.inl: + + Changed the method name to be blocked_connect () instead of + blocked (). + + * tao/IIOP_Connector.cpp: + * tao/Invocation_Endpoint_Selectors.cpp: + + Used blocked_connect () on Profile_Transport_Resolver. + Mon Mar 07 08:00:12 UTC 2005 Johnny Willemsen <jwillemsen@remedy.nl> * tests/Bug_1495_Regression/Client_Task.cpp: diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp index 367f636c3a5..34e19ce4ab4 100644 --- a/TAO/tao/IIOP_Connector.cpp +++ b/TAO/tao/IIOP_Connector.cpp @@ -158,7 +158,7 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, "to <%s:%d> which should %s\n", ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host()), iiop_endpoint->port(), - r->blocked () ? ACE_TEXT("block") : ACE_TEXT("nonblock"))); + r->blocked_connect () ? ACE_TEXT("block") : ACE_TEXT("nonblock"))); // Get the right synch options ACE_Synch_Options synch_options; @@ -169,7 +169,7 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, // If we don't need to block for a transport just set the timeout to // be zero. ACE_Time_Value tmp_zero (ACE_Time_Value::zero); - if (!r->blocked ()) + if (!r->blocked_connect ()) { synch_options.timeout (ACE_Time_Value::zero); timeout = &tmp_zero; diff --git a/TAO/tao/Invocation_Endpoint_Selectors.cpp b/TAO/tao/Invocation_Endpoint_Selectors.cpp index 01290c9cca3..0a31ce06b74 100644 --- a/TAO/tao/Invocation_Endpoint_Selectors.cpp +++ b/TAO/tao/Invocation_Endpoint_Selectors.cpp @@ -43,8 +43,8 @@ TAO_Default_Endpoint_Selector::select_endpoint ( // Check whether we need to do a blocked wait or we have a // non-blocked wait and we support that. If this is not the // case we can't use this profile so try the next. - if (r->blocked () || - (!r->blocked () && r->profile ()->supports_non_blocking_oneways ())) + if (r->blocked_connect () || + (!r->blocked_connect () && r->profile ()->supports_non_blocking_oneways ())) { const size_t endpoint_count = r->profile ()->endpoint_count (); diff --git a/TAO/tao/Leader_Follower.cpp b/TAO/tao/Leader_Follower.cpp index 7e2836f06d2..62988b8fbd2 100644 --- a/TAO/tao/Leader_Follower.cpp +++ b/TAO/tao/Leader_Follower.cpp @@ -148,7 +148,8 @@ TAO_Leader_Follower::set_client_thread (void) } if (this->clients_ == 0 && - this->orb_core_->has_shutdown ()) + this->orb_core_->has_shutdown () && + !this->orb_core_->resource_factory ()->drop_replies_during_shutdown ()) { // The ORB has shutdown and we are the first client after // that. This means that the reactor is disabled, we must @@ -171,7 +172,8 @@ TAO_Leader_Follower::reset_client_thread (void) } this->clients_--; - if (this->clients_ == 0 && this->orb_core_->has_shutdown ()) + if (this->clients_ == 0 && + this->orb_core_->has_shutdown ()) { // The ORB has shutdown and we are the last client thread, we // must stop the reactor to ensure that any server threads go @@ -441,7 +443,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, t_id), -1); - if (result == -1) + if (result == -1 && !this->reactor_->reactor_event_loop_done ()) ACE_ERROR_RETURN ((LM_ERROR, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " handle_events failed\n", diff --git a/TAO/tao/Profile_Transport_Resolver.h b/TAO/tao/Profile_Transport_Resolver.h index 131e85d8904..4c09b20d327 100644 --- a/TAO/tao/Profile_Transport_Resolver.h +++ b/TAO/tao/Profile_Transport_Resolver.h @@ -109,9 +109,9 @@ namespace TAO /// Accessor for the transport reserved for this invocation. TAO_Transport *transport (void) const; - /// Accessor to indicate whether we should deliver a connection - /// blocking for completed connections - bool blocked (void) const; + /// Accessor to indicate whether we should block while + /// establishing a connection. + bool blocked_connect (void) const; //@} /// Signal to let the resolver know that the transport has been diff --git a/TAO/tao/Profile_Transport_Resolver.inl b/TAO/tao/Profile_Transport_Resolver.inl index 250eceb9889..2f35fa34c5b 100644 --- a/TAO/tao/Profile_Transport_Resolver.inl +++ b/TAO/tao/Profile_Transport_Resolver.inl @@ -42,7 +42,7 @@ namespace TAO } ACE_INLINE bool - Profile_Transport_Resolver::blocked (void) const + Profile_Transport_Resolver::blocked_connect (void) const { return this->blocked_; } diff --git a/TAO/tao/Resource_Factory.h b/TAO/tao/Resource_Factory.h index 5d36035a520..d78937a555c 100644 --- a/TAO/tao/Resource_Factory.h +++ b/TAO/tao/Resource_Factory.h @@ -237,6 +237,10 @@ public: TAO_Resource_Factory::Resource_Usage resource_usage_strategy (void) const = 0; + /// Return the value of the strategy that indicates whether + /// the ORB should wait for the replies during shutdown or drop + /// replies during shutdown. + virtual bool drop_replies_during_shutdown () const = 0; protected: /** * Loads the default protocols. This method is used so that the diff --git a/TAO/tao/Thread_Lane_Resources.cpp b/TAO/tao/Thread_Lane_Resources.cpp index 2357bf457f7..6487ad8a3fa 100644 --- a/TAO/tao/Thread_Lane_Resources.cpp +++ b/TAO/tao/Thread_Lane_Resources.cpp @@ -499,15 +499,17 @@ TAO_Thread_Lane_Resources::shutdown_reactor (void) // load on the POA.... ACE_Reactor *reactor = leader_follower.reactor (); - reactor->wakeup_all_threads (); - // If there are some client threads running we have to wait until // they finish, when the last one does it will shutdown the reactor // for us. Meanwhile no new requests will be accepted because the // POA will not process them. - if (!leader_follower.has_clients ()) + if (!this->orb_core_.resource_factory ()->drop_replies_during_shutdown () && + leader_follower.has_clients ()) { - // Wake up all waiting threads in the reactor. - reactor->end_reactor_event_loop (); + reactor->wakeup_all_threads (); + return; } + + // Wake up all waiting threads in the reactor. + reactor->end_reactor_event_loop (); } diff --git a/TAO/tao/Transport_Connector.cpp b/TAO/tao/Transport_Connector.cpp index 9a2c55c9883..9116f3e32c5 100644 --- a/TAO/tao/Transport_Connector.cpp +++ b/TAO/tao/Transport_Connector.cpp @@ -354,7 +354,7 @@ TAO_Connector::wait_for_connection_completion ( // If we don't need to block for a transport just set the timeout to // be zero. ACE_Time_Value tmp_zero (ACE_Time_Value::zero); - if (!r->blocked ()) + if (!r->blocked_connect ()) { timeout = &tmp_zero; } @@ -381,7 +381,7 @@ TAO_Connector::wait_for_connection_completion ( if (result == -1) { - if (!r->blocked () && errno == ETIME) + if (!r->blocked_connect () && errno == ETIME) { // If we did a non blocking connect, just ignore // any timeout errors @@ -414,9 +414,28 @@ TAO_Connector::wait_for_connection_completion ( } } - // Connection not ready yet but we can use this transport, if - // we need a connected one we will block later to make sure - // it is connected + // Fix for a subtle problem. What happens if we are supposed to do + // blocked connect but the transport is NOT connected? Force close + // the connections + if (r->blocked_connect () && !transport->is_connected ()) + { + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Transport_Connector::" + "wait_for_connection_completion, " + "no connected transport for a blocked connection, " + "cancelling connections and reverting things \n")); + + // Forget the return value. We are busted anyway. Try our best + // here. + (void) this->cancel_svc_handler (transport->connection_handler ()); + transport = 0; + return false; + } + + // Connection may not ready for SYNC_NONE cases but we can use this + // transport, if we need a connected one we will block later to make + // sure it is connected return true; } diff --git a/TAO/tao/default_resource.cpp b/TAO/tao/default_resource.cpp index 9451a53d4bd..a2a79f16fdf 100644 --- a/TAO/tao/default_resource.cpp +++ b/TAO/tao/default_resource.cpp @@ -44,6 +44,7 @@ TAO_Default_Resource_Factory::TAO_Default_Resource_Factory (void) , flushing_strategy_type_ (TAO_LEADER_FOLLOWER_FLUSHING) , codeset_manager_ (0) , resource_usage_strategy_ (TAO_Resource_Factory::TAO_EAGER) + , drop_replies_ (true) { #if TAO_USE_LAZY_RESOURCE_USAGE_STRATEGY == 1 this->resource_usage_strategy_ = @@ -94,7 +95,7 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) int curarg = 0; for (curarg = 0; curarg < argc; ++curarg) - { + { // Parse thro' and find the number of Parsers to be loaded. if (ACE_OS::strcasecmp (argv[curarg], ACE_TEXT("-ORBIORParser")) == 0) @@ -102,6 +103,8 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) ++curarg; + + if (curarg == (argc-1) && this->parser_names_count_ != 0) { // This is the last loop.. @@ -119,16 +122,11 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) } for (curarg = 0; curarg < argc; ++curarg) - if (ACE_OS::strcasecmp (argv[curarg], - ACE_TEXT("-ORBResources")) == 0) - { - ++curarg; - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) This option has been deprecated \n"))); - } - - else if (ACE_OS::strcasecmp (argv[curarg], + { + ACE_DEBUG ((LM_DEBUG, + "The curr arg is [%s] \n", + argv[curarg])); + if (ACE_OS::strcasecmp (argv[curarg], ACE_TEXT("-ORBReactorMaskSignals")) == 0) { ++curarg; @@ -462,6 +460,25 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) this->report_option_value_error (ACE_TEXT("-ORBMuxedConnectionMax"), argv[curarg]); } + else if (ACE_OS::strcasecmp (argv[curarg], + ACE_LIB_TEXT("-ORBDropRepliesDuringShutdown")) == 0) + { + ACE_DEBUG ((LM_DEBUG, + "IN HERE \n")); + ++curarg; + if (curarg < argc) + { + int tmp = ACE_OS::atoi (argv[curarg]); + + if (tmp == 0) + this->drop_replies_ = false; + else + this->drop_replies_ = true; + } + else + this->report_option_value_error (ACE_LIB_TEXT("-ORBDropRepliesDuringShutdown"), + argv[curarg]); + } else if (ACE_OS::strncmp (argv[curarg], ACE_TEXT ("-ORB"), 4) == 0) @@ -480,6 +497,7 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) ACE_TEXT ("ignoring option <%s>\n"), argv[curarg])); } + } TAO_Codeset_Manager *csm = this->get_codeset_manager(); if (csm) @@ -1035,6 +1053,12 @@ TAO_Default_Resource_Factory::resource_usage_strategy (void) const return this->resource_usage_strategy_; } +bool +TAO_Default_Resource_Factory::drop_replies_during_shutdown (void) const +{ + return this->drop_replies_; +} + // **************************************************************** ACE_STATIC_SVC_DEFINE (TAO_Default_Resource_Factory, diff --git a/TAO/tao/default_resource.h b/TAO/tao/default_resource.h index 92b3b48ac72..417554b818f 100644 --- a/TAO/tao/default_resource.h +++ b/TAO/tao/default_resource.h @@ -138,6 +138,7 @@ public: virtual TAO_LF_Strategy *create_lf_strategy (void); virtual void disable_factory (void); + virtual bool drop_replies_during_shutdown (void) const; //@} protected: @@ -243,6 +244,10 @@ private: /// Resource usage strategy Resource_Usage resource_usage_strategy_; + + /// Flag to indicate whether replies should be dropped during ORB + /// shutdown. + bool drop_replies_; }; ACE_STATIC_SVC_DECLARE_EXPORT (TAO, TAO_Default_Resource_Factory) |