summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbala <balanatarajan@users.noreply.github.com>2002-11-12 18:49:19 +0000
committerbala <balanatarajan@users.noreply.github.com>2002-11-12 18:49:19 +0000
commitcc750e7f952a20c1c0604f4f60734cf3ed66699a (patch)
tree0cc3c26b5c6f6833ce11a7212d9165f1205f22d9
parentc5fd88734436fd8ce99508ea840fd419efb43102 (diff)
downloadATCD-cc750e7f952a20c1c0604f4f60734cf3ed66699a.tar.gz
ChangeLogTag: Tue Nov 12 12:47:31 2002 Balachandran Natarajan <bala@isis-server.isis.vanderbilt.edu>
-rw-r--r--TAO/ChangeLog43
-rw-r--r--TAO/tao/Connection_Handler.h23
-rw-r--r--TAO/tao/LF_CH_Event.cpp101
-rw-r--r--TAO/tao/LF_CH_Event.h92
-rw-r--r--TAO/tao/LF_Event.cpp90
-rw-r--r--TAO/tao/LF_Event.h51
-rw-r--r--TAO/tao/LF_Event.inl27
-rw-r--r--TAO/tao/LF_Invocation_Event.cpp93
-rw-r--r--TAO/tao/LF_Invocation_Event.h84
-rw-r--r--TAO/tao/LF_Invocation_Event.inl12
-rw-r--r--TAO/tao/Makefile.bor2
-rw-r--r--TAO/tao/Makefile.tao4
-rw-r--r--TAO/tao/Queued_Message.h4
-rw-r--r--TAO/tao/Synch_Reply_Dispatcher.h9
-rw-r--r--TAO/tao/Transport.cpp27
15 files changed, 518 insertions, 144 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index f59c0d0d83d..c8bff1c7700 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,46 @@
+Tue Nov 12 12:47:31 2002 Balachandran Natarajan <bala@isis-server.isis.vanderbilt.edu>
+
+ Fix for [BUG 1020]. Please see details of the bug at
+
+ http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=1020
+
+ Please see the discussions in the above URL for details on
+ the motivations for these changes. A very brief summary of the
+ changes alone are mentioned.
+
+ * tao/Transport.cpp(close_connection_shared): Wait on the
+ leader follower if the handle is registered with the
+ reactor.
+
+ * tao/LF_Event.h:
+ * tao/LF_Event.cpp:
+ * tao/LF_Event.inl: Made the class TAO_LF_Event as an abstract
+ base class. This helps us to strategize the type of
+ behaviour required in different concrete classes which can
+ in turn be used by other portions of the ORB to wait on LF.
+
+ * tao/LF_Invocation_Event.h:
+ * tao/LF_Invocation_Event.cpp:
+ * tao/LF_Invocation_Event.inl: Concrete implementation of a
+ LF_Event class, where the state transitions along the invocation
+ path are consolidated.
+
+ * tao/LF_CH_Event.h:
+ * tao/LF_CH_Event.cpp: Concrete implementation of a LF_Event
+ class, where the state transitions of the connection handler are
+ consolidated.
+
+ * tao/Queued_Message.h:
+ * tao/Synch_Reply_Dispatcher.h: They now inherit from
+ TAO_LF_Invocation_Event class.
+
+ * tao/Connection_Handler.h: This class inherits now from the
+ TAO_LF_CH_Event class.
+
+ * tao/Makefile.bor:
+ * tao/Makefile.tao: Added the new files to the list of compilable
+ files.
+
Tue Nov 12 12:37:18 2002 Pradeep Gore <pradeep@oomworks.com>
* orbsvcs/Logging_Service/Notify_Logging_Service/Makefile:
diff --git a/TAO/tao/Connection_Handler.h b/TAO/tao/Connection_Handler.h
index c72d1c92c6f..a54eeee6ae9 100644
--- a/TAO/tao/Connection_Handler.h
+++ b/TAO/tao/Connection_Handler.h
@@ -16,7 +16,7 @@
#include "ace/pre.h"
-#include "LF_Event.h"
+#include "LF_CH_Event.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -41,7 +41,7 @@ class ACE_Event_Handler;
* right protocol. This way, most of the common code for the
* different protocols would be in this implementation.
*/
-class TAO_Export TAO_Connection_Handler : public TAO_LF_Event
+class TAO_Export TAO_Connection_Handler : public TAO_LF_CH_Event
{
public:
@@ -104,15 +104,16 @@ protected:
/// Object.
int svc_i (void);
- /// Increment and decrement the number of upcalls that have gone
- /// through this handler. Returns the upcall count. The calls are
- /// thread safe..
- int incr_pending_upcalls (void);
-
- int decr_pending_upcalls (void);
-
- /// Query the upcall count
- int pending_upcalls (void) const;
+ /****
+ * Not sure where they are defined and used.. Looks legacy.
+ *
+ * Increment and decrement the number of upcalls that have gone
+ * this handler. Returns the upcall count. The calls are
+ * safe..
+ * int incr_pending_upcalls (void);
+ * int decr_pending_upcalls (void);
+ * int pending_upcalls (void) const;
+ */
//@{
/**
diff --git a/TAO/tao/LF_CH_Event.cpp b/TAO/tao/LF_CH_Event.cpp
new file mode 100644
index 00000000000..0597f99e582
--- /dev/null
+++ b/TAO/tao/LF_CH_Event.cpp
@@ -0,0 +1,101 @@
+#include "LF_CH_Event.h"
+#include "ace/Log_Msg.h"
+
+
+#if !defined (__ACE_INLINE__)
+# include "LF_CH_Event.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(tao,
+ LF_Invocation_Event,
+ "$Id$")
+
+TAO_LF_CH_Event::TAO_LF_CH_Event (void)
+ : TAO_LF_Event (),
+ prev_state_ (TAO_LF_Event::LFS_IDLE)
+
+{
+}
+
+TAO_LF_CH_Event::~TAO_LF_CH_Event (void)
+{
+}
+
+void
+TAO_LF_CH_Event::state_changed_i (int new_state)
+{
+ if (this->state_ == new_state)
+ return;
+
+ // Validate the state change
+ if (this->state_ == TAO_LF_Event::LFS_IDLE)
+ {
+ // From the LFS_IDLE state we can only become active.
+ if (new_state == TAO_LF_Event::LFS_CONNECTION_WAIT)
+ {
+ this->prev_state_ = this->state_;
+ this->state_ = new_state;
+ }
+ return;
+ }
+ else if (this->state_ == TAO_LF_Event::LFS_CONNECTION_WAIT)
+ {
+ // Only a few states are possible from CONNECTION_WAIT states
+ if (new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED
+ || new_state == TAO_LF_Event::LFS_SUCCESS)
+ {
+ this->prev_state_ = this->state_;
+ this->state_ = new_state;
+ }
+
+ return;
+ }
+ else if (this->state_ == TAO_LF_Event::LFS_SUCCESS)
+ {
+ if (new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED)
+ {
+ this->prev_state_ = this->state_;
+ this->state_ = new_state;
+ }
+ return;
+ }
+
+ return;
+}
+
+
+int
+TAO_LF_CH_Event::successful (void) const
+{
+ if (this->prev_state_ == TAO_LF_Event::LFS_CONNECTION_WAIT)
+ return this->state_ == TAO_LF_Event::LFS_SUCCESS;
+ else if (this->prev_state_ == TAO_LF_Event::LFS_SUCCESS)
+ return this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED;
+
+ return 0;
+}
+
+int
+TAO_LF_CH_Event::error_detected (void) const
+{
+ if (this->prev_state_ == TAO_LF_Event::LFS_CONNECTION_WAIT)
+ return this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED;
+ else if (this->prev_state_ == TAO_LF_Event::LFS_SUCCESS)
+ return (this->state_ != TAO_LF_Event::LFS_CONNECTION_CLOSED);
+
+ return 0;
+}
+
+void
+TAO_LF_CH_Event::set_state (int new_state)
+{
+ this->prev_state_ = this->state_;
+ this->state_ = new_state;
+}
+
+
+int
+TAO_LF_CH_Event::is_state_final (void)
+{
+ 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
new file mode 100644
index 00000000000..0ac940f66dc
--- /dev/null
+++ b/TAO/tao/LF_CH_Event.h
@@ -0,0 +1,92 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file LF_CH_Event.h
+ *
+ * $Id$
+ *
+ * @author Balachandran Natarajan <bala@cs.wustl.edu>
+ */
+//=============================================================================
+#ifndef TAO_LF_CH_EVENT_H
+#define TAO_LF_CH_EVENT_H
+#include "ace/pre.h"
+
+#include "LF_Event.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class TAO_LF_CH_Event
+ *
+ * @brief Use the Leader/Follower loop to wait for one specific event
+ * in the invocation path.
+ *
+ * Concrete event types and manipulation class which is used for
+ * connection handleing purposes.
+ */
+class TAO_Export TAO_LF_CH_Event: public TAO_LF_Event
+{
+public:
+ /// Constructor
+ TAO_LF_CH_Event (void);
+
+ /// Destructor
+ 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;
+ //@}
+
+ /// Reset the state, irrespective of the previous states
+ void reset_state (int new_state);
+
+
+private:
+ /// Validate and change the state
+ /*
+ * This concrete class uses the following states declared in the
+ * class TAO_LF_Event to transition states
+ *
+ * LFS_IDLE - The event is created, and is in initial
+ * state.
+ * LFS_CONNECTION_WAIT - The event is waiting for connection
+ * completion and it can transition to any of
+ * the following states, all the states are
+ * final.
+ * LFS_SUCCESS - The event, connection establishment, has
+ * completed successfully.
+ * LFS_TIMEOUT - The event has timed out.
+ * LFS_CONNECTION_CLOSED - The connection was closed since an error
+ * occured while trying to establish
+ * connection
+ *
+ */
+ virtual void state_changed_i (int new_state);
+
+ /// Check whether we have reached the final state..
+ virtual int is_state_final (void);
+
+ /// Set the state irrespective of anything.
+ virtual void set_state (int new_state);
+
+private:
+
+ /// The previous state that the LF_CH_Event was in
+ int prev_state_;
+};
+
+#if defined (__ACE_INLINE__)
+# include "LF_Invocation_Event.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/post.h"
+#endif /* TAO_LF_CH_EVENT_H */
diff --git a/TAO/tao/LF_Event.cpp b/TAO/tao/LF_Event.cpp
index a4b4a4bec94..c3f82d4cbee 100644
--- a/TAO/tao/LF_Event.cpp
+++ b/TAO/tao/LF_Event.cpp
@@ -1,9 +1,8 @@
// -*- C++ -*-
// $Id$
-
#include "tao/LF_Event.h"
-#include "tao/LF_Follower.h"
-#include "tao/Leader_Follower.h"
+#include "LF_Follower.h"
+#include "Leader_Follower.h"
#if !defined (__ACE_INLINE__)
# include "tao/LF_Event.inl"
@@ -35,91 +34,20 @@ TAO_LF_Event::state_changed (int new_state)
ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, leader_follower.lock ());
- if (is_state_final ()== 0 &&
- this->follower_ != 0)
+ if (this->is_state_final () == 0)
{
this->state_changed_i (new_state);
- this->follower_->signal ();
+ /// Sort of double-checked optimization..
+ if (this->follower_ != 0)
+ this->follower_->signal ();
}
}
}
-void
-TAO_LF_Event::state_changed_i (int new_state)
-{
- if (this->state_ == new_state)
- return;
- // Validate the state change
- if (this->state_ == TAO_LF_Event::LFS_IDLE)
- {
- // From the LFS_IDLE state we can only become active.
- if (new_state == TAO_LF_Event::LFS_ACTIVE
- || new_state == TAO_LF_Event::LFS_CONNECTION_WAIT
- || new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED)
- this->state_ = new_state;
- return;
- }
- else if (this->state_ == TAO_LF_Event::LFS_ACTIVE)
- {
- // From LFS_ACTIVE we can only move to a few states
- if (new_state != TAO_LF_Event::LFS_IDLE)
- {
- if (new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED)
- {
- this->state_ = TAO_LF_Event::LFS_FAILURE;
- }
- else
- {
- this->state_ = new_state;
- }
- }
- return;
- }
- else if (this->state_ == TAO_LF_Event::LFS_CONNECTION_WAIT)
- {
- // From LFS_CONNECTION_WAIT we can only move to a few states
- if (new_state != TAO_LF_Event::LFS_IDLE)
- {
- if (new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED)
- {
- this->state_ = TAO_LF_Event::LFS_FAILURE;
- }
- else
- {
- this->state_ = new_state;
- }
- }
- return;
- }
- else if (this->state_ == TAO_LF_Event::LFS_SUCCESS
- || this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED)
- {
- // From the two states above we can go back to ACTIVE, as when a
- // request is restarted.
- if (new_state == TAO_LF_Event::LFS_ACTIVE)
- {
- this->state_ = new_state;
- }
- return;
- }
- else /* if (this->state_ == TAO_LF_Event::LFS_TIMEOUT || FAILURE ) */
- {
- // Other states are final...
- }
-}
-
-int
-TAO_LF_Event::successful (void) const
-{
- return this->state_ == TAO_LF_Event::LFS_SUCCESS;
-}
-
-int
-TAO_LF_Event::error_detected (void) const
+void
+TAO_LF_Event::set_state (int new_state)
{
- return (this->state_ == TAO_LF_Event::LFS_FAILURE
- || this->state_ == TAO_LF_Event::LFS_TIMEOUT
- || this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED);
+ this->state_ = new_state;
}
diff --git a/TAO/tao/LF_Event.h b/TAO/tao/LF_Event.h
index ad1fe1c23ad..6dd77f6e23b 100644
--- a/TAO/tao/LF_Event.h
+++ b/TAO/tao/LF_Event.h
@@ -31,7 +31,7 @@ class TAO_LF_Follower;
* responses, as well as to wait for all the data to be flushed.
* This class encapsulates this event loop. It uses Template Method to
* parametrize the 'waited for' predicate (i.e. reply received or
- * message sent.)
+ * message sent or connection establishment etc.)
*
* @todo Implementing the Leader/Followers loop in this class, as
* well as the callbacks to communicate that an event has completed
@@ -71,19 +71,17 @@ public:
*
* A Leader/Followers event goes through several states during its
* lifetime. We use an enum to represent those states and state
- * changes are validated according to the rules below.
- *
+ * changes are validated according to the rules defined in the
+ * concrete classes. We treat the states as finite states in a
+ * FSM. The possible sequence of states through which the FSM
+ * migrates is defined in the concrete classes.
*/
enum {
- /// The event is created, initial state can only move to
- /// LFS_ACTIVE or LFS_CONNECTION_WAIT
- LFS_IDLE,
- /// The event is active, can change to any of the following
- /// states, each of them is a final state
+ /// The event is created, and is in initial state
+ LFS_IDLE = 0,
+ /// The event is active
LFS_ACTIVE,
- /// The event is waiting for connection completion. It can change
- /// to the any of the following states, each of them being a final
- /// state.
+ /// The event is waiting for connection completion.
LFS_CONNECTION_WAIT,
/// The event has completed successfully
LFS_SUCCESS,
@@ -91,45 +89,50 @@ public:
LFS_FAILURE,
/// The event has timed out
LFS_TIMEOUT,
- /// The connection was closed while the state was active
+ /// The connection was closed.
LFS_CONNECTION_CLOSED
};
- /// Change the state
+ /**
+ * Virtual methods for this class hierarchy..
+ */
+ /// Accessor to change the state. The state isnt changed unless
+ /// certain conditions are satisfied.
void state_changed (int new_state);
/// Return 1 if the condition was satisfied successfully, 0 if it
/// has not
- int successful (void) const;
+ virtual int successful (void) const = 0 ;
/// Return 1 if an error was detected while waiting for the
/// event
- int error_detected (void) const;
- //@}
+ virtual int error_detected (void) const = 0;
/// Check if we should keep waiting.
int keep_waiting (void);
+ //@}
/// Reset the state, irrespective of the previous states
void reset_state (int new_state);
protected:
- /// Validate the state change
- void state_changed_i (int new_state);
-private:
+ /// Validate the state change
+ virtual void state_changed_i (int new_state) = 0;
/// Check whether we have reached the final state..
- int is_state_final (void);
-
- /// Set the state.
- void set_state (int new_state);
+ virtual int is_state_final (void) = 0;
private:
+
+ /// Set the state irrespective of anything.
+ virtual void set_state (int new_state);
+
+protected:
/// The current state
int state_;
- /// The bound follower thread
+ /// The bounded follower
TAO_LF_Follower *follower_;
};
diff --git a/TAO/tao/LF_Event.inl b/TAO/tao/LF_Event.inl
index 2a62fcfb545..d6509c68430 100644
--- a/TAO/tao/LF_Event.inl
+++ b/TAO/tao/LF_Event.inl
@@ -1,11 +1,6 @@
+// -*- C++ -*-
// $Id$
-ACE_INLINE void
-TAO_LF_Event::reset_state (int new_state)
-{
- this->state_ = new_state;
-}
-
ACE_INLINE int
TAO_LF_Event::bind (TAO_LF_Follower *follower)
{
@@ -16,31 +11,21 @@ TAO_LF_Event::bind (TAO_LF_Follower *follower)
}
ACE_INLINE int
-TAO_LF_Event::is_state_final (void)
+TAO_LF_Event::unbind (void)
{
- if (this->state_ == TAO_LF_Event::LFS_TIMEOUT ||
- this->state_ == TAO_LF_Event::LFS_FAILURE)
- return 1;
-
+ if (this->follower_ == 0)
+ return -1;
+ this->follower_ = 0;
return 0;
}
ACE_INLINE void
-TAO_LF_Event::set_state (int new_state)
+TAO_LF_Event::reset_state (int new_state)
{
this->state_ = new_state;
}
ACE_INLINE int
-TAO_LF_Event::unbind (void)
-{
- if (this->follower_ == 0)
- return -1;
- this->follower_ = 0;
- return 0;
-}
-
-ACE_INLINE int
TAO_LF_Event::keep_waiting (void)
{
return (this->successful () == 0) && (this->error_detected () == 0);
diff --git a/TAO/tao/LF_Invocation_Event.cpp b/TAO/tao/LF_Invocation_Event.cpp
new file mode 100644
index 00000000000..4394098e2fb
--- /dev/null
+++ b/TAO/tao/LF_Invocation_Event.cpp
@@ -0,0 +1,93 @@
+// -*- C++ -*-
+#include "LF_Invocation_Event.h"
+
+
+#if !defined (__ACE_INLINE__)
+# include "tao/LF_Invocation_Event.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(tao,
+ LF_Invocation_Event,
+ "$Id$")
+
+TAO_LF_Invocation_Event::TAO_LF_Invocation_Event (void)
+ : TAO_LF_Event ()
+{
+}
+
+TAO_LF_Invocation_Event::~TAO_LF_Invocation_Event (void)
+{
+}
+
+void
+TAO_LF_Invocation_Event::state_changed_i (int new_state)
+{
+ if (this->state_ == new_state)
+ return;
+
+ // Validate the state change
+ if (this->state_ == TAO_LF_Event::LFS_IDLE)
+ {
+ // From the LFS_IDLE state we can only become active.
+ if (new_state == TAO_LF_Event::LFS_ACTIVE
+ || new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED)
+ this->state_ = new_state;
+ return;
+ }
+ else if (this->state_ == TAO_LF_Event::LFS_ACTIVE)
+ {
+ // From LFS_ACTIVE we can only move to a few states
+ if (new_state != TAO_LF_Event::LFS_IDLE)
+ {
+ if (new_state == TAO_LF_Event::LFS_CONNECTION_CLOSED)
+ {
+ this->state_ = TAO_LF_Event::LFS_FAILURE;
+ }
+ else
+ {
+ this->state_ = new_state;
+ }
+ }
+ return;
+ }
+ else if (this->state_ == TAO_LF_Event::LFS_SUCCESS
+ || this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED)
+ {
+ // From the two states above we can go back to ACTIVE, as when a
+ // request is restarted.
+ if (new_state == TAO_LF_Event::LFS_ACTIVE)
+ {
+ this->state_ = new_state;
+ }
+ return;
+ }
+ else/* if (this->state_ == TAO_LF_Event::LFS_TIMEOUT || FAILURE */
+ {
+ // Other states are final..
+ }
+
+}
+
+int
+TAO_LF_Invocation_Event::successful (void) const
+{
+ return this->state_ == TAO_LF_Event::LFS_SUCCESS;
+}
+
+int
+TAO_LF_Invocation_Event::error_detected (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)
+{
+ if (this->state_ == TAO_LF_Event::LFS_TIMEOUT ||
+ this->state_ == TAO_LF_Event::LFS_FAILURE)
+ return 1;
+
+ return 0;
+}
diff --git a/TAO/tao/LF_Invocation_Event.h b/TAO/tao/LF_Invocation_Event.h
new file mode 100644
index 00000000000..b85da5e31f0
--- /dev/null
+++ b/TAO/tao/LF_Invocation_Event.h
@@ -0,0 +1,84 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file LF_Invocation_Event.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan <coryan@uci.edu>
+ */
+//=============================================================================
+
+#ifndef TAO_LF_INVOCATION_EVENT_H
+#define TAO_LF_INVOCATION_EVENT_H
+#include "ace/pre.h"
+
+#include "LF_Event.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class TAO_LF_Invocation_Event
+ *
+ * @brief Use the Leader/Follower loop to wait for one specific event
+ * in the invocation path.
+ *
+ * Concrete event types and manipulation class through which the
+ * invocation data path would flow. Typically state changes of
+ * interest include whether a message has arrived, or timedout waiting
+ * for a message or if the cionnection is closed waiting for a
+ * message. Details of the states are documented within the class.
+ *
+ */
+class TAO_Export TAO_LF_Invocation_Event: public TAO_LF_Event
+{
+public:
+ /// Constructor
+ TAO_LF_Invocation_Event (void);
+
+ /// 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
+ /*
+ * This concrete class uses the following states declared in the
+ * class TAO_LF_Event
+ *
+ * LFS_IDLE - The event is created, and is in initial state.
+ * LFS_ACTIVE - The event is active and it can transition to any of
+ * the following states, all the states are final.
+ * LFS_SUCCESS - The event has completed successfully.
+ * LFS_FAILURE - A failure has been detected while the event was
+ * active.
+ * LFS_TIMEOUT - The event has timed out.
+ * LFS_CONNECTION_CLOSED - The connection was closed when the state
+ * was active.
+ *
+ */
+ virtual void state_changed_i (int new_state);
+
+private:
+ /// Check whether we have reached the final state..
+ int is_state_final (void);
+};
+
+#if defined (__ACE_INLINE__)
+# include "LF_Invocation_Event.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/post.h"
+#endif /* TAO_LF_INVOCATION_EVENT_H */
diff --git a/TAO/tao/LF_Invocation_Event.inl b/TAO/tao/LF_Invocation_Event.inl
new file mode 100644
index 00000000000..b364f0d845e
--- /dev/null
+++ b/TAO/tao/LF_Invocation_Event.inl
@@ -0,0 +1,12 @@
+// -*- C++ -*-
+// $Id$
+ACE_INLINE int
+TAO_LF_Event::is_state_final (void)
+{
+ if (this->state_ == TAO_LF_Event::LFS_TIMEOUT ||
+ this->state_ == TAO_LF_Event::LFS_FAILURE ||
+ this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED)
+ return 1;
+
+ return 0;
+}
diff --git a/TAO/tao/Makefile.bor b/TAO/tao/Makefile.bor
index b17397029c6..357d8b960bf 100644
--- a/TAO/tao/Makefile.bor
+++ b/TAO/tao/Makefile.bor
@@ -108,6 +108,8 @@ OBJFILES = \
$(OBJDIR)\Invocation.obj \
$(OBJDIR)\Invocation_Endpoint_Selectors.obj \
$(OBJDIR)\LF_Event.obj \
+ $(OBJDIR)\LF_Invocation_Event.obj \
+ $(OBJDIR)\LF_CH_Event.obj \
$(OBJDIR)\LF_Event_Binder.obj \
$(OBJDIR)\LF_Event_Loop_Thread_Helper.obj \
$(OBJDIR)\LF_Follower.obj \
diff --git a/TAO/tao/Makefile.tao b/TAO/tao/Makefile.tao
index c6072d607f5..f0f6c5db49e 100644
--- a/TAO/tao/Makefile.tao
+++ b/TAO/tao/Makefile.tao
@@ -42,6 +42,8 @@ PUB_HDRS = \
LF_Follower_Auto_Adder \
LF_Follower_Auto_Ptr \
LF_Event \
+ LF_Invocation_Event \
+ LF_CH_Event \
LF_Event_Binder \
LF_Event_Loop_Thread_Helper \
LF_Strategy \
@@ -206,6 +208,8 @@ ORB_CORE_FILES = \
Leader_Follower \
Leader_Follower_Flushing_Strategy \
LF_Event \
+ LF_Invocation_Event \
+ LF_CH_Event \
LF_Event_Binder \
LF_Event_Loop_Thread_Helper \
LF_Strategy \
diff --git a/TAO/tao/Queued_Message.h b/TAO/tao/Queued_Message.h
index 47a98735a4d..ece9491d047 100644
--- a/TAO/tao/Queued_Message.h
+++ b/TAO/tao/Queued_Message.h
@@ -20,7 +20,7 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "LF_Event.h"
+#include "LF_Invocation_Event.h"
class ACE_Message_Block;
class ACE_Allocator;
@@ -62,7 +62,7 @@ class ACE_Allocator;
* allocating the memory?
*
*/
-class TAO_Export TAO_Queued_Message : public TAO_LF_Event
+class TAO_Export TAO_Queued_Message : public TAO_LF_Invocation_Event
{
public:
/// Constructor
diff --git a/TAO/tao/Synch_Reply_Dispatcher.h b/TAO/tao/Synch_Reply_Dispatcher.h
index 8ca86c7057b..4094b0a0abb 100644
--- a/TAO/tao/Synch_Reply_Dispatcher.h
+++ b/TAO/tao/Synch_Reply_Dispatcher.h
@@ -20,14 +20,15 @@
#include "ace/pre.h"
#include "tao/Reply_Dispatcher.h"
-#include "tao/LF_Event.h"
-#include "tao/GIOP_Message_Version.h"
-#include "tao/CDR.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+#include "tao/LF_Invocation_Event.h"
+#include "tao/GIOP_Message_Version.h"
+#include "tao/CDR.h"
+
class TAO_Pluggable_Reply_Params;
/**
@@ -38,7 +39,7 @@ class TAO_Pluggable_Reply_Params;
*/
class TAO_Export TAO_Synch_Reply_Dispatcher
: public TAO_Reply_Dispatcher
- , public TAO_LF_Event
+ , public TAO_LF_Invocation_Event
{
public:
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index a6a0bc92830..50352209034 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -5,6 +5,7 @@
#include "Exception.h"
#include "ORB_Core.h"
+#include "Leader_Follower.h"
#include "Client_Strategy_Factory.h"
#include "Wait_Strategy.h"
#include "Transport_Mux_Strategy.h"
@@ -692,7 +693,31 @@ TAO_Transport::close_connection_shared (int disable_purge,
return;
}
- eh->close_connection ();
+
+ int retval = 0;
+
+ // The famous hack for 1020. We drive the Leader_Follower for
+ // a short period.
+ if (this->ws_->is_registered ())
+ {
+ // NOTE: This is a work around for BUG 1020. We drive the leader
+ // follower for a predetermined amount of time. Ideally this
+ // needs to be an ORB option. But this is just the first
+ // cut. Doing that will be a todo..
+
+ ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT, 0);
+ retval =
+ this->orb_core_->leader_follower ().wait_for_event (eh,
+ this,
+ &tv);
+ }
+
+ // We need to explicitly shut it down to avoid memory leaks.
+ if (retval == -1 ||
+ !this->ws_->is_registered ())
+ {
+ eh->close_connection ();
+ }
this->send_connection_closed_notifications ();