summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Willemsen <jwillemsen@users.noreply.github.com>2017-01-09 14:10:36 +0100
committerGitHub <noreply@github.com>2017-01-09 14:10:36 +0100
commit9c7f4df646c2b8f452fdfe6469563078b4952969 (patch)
tree43900925251a6ea7ae5b05abf27e957f42452812
parent1141f2b612de8172750563436a9f618f333f94bf (diff)
parentfca417408e738e43ea779d515ade0fbfa24fa777 (diff)
downloadATCD-9c7f4df646c2b8f452fdfe6469563078b4952969.tar.gz
Merge pull request #349 from jwillemsen/jwi-lf-race
Fix possible race conditions with leader follower
-rw-r--r--ACE/include/makeinclude/platform_g++_common.GNU6
-rw-r--r--TAO/docs/leader_follower.html26
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp8
-rw-r--r--TAO/tao/IIOP_Connector.cpp8
-rw-r--r--TAO/tao/LF_CH_Event.cpp20
-rw-r--r--TAO/tao/LF_CH_Event.h26
-rw-r--r--TAO/tao/LF_Connect_Strategy.cpp2
-rw-r--r--TAO/tao/LF_Event.cpp30
-rw-r--r--TAO/tao/LF_Event.h40
-rw-r--r--TAO/tao/LF_Event.inl10
-rw-r--r--TAO/tao/LF_Invocation_Event.cpp18
-rw-r--r--TAO/tao/LF_Invocation_Event.h21
-rw-r--r--TAO/tao/LF_Multi_Event.cpp42
-rw-r--r--TAO/tao/LF_Multi_Event.h27
-rw-r--r--TAO/tao/Leader_Follower.cpp20
-rw-r--r--TAO/tao/Leader_Follower.h4
-rw-r--r--TAO/tao/Reactive_Connect_Strategy.cpp6
-rw-r--r--TAO/tao/Strategies/SCIOP_Connector.cpp8
-rw-r--r--TAO/tao/Strategies/SHMIOP_Connector.cpp11
-rw-r--r--TAO/tao/Strategies/UIOP_Connector.cpp8
-rw-r--r--TAO/tao/Transport_Connector.cpp2
-rw-r--r--TAO/tao/Wait_On_Reactor.cpp11
-rw-r--r--TAO/tao/Wait_On_Read.cpp14
-rw-r--r--TAO/tests/Bug_3531b_Regression/server.cpp15
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;
}
};