diff options
author | Johnny Willemsen <jwillemsen@users.noreply.github.com> | 2017-01-09 14:10:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-09 14:10:36 +0100 |
commit | 9c7f4df646c2b8f452fdfe6469563078b4952969 (patch) | |
tree | 43900925251a6ea7ae5b05abf27e957f42452812 | |
parent | 1141f2b612de8172750563436a9f618f333f94bf (diff) | |
parent | fca417408e738e43ea779d515ade0fbfa24fa777 (diff) | |
download | ATCD-9c7f4df646c2b8f452fdfe6469563078b4952969.tar.gz |
Merge pull request #349 from jwillemsen/jwi-lf-race
Fix possible race conditions with leader follower
25 files changed, 220 insertions, 165 deletions
diff --git a/ACE/include/makeinclude/platform_g++_common.GNU b/ACE/include/makeinclude/platform_g++_common.GNU index 430e8bebb58..a42e169a234 100644 --- a/ACE/include/makeinclude/platform_g++_common.GNU +++ b/ACE/include/makeinclude/platform_g++_common.GNU @@ -233,6 +233,12 @@ ifeq ($(address-sanitizer),1) LDFLAGS += -fsanitize=address endif +thread-sanitizer ?= 0 +ifeq ($(thread-sanitizer),1) + CPPFLAGS += -fsanitize=thread + LDFLAGS += -fsanitize=thread +endif + pipes ?= 1 FLAGS_C_CC += -Wall -W -Wpointer-arith diff --git a/TAO/docs/leader_follower.html b/TAO/docs/leader_follower.html index a5cddb813bd..f722cf12fd3 100644 --- a/TAO/docs/leader_follower.html +++ b/TAO/docs/leader_follower.html @@ -3,40 +3,40 @@ <head> <title>Implementation of leader follower model for global resources</title> </head> - + <BODY text = "#000000" link="#0000ff" vlink="#cc0000" bgcolor="#ffffff"> - + <body> <HR> <h1>Leader follower model for global resources</h1> <HR> <h2>Context</h2> Global resources in TAO mean one ORB and using the reactive strategy - one Reactor. TAO uses the ACE Select Reactor for this purpose. + one Reactor. TAO uses the ACE Select Reactor for this purpose. One main problem with multithreading and only one Reactor is that - only one thread can wait in handle_events at a time. + only one thread can wait in handle_events at a time. Handle_events is called, when a thread expects input, meaning it is blocking to wait for it. - + <h2>Idea</h2> One solution to this problem is to use a leader-follower model, which partitions the set of threads wanting to wait for input into one leader and followers. Every thread is eligible to become a leader. A thread wanting to wait while nobody else is waiting becomes the leader. If the leader gets its input, which is in - this case its response, it will select a new leader out of the + this case its response, it will select a new leader out of the set of followers. The followers wait on a condition variable they own and register it with the ORB core. The ORB core is thereby responsible for making this access thread-save by providing a lock for the list of followers with some flags, like leader_available. - + <h2>Implementation</h2> - The above mentioned condition variables are owned by the - connection handlers, because reponses are expected per connection, + The above mentioned condition variables are owned by the + connection handlers, because responses are expected per connection, not necessarily, thinking about other resource models, per thread. <p> The involved classes are TAO_ORB_Core, TAO_Client_Connection_Handler @@ -44,14 +44,14 @@ a leader reference counter and a leader thread ID were added. The handle_input and send_request methods on the TAO_Client_Connection_Handler contain 95% of the code used for implementing the leader-follower - model. Care has to be taken, that the connection handlers are + model. Care has to be taken, that the connection handlers are suspended and resumed, properly. A special concern is that - no deadlocking occurs. - + no deadlocking occurs. + <HR> For more details and questions, <p> - + <address><a href="mailto:mk1@cs.wustl.edu">Michael Kircher</a></address> <p> <address><a href="mailto:irfan1@cs.wustl.edu">Irfan Pyarali</a></address> diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp index f920fe33b4a..3029c05c3e5 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp @@ -191,7 +191,7 @@ TAO::IIOP_SSL_Connector::make_connection ( return 0; } - if (svc_handler->keep_waiting ()) + if (svc_handler->keep_waiting (this->orb_core ()->leader_follower ())) { svc_handler->connection_pending (); } diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp index 6b17c141510..eb6303b9b37 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp @@ -671,14 +671,16 @@ TAO::SSLIOP::Connector::ssliop_connect ( return 0; } + TAO_Leader_Follower &leader_follower = this->orb_core ()->leader_follower (); + // fix for bug 2654 - if (svc_handler->keep_waiting ()) + if (svc_handler->keep_waiting (leader_follower)) { svc_handler->connection_pending (); } // fix for bug 2654 - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); } @@ -732,7 +734,7 @@ TAO::SSLIOP::Connector::ssliop_connect ( } // fix for bug 2654 - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); transport->purge_entry(); diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp index 33b73629a3b..c40bf59940c 100644 --- a/TAO/tao/IIOP_Connector.cpp +++ b/TAO/tao/IIOP_Connector.cpp @@ -575,7 +575,9 @@ TAO_IIOP_Connector::complete_connection (int result, return 0; } - if (svc_handler->keep_waiting()) + TAO_Leader_Follower &leader_follower = this->orb_core ()->leader_follower (); + + if (svc_handler->keep_waiting(leader_follower)) { svc_handler->connection_pending(); } @@ -591,7 +593,7 @@ TAO_IIOP_Connector::complete_connection (int result, #endif // INDUCE_BUG_2654_B // Fix for bug 2654. - if (transport->connection_handler()->error_detected()) + if (transport->connection_handler()->error_detected(leader_follower)) { if (TAO_debug_level > 0) TAOLIB_DEBUG((LM_DEBUG, @@ -652,7 +654,7 @@ TAO_IIOP_Connector::complete_connection (int result, // before caching, the connection really failed, thus an invalid // connection is put into the cache. Thus we do one last status // check before handing the connection back to the caller. - if (svc_handler->error_detected()) + if (svc_handler->error_detected(leader_follower)) { if (TAO_debug_level > 0) TAOLIB_DEBUG((LM_DEBUG, diff --git a/TAO/tao/LF_CH_Event.cpp b/TAO/tao/LF_CH_Event.cpp index b00c7a59f29..ce68e95f94e 100644 --- a/TAO/tao/LF_CH_Event.cpp +++ b/TAO/tao/LF_CH_Event.cpp @@ -30,7 +30,7 @@ TAO_LF_CH_Event::unbind (TAO_LF_Follower *follower) } void -TAO_LF_CH_Event::state_changed_i (int new_state) +TAO_LF_CH_Event::state_changed_i (LFS_STATE new_state) { if (this->state_ != new_state) { @@ -64,7 +64,7 @@ TAO_LF_CH_Event::state_changed_i (int new_state) } void -TAO_LF_CH_Event::validate_state_change (int new_state) +TAO_LF_CH_Event::validate_state_change (LFS_STATE new_state) { if (this->state_ == TAO_LF_Event::LFS_IDLE) { @@ -109,8 +109,8 @@ TAO_LF_CH_Event::validate_state_change (int new_state) } -int -TAO_LF_CH_Event::successful (void) const +bool +TAO_LF_CH_Event::successful_i (void) const { if (this->prev_state_ == TAO_LF_Event::LFS_CONNECTION_WAIT) return this->state_ == TAO_LF_Event::LFS_SUCCESS; @@ -118,8 +118,8 @@ TAO_LF_CH_Event::successful (void) const return this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED; } -int -TAO_LF_CH_Event::error_detected (void) const +bool +TAO_LF_CH_Event::error_detected_i (void) const { if (this->prev_state_ == TAO_LF_Event::LFS_CONNECTION_WAIT) return this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED; @@ -128,10 +128,10 @@ TAO_LF_CH_Event::error_detected (void) const } void -TAO_LF_CH_Event::set_state (int new_state) +TAO_LF_CH_Event::set_state (LFS_STATE new_state) { // @@ NOTE: Is this still required? - if (this->is_state_final () == 0 + if (!this->is_state_final () && new_state == TAO_LF_Event::LFS_TIMEOUT) { this->state_ = new_state; @@ -150,8 +150,8 @@ TAO_LF_CH_Event::set_state (int new_state) } } -int -TAO_LF_CH_Event::is_state_final (void) +bool +TAO_LF_CH_Event::is_state_final (void) const { return this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED; } diff --git a/TAO/tao/LF_CH_Event.h b/TAO/tao/LF_CH_Event.h index ab3bdd0c5ba..cb22cd48325 100644 --- a/TAO/tao/LF_CH_Event.h +++ b/TAO/tao/LF_CH_Event.h @@ -55,18 +55,10 @@ public: virtual ~TAO_LF_CH_Event (void); //@{ - /// Return 1 if the condition was satisfied successfully, 0 if it - /// has not - int successful (void) const; - - /// Return 1 if an error was detected while waiting for the - /// event - int error_detected (void) const; - protected: /// Check whether we have reached the final state.. - virtual int is_state_final (void); + virtual bool is_state_final (void) const; //@} private: @@ -105,10 +97,18 @@ private: * Timeouts can occur while waiting for connections. * */ - virtual void state_changed_i (int new_state); + virtual void state_changed_i (LFS_STATE new_state); + + /// Return true if the condition was satisfied successfully, false if it + /// has not + virtual bool successful_i (void) const; + + /// Return true if an error was detected while waiting for the + /// event + virtual bool error_detected_i (void) const; /// Set the state irrespective of anything. - virtual void set_state (int new_state); + virtual void set_state (LFS_STATE new_state); virtual int bind (TAO_LF_Follower *follower); virtual int unbind (TAO_LF_Follower *follower); @@ -116,9 +116,9 @@ private: private: /// The previous state that the LF_CH_Event was in - int prev_state_; + LFS_STATE prev_state_; - void validate_state_change (int new_state); + void validate_state_change (LFS_STATE new_state); typedef ACE_Hash_Map_Manager_Ex <TAO_LF_Follower *, int, ACE_Hash<void *>, diff --git a/TAO/tao/LF_Connect_Strategy.cpp b/TAO/tao/LF_Connect_Strategy.cpp index 3f1ae449589..8bc6dce0c6c 100644 --- a/TAO/tao/LF_Connect_Strategy.cpp +++ b/TAO/tao/LF_Connect_Strategy.cpp @@ -52,7 +52,7 @@ TAO_LF_Connect_Strategy::wait_i (TAO_LF_Event *ev, int result = leader_follower.wait_for_event (ev, transport, max_wait_time); - if (ev->error_detected () && result != -1) + if (ev->error_detected (leader_follower) && result != -1) result = -1; return result; diff --git a/TAO/tao/LF_Event.cpp b/TAO/tao/LF_Event.cpp index ff281af1e98..16139aeb985 100644 --- a/TAO/tao/LF_Event.cpp +++ b/TAO/tao/LF_Event.cpp @@ -21,11 +21,11 @@ TAO_LF_Event::~TAO_LF_Event (void) } void -TAO_LF_Event::state_changed (int new_state, TAO_Leader_Follower &lf) +TAO_LF_Event::state_changed (LFS_STATE new_state, TAO_Leader_Follower &lf) { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, lf.lock ()); - if (this->is_state_final () == 0) + if (!this->is_state_final ()) { this->state_changed_i (new_state); @@ -35,8 +35,32 @@ TAO_LF_Event::state_changed (int new_state, TAO_Leader_Follower &lf) } } +bool +TAO_LF_Event::keep_waiting (TAO_Leader_Follower &lf) const +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, lf.lock (), false); + + return this->keep_waiting_i (); +} + +bool +TAO_LF_Event::successful (TAO_Leader_Follower &lf) const +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, lf.lock (), false); + + return this->successful_i (); +} + +bool +TAO_LF_Event::error_detected (TAO_Leader_Follower &lf) const +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, lf.lock (), true); + + return this->error_detected_i (); +} + void -TAO_LF_Event::set_state (int new_state) +TAO_LF_Event::set_state (LFS_STATE new_state) { this->state_ = new_state; } diff --git a/TAO/tao/LF_Event.h b/TAO/tao/LF_Event.h index c1000ba376a..edf42f8b361 100644 --- a/TAO/tao/LF_Event.h +++ b/TAO/tao/LF_Event.h @@ -82,7 +82,7 @@ public: * FSM. The possible sequence of states through which the FSM * migrates is defined in the concrete classes. */ - enum { + enum LFS_STATE { /// The event is created, and is in initial state LFS_IDLE = 0, /// The event is active @@ -99,46 +99,54 @@ public: LFS_CONNECTION_CLOSED }; - /** - * Virtual methods for this class hierarchy.. - */ /// Accessor to change the state. The state isn't changed unless /// certain conditions are satisfied. - void state_changed (int new_state, TAO_Leader_Follower &lf); + void state_changed (LFS_STATE new_state, TAO_Leader_Follower &lf); - /// Return 1 if the condition was satisfied successfully, 0 if it + /// Return true if the condition was satisfied successfully, false if it /// has not - virtual int successful (void) const = 0 ; + bool successful (TAO_Leader_Follower &lf) const; - /// Return 1 if an error was detected while waiting for the + /// Return true if an error was detected while waiting for the /// event - virtual int error_detected (void) const = 0; + bool error_detected (TAO_Leader_Follower &lf) const; /// Check if we should keep waiting. - int keep_waiting (void); + bool keep_waiting (TAO_Leader_Follower &lf) const; //@} /// Reset the state, irrespective of the previous states - void reset_state (int new_state); + void reset_state (LFS_STATE new_state); - static const char *state_name (int st); + static const char *state_name (LFS_STATE st); protected: /// Validate the state change - virtual void state_changed_i (int new_state) = 0; + virtual void state_changed_i (LFS_STATE new_state) = 0; + + /// Check if we should keep waiting. + bool keep_waiting_i (void) const; + + /// Return true if the condition was satisfied successfully, false if it + /// has not + virtual bool successful_i (void) const = 0 ; + + /// Return true if an error was detected while waiting for the + /// event + virtual bool error_detected_i (void) const = 0; /// Check whether we have reached the final state.. - virtual int is_state_final (void) = 0; + virtual bool is_state_final (void) const = 0; private: /// Set the state irrespective of anything. - virtual void set_state (int new_state); + virtual void set_state (LFS_STATE new_state); protected: /// The current state - int state_; + LFS_STATE state_; /// The bounded follower TAO_LF_Follower *follower_; diff --git a/TAO/tao/LF_Event.inl b/TAO/tao/LF_Event.inl index 66ca21934f6..dccfae380bb 100644 --- a/TAO/tao/LF_Event.inl +++ b/TAO/tao/LF_Event.inl @@ -20,19 +20,19 @@ TAO_LF_Event::unbind (TAO_LF_Follower *) } ACE_INLINE void -TAO_LF_Event::reset_state (int new_state) +TAO_LF_Event::reset_state (LFS_STATE new_state) { this->state_ = new_state; } -ACE_INLINE int -TAO_LF_Event::keep_waiting (void) +ACE_INLINE bool +TAO_LF_Event::keep_waiting_i (void) const { - return (this->successful () == 0) && (this->error_detected () == 0); + return (!this->successful_i ()) && (!this->error_detected_i ()); } ACE_INLINE const char * -TAO_LF_Event::state_name (int st) +TAO_LF_Event::state_name (LFS_STATE st) { #define TAO_LF_EVENT_ENTRY(X) case X: return #X switch (st) diff --git a/TAO/tao/LF_Invocation_Event.cpp b/TAO/tao/LF_Invocation_Event.cpp index f19ede1d259..16964032c5b 100644 --- a/TAO/tao/LF_Invocation_Event.cpp +++ b/TAO/tao/LF_Invocation_Event.cpp @@ -13,7 +13,7 @@ TAO_LF_Invocation_Event::~TAO_LF_Invocation_Event (void) } void -TAO_LF_Invocation_Event::state_changed_i (int new_state) +TAO_LF_Invocation_Event::state_changed_i (LFS_STATE new_state) { if (this->state_ == new_state) return; @@ -61,28 +61,28 @@ TAO_LF_Invocation_Event::state_changed_i (int new_state) } -int -TAO_LF_Invocation_Event::successful (void) const +bool +TAO_LF_Invocation_Event::successful_i (void) const { return this->state_ == TAO_LF_Event::LFS_SUCCESS; } -int -TAO_LF_Invocation_Event::error_detected (void) const +bool +TAO_LF_Invocation_Event::error_detected_i (void) const { return (this->state_ == TAO_LF_Event::LFS_FAILURE || this->state_ == TAO_LF_Event::LFS_TIMEOUT || this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED); } -int -TAO_LF_Invocation_Event::is_state_final (void) +bool +TAO_LF_Invocation_Event::is_state_final (void) const { if (this->state_ == TAO_LF_Event::LFS_TIMEOUT || this->state_ == TAO_LF_Event::LFS_FAILURE) - return 1; + return true; - return 0; + return false; } TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/LF_Invocation_Event.h b/TAO/tao/LF_Invocation_Event.h index 3ff6538ff3f..1e56a409c81 100644 --- a/TAO/tao/LF_Invocation_Event.h +++ b/TAO/tao/LF_Invocation_Event.h @@ -42,15 +42,6 @@ public: /// Destructor virtual ~TAO_LF_Invocation_Event (void); - /// Return 1 if the condition was satisfied successfully, 0 if it - /// has not - int successful (void) const; - - /// Return 1 if an error was detected while waiting for the - /// event - int error_detected (void) const; - //@} - protected: /// Validate and perform the state change @@ -68,11 +59,19 @@ protected: * LFS_CONNECTION_CLOSED - The connection was closed when the state * was active. */ - virtual void state_changed_i (int new_state); + virtual void state_changed_i (LFS_STATE new_state); + + /// Return true if the condition was satisfied successfully, false if it + /// has not + virtual bool successful_i (void) const; + + /// Return true if an error was detected while waiting for the + /// event + virtual bool error_detected_i (void) const; private: /// Check whether we have reached the final state.. - int is_state_final (void); + bool is_state_final (void) const; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/LF_Multi_Event.cpp b/TAO/tao/LF_Multi_Event.cpp index cfca3ecb36d..e2b6601a888 100644 --- a/TAO/tao/LF_Multi_Event.cpp +++ b/TAO/tao/LF_Multi_Event.cpp @@ -78,42 +78,48 @@ TAO_LF_Multi_Event::base_transport (void) return (this->events_ == 0) ? 0 : this->events_->ptr_->transport(); } -int -TAO_LF_Multi_Event::successful (void) const +bool +TAO_LF_Multi_Event::successful_i (void) const { for (Event_Node *n = this->events_; n != 0; n = n->next_) - if (n->ptr_->successful() == 1) + if (n->ptr_->successful_i()) { this->winner_ = n->ptr_; - return 1; + return true; } - return 0; + return false; } -int -TAO_LF_Multi_Event::error_detected (void) const +bool +TAO_LF_Multi_Event::error_detected_i (void) const { - int result = 1; for (Event_Node *n = this->events_; n != 0; n = n->next_) - if (n->ptr_->error_detected () == 0) - result = 0; - return result; + { + if (!n->ptr_->error_detected_i ()) + { + return false; + } + } + return true; } void -TAO_LF_Multi_Event::state_changed_i (int ) +TAO_LF_Multi_Event::state_changed_i (LFS_STATE ) { // no-op } -int -TAO_LF_Multi_Event::is_state_final (void) +bool +TAO_LF_Multi_Event::is_state_final (void) const { - int result = 1; for (Event_Node *n = this->events_; n != 0; n = n->next_) - if (n->ptr_->is_state_final () == 0) - result = 0; - return result; + { + if (!n->ptr_->is_state_final ()) + { + return false; + } + } + return true; } TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/LF_Multi_Event.h b/TAO/tao/LF_Multi_Event.h index fa08590da3f..5b01b37ac30 100644 --- a/TAO/tao/LF_Multi_Event.h +++ b/TAO/tao/LF_Multi_Event.h @@ -59,18 +59,6 @@ public: /// Returns the transport associated with the first entry in the collection. TAO_Transport *base_transport(void); - //@{ - /// Return 1 if the condition was satisfied successfully, 0 if it - /// has not - This iterates over the list of attached events and - /// returns 1 if any of them return 1 from successful. - int successful (void) const; - - /// Return 1 if an error was detected while waiting for the - /// event - This iterates over the list of events and returns - /// 1 only if all of them return 1 from error_detected(). - int error_detected (void) const; - - //@} private: void operator= (const TAO_LF_Multi_Event &); TAO_LF_Multi_Event (const TAO_LF_Multi_Event &); @@ -78,10 +66,20 @@ private: protected: /// Validate the state change - virtual void state_changed_i (int new_state); + virtual void state_changed_i (LFS_STATE new_state); /// Check whether we have reached the final state.. - virtual int is_state_final (void); + virtual bool is_state_final (void) const; + + /// Return true if the condition was satisfied successfully, false if it + /// has not - This iterates over the list of attached events and + /// returns true if any of them return true from successful. + virtual bool successful_i (void) const; + + /// Return true if an error was detected while waiting for the + /// event - This iterates over the list of events and returns + /// true only if all of them return true from error_detected(). + virtual bool error_detected_i (void) const; private: @@ -93,7 +91,6 @@ private: struct Event_Node *events_; mutable TAO_Connection_Handler * winner_; - }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/Leader_Follower.cpp b/TAO/tao/Leader_Follower.cpp index 18c3fe60b57..62b3527edd8 100644 --- a/TAO/tao/Leader_Follower.cpp +++ b/TAO/tao/Leader_Follower.cpp @@ -281,7 +281,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // still not completed (and we haven't run out of time). // All the conditions below are basically the various ways the // leader loop below can end, other than the event being complete - while (event->keep_waiting () + while (event->keep_waiting_i () && !(result == 0 && max_wait_time != 0 && *max_wait_time == ACE_Time_Value::zero) @@ -309,7 +309,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // get a signal when the event terminates TAO_LF_Event_Binder event_binder (event, follower.get ()); - while (event->keep_waiting () && + while (event->keep_waiting_i () && this->leader_available ()) { // Scope #4: this loop handles spurious wake-ups // Add ourselves to the list, do it everytime we wake up @@ -374,7 +374,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // We have timedout event->set_state (TAO_LF_Event::LFS_TIMEOUT); - if (!event->successful ()) + if (!event->successful_i ()) { // Remove follower can fail because either // 1) the condition was satisfied (i.e. reply @@ -420,15 +420,15 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") ACE_TEXT (" done (follower), successful %d\n"), t_id, - event->successful ())); + event->successful_i ())); // Now somebody woke us up to become a leader or to handle our // input. We are already removed from the follower queue. - if (event->successful ()) + if (event->successful_i ()) return 0; - if (event->error_detected ()) + if (event->error_detected_i ()) return -1; // FALLTHROUGH @@ -499,7 +499,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // If we got our event, no need to run the event loop any // further. - while (event->keep_waiting ()) + while (event->keep_waiting_i ()) { // Run the event loop. result = reactor->handle_events (max_wait_time); @@ -602,13 +602,13 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // Return an error if there was a problem receiving the reply... if (max_wait_time != 0) { - if (!event->successful () + if (!event->successful_i () && *max_wait_time == ACE_Time_Value::zero) { result = -1; errno = ETIME; } - else if (event->error_detected ()) + else if (event->error_detected_i ()) { // If the time did not expire yet, but we get a failure, // e.g. the connections closed, we should still return an error. @@ -624,7 +624,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, * clients. * result = 0; */ - if (event->error_detected ()) + if (event->error_detected_i ()) { result = -1; } diff --git a/TAO/tao/Leader_Follower.h b/TAO/tao/Leader_Follower.h index a48b821082e..053c2d3f9e2 100644 --- a/TAO/tao/Leader_Follower.h +++ b/TAO/tao/Leader_Follower.h @@ -182,7 +182,7 @@ public: /// Check if there are any client threads running bool has_clients (void) const; - /// Accesor to the reactor + /// Accessor to the reactor ACE_Reactor *reactor (void); /// Called when we are out of leaders. @@ -191,7 +191,7 @@ public: /// Set the new leader generator. void set_new_leader_generator(TAO_New_Leader_Generator *new_leader_generator); - /// Method to support deffering an event till later (f.i. in + /// Method to support deferring an event till later (f.i. in /// cases where transport()->wait_strategy()->can_process_upcalls() /// returns false). int defer_event (ACE_Event_Handler*); diff --git a/TAO/tao/Reactive_Connect_Strategy.cpp b/TAO/tao/Reactive_Connect_Strategy.cpp index 9af1d96c729..db4e03fc623 100644 --- a/TAO/tao/Reactive_Connect_Strategy.cpp +++ b/TAO/tao/Reactive_Connect_Strategy.cpp @@ -55,9 +55,11 @@ TAO_Reactive_Connect_Strategy::wait_i (TAO_LF_Event *ev, //FUZZ: enable check_for_lack_ACE_OS } + TAO_Leader_Follower &leader_follower = this->orb_core_->leader_follower (); + try { - while (ev->keep_waiting ()) + while (ev->keep_waiting (leader_follower)) { result = this->orb_core_->run (max_wait_time, 1); @@ -83,7 +85,7 @@ TAO_Reactive_Connect_Strategy::wait_i (TAO_LF_Event *ev, } // Set the result. - if (result != -1 && ev->error_detected ()) + if (result != -1 && ev->error_detected (leader_follower)) { result = -1; } diff --git a/TAO/tao/Strategies/SCIOP_Connector.cpp b/TAO/tao/Strategies/SCIOP_Connector.cpp index 3f88e558447..75a0bd4d946 100644 --- a/TAO/tao/Strategies/SCIOP_Connector.cpp +++ b/TAO/tao/Strategies/SCIOP_Connector.cpp @@ -236,12 +236,14 @@ TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r, return 0; } - if (svc_handler->keep_waiting ()) + TAO_Leader_Follower &leader_follower = this->orb_core ()->leader_follower (); + + if (svc_handler->keep_waiting (leader_follower)) { svc_handler->connection_pending (); } - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); return 0; @@ -278,7 +280,7 @@ TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r, return 0; } - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower) { svc_handler->cancel_pending_connection (); transport->purge_entry(); diff --git a/TAO/tao/Strategies/SHMIOP_Connector.cpp b/TAO/tao/Strategies/SHMIOP_Connector.cpp index 2f5e4e426be..bcf909b54ee 100644 --- a/TAO/tao/Strategies/SHMIOP_Connector.cpp +++ b/TAO/tao/Strategies/SHMIOP_Connector.cpp @@ -173,18 +173,19 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, return 0; } - if (svc_handler->keep_waiting ()) + TAO_Leader_Follower &leader_follower = this->orb_core ()->leader_follower (); + + if (svc_handler->keep_waiting (leader_follower)) { svc_handler->connection_pending (); } - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); } - TAO_Transport *transport = - svc_handler->transport (); + TAO_Transport *transport = svc_handler->transport (); // At this point, the connection has be successfully connected. // #REFCOUNT# is one. @@ -218,7 +219,7 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, return 0; } - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); transport->purge_entry(); diff --git a/TAO/tao/Strategies/UIOP_Connector.cpp b/TAO/tao/Strategies/UIOP_Connector.cpp index 3b9e56f6067..1d739ccd8c8 100644 --- a/TAO/tao/Strategies/UIOP_Connector.cpp +++ b/TAO/tao/Strategies/UIOP_Connector.cpp @@ -210,12 +210,14 @@ TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, return 0; } - if (svc_handler->keep_waiting ()) + TAO_Leader_Follower &leader_follower = this->orb_core ()->leader_follower (); + + if (svc_handler->keep_waiting (leader_follower)) { svc_handler->connection_pending (); } - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); } @@ -250,7 +252,7 @@ TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, return 0; } - if (svc_handler->error_detected ()) + if (svc_handler->error_detected (leader_follower)) { svc_handler->cancel_pending_connection (); transport->purge_entry(); diff --git a/TAO/tao/Transport_Connector.cpp b/TAO/tao/Transport_Connector.cpp index 9ea721d8789..e6f2bdfeca3 100644 --- a/TAO/tao/Transport_Connector.cpp +++ b/TAO/tao/Transport_Connector.cpp @@ -502,7 +502,7 @@ TAO_Connector::connect (TAO::Profile_Transport_Resolver *r, { TAO_Connection_Handler *ch = base_transport->connection_handler (); // one last check before using the cached connection - if (ch->error_detected ()) + if (ch->error_detected (this->orb_core ()->leader_follower ())) { if (TAO_debug_level > 0) { diff --git a/TAO/tao/Wait_On_Reactor.cpp b/TAO/tao/Wait_On_Reactor.cpp index a36cadfa796..7232bf64838 100644 --- a/TAO/tao/Wait_On_Reactor.cpp +++ b/TAO/tao/Wait_On_Reactor.cpp @@ -29,6 +29,9 @@ TAO_Wait_On_Reactor::wait (ACE_Time_Value *max_wait_time, ACE_Reactor *const reactor = this->transport_->orb_core ()->reactor (); + TAO_Leader_Follower &leader_follower = + this->transport_->orb_core ()->leader_follower (); + // Do the event loop, till we fully receive a reply. int result = 0; @@ -39,7 +42,7 @@ TAO_Wait_On_Reactor::wait (ACE_Time_Value *max_wait_time, // If we got our reply, no need to run the event loop any // further. - if (!rd.keep_waiting ()) + if (!rd.keep_waiting (leader_follower)) { break; } @@ -61,7 +64,7 @@ TAO_Wait_On_Reactor::wait (ACE_Time_Value *max_wait_time, // Otherwise, keep going... } - if (result == -1 || rd.error_detected ()) + if (result == -1 || rd.error_detected (leader_follower)) { return -1; } @@ -69,7 +72,7 @@ TAO_Wait_On_Reactor::wait (ACE_Time_Value *max_wait_time, // Return an error if there was a problem receiving the reply. if (max_wait_time != 0) { - if (rd.successful () && *max_wait_time == ACE_Time_Value::zero) + if (rd.successful (leader_follower) && *max_wait_time == ACE_Time_Value::zero) { result = -1; errno = ETIME; @@ -79,7 +82,7 @@ TAO_Wait_On_Reactor::wait (ACE_Time_Value *max_wait_time, { result = 0; - if (rd.error_detected ()) + if (rd.error_detected (leader_follower)) { result = -1; } diff --git a/TAO/tao/Wait_On_Read.cpp b/TAO/tao/Wait_On_Read.cpp index 43176403909..f2cc92134e3 100644 --- a/TAO/tao/Wait_On_Read.cpp +++ b/TAO/tao/Wait_On_Read.cpp @@ -81,8 +81,10 @@ TAO_Wait_On_Read::wait (ACE_Time_Value * max_wait_time, // method. TAO::ORB_Countdown_Time countdown (max_wait_time); - rd.state_changed (TAO_LF_Event::LFS_ACTIVE, - this->transport_->orb_core ()->leader_follower ()); + TAO_Leader_Follower &leader_follower = + this->transport_->orb_core ()->leader_follower (); + + rd.state_changed (TAO_LF_Event::LFS_ACTIVE, leader_follower); // Do the same sort of looping that is done in other wait // strategies. @@ -94,7 +96,7 @@ TAO_Wait_On_Read::wait (ACE_Time_Value * max_wait_time, // If we got our reply, no need to run the loop any // further. - if (!rd.keep_waiting ()) + if (!rd.keep_waiting (leader_follower)) break; // @@ We are not checking for timeouts here... @@ -104,12 +106,12 @@ TAO_Wait_On_Read::wait (ACE_Time_Value * max_wait_time, break; } - if (rd.error_detected () == -1 || retval == -1) + if (rd.error_detected (leader_follower) || retval == -1) { this->transport_->close_connection (); } - if (rd.successful ()) + if (rd.successful (leader_follower)) { TAO_ORB_Core * const oc = this->transport_->orb_core (); @@ -147,7 +149,7 @@ TAO_Wait_On_Read::wait (ACE_Time_Value * max_wait_time, return 0; } - if (rd.error_detected ()) + if (rd.error_detected (leader_follower)) return -1; return 1; diff --git a/TAO/tests/Bug_3531b_Regression/server.cpp b/TAO/tests/Bug_3531b_Regression/server.cpp index c687e3b5735..93fdf3555f6 100644 --- a/TAO/tests/Bug_3531b_Regression/server.cpp +++ b/TAO/tests/Bug_3531b_Regression/server.cpp @@ -251,30 +251,29 @@ public: this->state_changed (TAO_LF_Event::LFS_SUCCESS, lf); } - virtual int successful (void) const +protected: + virtual bool successful_i (void) const { return this->state_ == TAO_LF_Event::LFS_SUCCESS; } - virtual int error_detected (void) const + virtual bool error_detected_i (void) const { return (this->state_ == TAO_LF_Event::LFS_FAILURE || this->state_ == TAO_LF_Event::LFS_TIMEOUT || this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED); } -protected: - virtual void state_changed_i (int new_state) + virtual void state_changed_i (LFS_STATE new_state) { this->state_ = new_state; - return; } - virtual int is_state_final (void) + virtual bool is_state_final (void) const { if (this->state_ == TAO_LF_Event::LFS_TIMEOUT || this->state_ == TAO_LF_Event::LFS_FAILURE) - return 1; - return 0; + return true; + return false; } }; |