summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TAO/ChangeLog54
-rw-r--r--TAO/docs/Options.html23
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp11
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp11
-rw-r--r--TAO/tao/Acceptor_Impl.cpp7
-rw-r--r--TAO/tao/Connection_Handler.cpp37
-rw-r--r--TAO/tao/Connection_Handler.h5
-rw-r--r--TAO/tao/IIOP_Connection_Handler.cpp11
-rw-r--r--TAO/tao/ORB_Core.cpp1
-rw-r--r--TAO/tao/ORB_Core.h4
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.cpp11
-rw-r--r--TAO/tao/Strategies/SCIOP_Connection_Handler.cpp11
-rw-r--r--TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp11
-rw-r--r--TAO/tao/Strategies/UIOP_Connection_Handler.cpp11
-rw-r--r--TAO/tao/Transport.cpp1
-rw-r--r--TAO/tao/Transport.h26
-rw-r--r--TAO/tao/Transport.inl18
-rw-r--r--TAO/tao/Transport_Connector.cpp32
-rw-r--r--TAO/tao/Wait_On_LF_No_Upcall.cpp54
-rw-r--r--TAO/tao/Wait_On_LF_No_Upcall.h51
-rw-r--r--TAO/tao/default_client.cpp13
-rw-r--r--TAO/tao/default_client.h3
-rw-r--r--TAO/tao/tao.mpc1
23 files changed, 326 insertions, 81 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index ac0a6f7e3d9..df55ad5317c 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,57 @@
+Thu Aug 19 16:49:24 2004 Chris Cleeland <cleeland_c@ociweb.com>
+
+ * tao/Wait_On_LF_No_Upcall.h:
+ * tao/Wait_On_LF_No_Upcall.cpp:
+ * tao/tao.mpc:
+
+ Created new wait strategy that combines features of Wait_On_Read
+ and Wait_On_Leader_Follower. This strategy re-enters the
+ leader-follower, but does not permit nested upcalls on the
+ requesting thread while waiting for a reply. Other threads are
+ permitted to operate normally. The strategy was motivated by
+ the need to recognize connections opened in the client role and
+ closed by the far side. Using Wait_On_Read, the closure would
+ only be recognized the next time an invocation gets made that
+ goes through that connection. Notably in the notification
+ service, there is a _narrow() that causes an invocation on an
+ object, and that connection never gets reused. Thus, it sits in
+ CLOSE_WAIT consuming a file descriptor for the rest of the
+ process.
+
+ Implementing this required modifications to other files to
+ allocate and honor a flag set by this wait strategy.
+
+ * docs/Options.html:
+
+ Added documentation on the new wait strategy.
+
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp:
+ * orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connection_Handler.cpp:
+ * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp:
+ * tao/Strategies/DIOP_Connection_Handler.cpp:
+ * tao/Strategies/SCIOP_Connection_Handler.cpp:
+ * tao/Strategies/SHMIOP_Connection_Handler.cpp:
+ * tao/Strategies/UIOP_Connection_Handler.cpp:
+ * tao/Transport.h:
+ * tao/Transport.cpp:
+ * tao/Transport.inl:
+ * tao/Transport_Connector.cpp:
+ * tao/Connection_Handler.h:
+ * tao/Connection_Handler.inl:
+ * tao/ORB_Core.h:
+ * tao/ORB_Core.cpp:
+ * tao/Connection_Handler.cpp:
+ * tao/IIOP_Connection_Handler.cpp:
+ * tao/Acceptor_Impl.cpp:
+ * tao/default_client.cpp:
+ * tao/default_client.h:
+ * tao/Thread_Per_Connection_Handler.cpp:
+
+ Updated to cooperate with the new wait strategy. Note that some
+ refactoring in the Connection_Handler requires changes in any
+ pluggable transport's derived Connection_Handler in order to
+ participate in this wait strategy.
+
Thu Aug 19 01:54:51 2004 Ossama Othman <ossama@dre.vanderbilt.edu>
* orbsvcs/orbsvcs/SSLIOP/SSLIOP_OpenSSL_st_T.inl:
diff --git a/TAO/docs/Options.html b/TAO/docs/Options.html
index 45077a56964..35eb4462eb2 100644
--- a/TAO/docs/Options.html
+++ b/TAO/docs/Options.html
@@ -909,6 +909,11 @@ the ORB uses. The default reactor is the ACE_TP_Reactor.
<td><code>tp</code></td>
<td>Use the <code>ACE_TP_Reactor</code>, a select based
thread-pool reactor which is the
+ MT_NO_UPCALL means use a client connection handler that
+ participates in the leader-follower model like MT, but, like
+ RW, does not allow handling of nested upcalls within the
+ waiting thread.
+
default.</td>
</tr>
</tbody>
@@ -1168,7 +1173,11 @@ a null lock is used. This makes sense in case of optimizations and is
allowed when no forwarding is used or only a single threaded client. </td>
</tr>
<tr>
- <td><code>-ORBClientConnectionHandler</code> <em>MT | ST | RW</em></td>
+ <td><code>-ORBClientConnectionHandler</code> <em>MT | ST | RW
+ / MT_NOUPCALL</em><br>
+ <code>-ORBWaitStrategy</code> <em>MT / ST / RW / MT_NOUPCALL
+ </em>
+</td>
<td><a name="-ORBClientConnectionHandler"></a><em>ST</em> means
use the single-threaded client connection handler, i.e., the leader
follower model will not be used. However, <em>ST</em> does support
@@ -1189,6 +1198,18 @@ strategy will only effect two way calls, since there is no waiting for
one way calls. This strategy can also be used in an application that is
both a client and a server if the server side is handled by a separate
thread and the client threads are "pure" clients. </p>
+<p>
+ MT_NOUPCALL means use a client connection handler that
+ participates in the leader-follower model like MT, but, like
+ RW, does not allow handling of nested upcalls within the
+ waiting thread. Note that with this strategy it is possible
+ to "run out of threads" in a thread pool, and that TAO doesn't
+ grow thread pools. Unlike RW, this does not require <a
+ href="-ORBTransportMuxStrategy">-ORBTransportMuxStrategy&nbsp;<em>EXCLUSIVE</em></a>.
+<!--
+I'm not sure what the effect of AMI on this option is.
+-->
+</p>
<p>Default for this option is <em>MT</em>. </p>
</td>
</tr>
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp
index 42bd78c73ed..870c1dd57e4 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp
@@ -191,16 +191,7 @@ TAO_UIPMC_Connection_Handler::close_connection (void)
int
TAO_UIPMC_Connection_Handler::handle_input (ACE_HANDLE h)
{
- int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp
index 1d11ea6eb0d..980a4d6cf68 100644
--- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp
@@ -191,16 +191,7 @@ TAO::SSLIOP::Connection_Handler::close_connection (void)
int
TAO::SSLIOP::Connection_Handler::handle_input (ACE_HANDLE h)
{
- const int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/tao/Acceptor_Impl.cpp b/TAO/tao/Acceptor_Impl.cpp
index 3b9c88e9f32..3f00eeb0567 100644
--- a/TAO/tao/Acceptor_Impl.cpp
+++ b/TAO/tao/Acceptor_Impl.cpp
@@ -81,6 +81,13 @@ template <class SVC_HANDLER> int
TAO_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *sh,
void *arg)
{
+ sh->transport ()->opened_as (TAO_SERVER_ROLE);
+ // Indicate that this transport was opened in the server role
+ if (TAO_debug_level > 6)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) - TAO_Concurrency_Strategy::activate_svc_handler "
+ "opened as TAO_SERVER_ROLE\n"));
+
// Here the service handler has been created and the new connection
// has been accepted. #REFCOUNT# is one at this point.
diff --git a/TAO/tao/Connection_Handler.cpp b/TAO/tao/Connection_Handler.cpp
index 601d11ac066..c154e90456c 100644
--- a/TAO/tao/Connection_Handler.cpp
+++ b/TAO/tao/Connection_Handler.cpp
@@ -209,6 +209,43 @@ TAO_Connection_Handler::handle_output_eh (
int
TAO_Connection_Handler::handle_input_eh (
+ ACE_HANDLE h, ACE_Event_Handler *eh)
+{
+ if (this->transport ()->acts_as_server () &&
+ this->tss_resources_->upcalls_temporarily_suspended_on_this_thread_)
+ {
+#if 0 // DON'T IMPLEMENT YET, BUT RECORD THE IDEA FOR POSTERITY
+ // ACE_Time_Value this->spin_prevention_backoff_delay_;
+ ACE_OS::usleep (this->spin_prevention_backoff_delay_);
+ this->spin_prevention_backoff_delay_ = 2 * this->spin_prevention_backoff_delay_ + 1;
+#endif
+ if (TAO_debug_level > 6)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) Connection_Handler[%d] - not going to handle_input "
+ "on Transport %d "
+ "because upcalls temporarily suspended on this thread\n",
+ this->transport()->id(),
+ this->transport()->id()));
+ return 0;
+ }
+
+#if 0
+ this->spin_prevention_backoff_delay_ = 0;
+#endif
+
+ int result = this->handle_input_internal (h, eh);
+
+ if (result == -1)
+ {
+ this->close_connection ();
+ return 0;
+ }
+
+ return result;
+}
+
+int
+TAO_Connection_Handler::handle_input_internal (
ACE_HANDLE h, ACE_Event_Handler * eh)
{
// Let the transport know that it is used
diff --git a/TAO/tao/Connection_Handler.h b/TAO/tao/Connection_Handler.h
index 594eabe7831..357ea8ab768 100644
--- a/TAO/tao/Connection_Handler.h
+++ b/TAO/tao/Connection_Handler.h
@@ -125,7 +125,12 @@ protected:
int handle_output_eh (ACE_HANDLE h, ACE_Event_Handler * eh);
/// Implement the handle_input() callback
+ // We're actually going to pull the code from the protocol-specific
+ // handlers back into this class, because they ALL look exactly the same.
+ // If some other protocol comes along and needs to do something different,
+ // it is always free to override handle_input() as it sees fit.
int handle_input_eh (ACE_HANDLE h, ACE_Event_Handler * eh);
+ int handle_input_internal (ACE_HANDLE h, ACE_Event_Handler *eh);
/// Implement close_connection() for Connection_Handlers that are
/// also Event_Handlers.
diff --git a/TAO/tao/IIOP_Connection_Handler.cpp b/TAO/tao/IIOP_Connection_Handler.cpp
index 5e0137818a9..c48e62962c8 100644
--- a/TAO/tao/IIOP_Connection_Handler.cpp
+++ b/TAO/tao/IIOP_Connection_Handler.cpp
@@ -166,16 +166,7 @@ TAO_IIOP_Connection_Handler::close_connection (void)
int
TAO_IIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
- const int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp
index 7530bde6ff3..263868b0201 100644
--- a/TAO/tao/ORB_Core.cpp
+++ b/TAO/tao/ORB_Core.cpp
@@ -2828,6 +2828,7 @@ TAO_ORB_Core_TSS_Resources::TAO_ORB_Core_TSS_Resources (void)
, client_leader_thread_ (0)
, lane_ (0)
, ts_objects_ ()
+ , upcalls_temporarily_suspended_on_this_thread_ (false)
, orb_core_ (0)
#if TAO_HAS_INTERCEPTORS == 1
, pi_current_ ()
diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h
index ef2a06b711a..e6cdddce1d2 100644
--- a/TAO/tao/ORB_Core.h
+++ b/TAO/tao/ORB_Core.h
@@ -173,6 +173,10 @@ public:
/// Generic container for thread-specific objects.
ACE_Array_Base<void *> ts_objects_;
+ // Set to true by the wait_on_lf_no_nested_upcall wait strategy
+ // @CJC@ maybe we should use allocate_tss_slot_id() instead?
+ bool upcalls_temporarily_suspended_on_this_thread_;
+
/// Pointer to the ORB core. Needed to get access to the TSS
/// cleanup functions for the TSS objects stored in the TSS object
/// array in this class.
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
index ad27281fa83..8854b94696e 100644
--- a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
@@ -169,16 +169,7 @@ TAO_DIOP_Connection_Handler::close_connection (void)
int
TAO_DIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
- int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp b/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp
index ee482009578..60d586cef75 100644
--- a/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp
@@ -185,16 +185,7 @@ TAO_SCIOP_Connection_Handler::close_connection (void)
int
TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
- int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp b/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp
index 5752c058b8e..cc3a4ae8b9d 100644
--- a/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp
@@ -142,16 +142,7 @@ TAO_SHMIOP_Connection_Handler::close_connection (void)
int
TAO_SHMIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
- int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
index 190458548c4..f3ad70d0fcd 100644
--- a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
@@ -123,16 +123,7 @@ TAO_UIOP_Connection_Handler::close_connection (void)
int
TAO_UIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
- const int result =
- this->handle_input_eh (h, this);
-
- if (result == -1)
- {
- this->close_connection ();
- return 0;
- }
-
- return result;
+ return this->handle_input_eh (h, this);
}
int
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index 330ce4190ca..3d19bbbae1b 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -111,6 +111,7 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
, orb_core_ (orb_core)
, cache_map_entry_ (0)
, bidirectional_flag_ (-1)
+ , opening_connection_role_ (TAO_UNSPECIFIED_ROLE)
, head_ (0)
, tail_ (0)
, incoming_message_queue_ (orb_core)
diff --git a/TAO/tao/Transport.h b/TAO/tao/Transport.h
index 63011bbeb23..4c1ec16ccea 100644
--- a/TAO/tao/Transport.h
+++ b/TAO/tao/Transport.h
@@ -43,6 +43,13 @@ class TAO_Resume_Handle;
class TAO_Stub;
struct iovec;
+enum TAO_Connection_Role
+{
+ TAO_UNSPECIFIED_ROLE = 0,
+ TAO_SERVER_ROLE = 1,
+ TAO_CLIENT_ROLE = 2,
+};
+
/**
* @class TAO_Transport
*
@@ -277,6 +284,23 @@ public:
size_t id (void) const;
void id (size_t id);
+ /**
+ * Methods dealing with the role of the connection, e.g., CLIENT or SERVER.
+ * See CORBA 2.6 Specification, Section 15.5.1 for origin of definitions.
+ */
+ TAO_Connection_Role opened_as (void) const;
+ void opened_as (TAO_Connection_Role);
+
+ /**
+ * Predicate that returns true if it is valid for this transport to act in a server
+ * role. This would, for example, be true if opened_as() == TAO_SERVER_ROLE
+ * or bidirectional_flag() == 1.
+ *
+ * \return 0 cannot act in server role
+ * \return 1 can acts in server role
+ */
+ int acts_as_server (void) const;
+
/// Get and Set the purging order. The purging strategy uses the set
/// version to set the purging order.
unsigned long purging_order (void) const;
@@ -870,6 +894,8 @@ protected:
*/
int bidirectional_flag_;
+ TAO_Connection_Role opening_connection_role_;
+
/// Implement the outgoing data queue
TAO_Queued_Message *head_;
TAO_Queued_Message *tail_;
diff --git a/TAO/tao/Transport.inl b/TAO/tao/Transport.inl
index 68943732205..75c7f904846 100644
--- a/TAO/tao/Transport.inl
+++ b/TAO/tao/Transport.inl
@@ -38,6 +38,24 @@ TAO_Transport::bidirectional_flag (int flag)
this->bidirectional_flag_ = flag;
}
+ACE_INLINE TAO_Connection_Role
+TAO_Transport::opened_as () const
+{
+ return this->opening_connection_role_;
+}
+
+ACE_INLINE void
+TAO_Transport::opened_as (TAO_Connection_Role role)
+{
+ this->opening_connection_role_ = role;
+}
+
+ACE_INLINE int
+TAO_Transport::acts_as_server (void) const
+{
+ return (this->opened_as() == TAO_SERVER_ROLE || this->bidirectional_flag_ == 1) ? 1 : 0;
+}
+
ACE_INLINE TAO_Transport_Cache_Manager::HASH_MAP_ENTRY *
TAO_Transport::cache_map_entry (void)
{
diff --git a/TAO/tao/Transport_Connector.cpp b/TAO/tao/Transport_Connector.cpp
index b13f0af134e..5becf307ac9 100644
--- a/TAO/tao/Transport_Connector.cpp
+++ b/TAO/tao/Transport_Connector.cpp
@@ -239,17 +239,33 @@ TAO_Connector::connect (TAO::Profile_Transport_Resolver *r,
// Purge connections (if necessary)
tcm.purge ();
- return this->make_connection (r,
- *desc,
- timeout);
+ TAO_Transport* result = this->make_connection (r,
+ *desc,
+ timeout);
+ if (result == 0)
+ {
+ r->transport ()->opened_as (TAO_CLIENT_ROLE);
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Transport_Connector::connect, "
+ "opening Transport[%d] in TAO_CLIENT_ROLE\n",
+ r->transport ()->id ()));
+ }
+ return result;
}
if (TAO_debug_level > 4)
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Transport_Connector::connect, "
- "got an existing %s Transport[%d]\n",
- base_transport->is_connected () ? "connected" : "unconnected",
- base_transport->id ()));
+ {
+ TAO_Connection_Role cr = base_transport->opened_as ();
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Transport_Connector::connect, "
+ "got an existing %s Transport[%d] in role %s\n",
+ base_transport->is_connected () ? "connected" : "unconnected",
+ base_transport->id (),
+ cr == TAO_SERVER_ROLE ? "TAO_SERVER_ROLE" :
+ cr == TAO_CLIENT_ROLE ? "TAO_CLIENT_ROLE" :
+ "TAO_UNSPECIFIED_ROLE" ));
+ }
// If connected return..
if (base_transport->is_connected ())
diff --git a/TAO/tao/Wait_On_LF_No_Upcall.cpp b/TAO/tao/Wait_On_LF_No_Upcall.cpp
new file mode 100644
index 00000000000..67f79fa517f
--- /dev/null
+++ b/TAO/tao/Wait_On_LF_No_Upcall.cpp
@@ -0,0 +1,54 @@
+// $Id$
+
+#include "tao/Wait_On_LF_No_Upcall.h"
+
+#include "tao/Transport.h"
+#include "tao/ORB_Core.h"
+#include "debug.h"
+
+ACE_RCSID(tao, Wait_On_LF_No_Upcall, "$Id$")
+
+class TAO_Transport;
+
+class TAO_Nested_Upcall_Guard
+{
+public:
+ // Maybe we should instead just take in a ptr to
+ // TAO_ORB_Core_TSS_Resources? Or at least ORB_Core*?
+ TAO_Nested_Upcall_Guard (TAO_Transport* t) : t_(t)
+ {
+ t_->orb_core()->get_tss_resources()->upcalls_temporarily_suspended_on_this_thread_ = true;
+ if (TAO_debug_level > 6)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Wait_On_LF_No_Upcall::wait "
+ "disabling upcalls on thread %t\n"));
+ }
+
+ ~TAO_Nested_Upcall_Guard ()
+ {
+ t_->orb_core()->get_tss_resources()->upcalls_temporarily_suspended_on_this_thread_ = false;
+ if (TAO_debug_level > 6)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Wait_On_LF_No_Upcall::wait "
+ "re-enabling upcalls on thread %t\n"));
+ }
+
+private:
+ TAO_Nested_Upcall_Guard ();
+ TAO_Nested_Upcall_Guard (const TAO_Nested_Upcall_Guard&);
+
+ TAO_Transport* t_;
+};
+
+TAO_Wait_On_LF_No_Upcall::~TAO_Wait_On_LF_No_Upcall (void)
+{
+}
+
+int
+TAO_Wait_On_LF_No_Upcall::wait (ACE_Time_Value *max_wait_time,
+ TAO_Synch_Reply_Dispatcher &rd)
+{
+ TAO_Nested_Upcall_Guard upcall_guard(this->transport_);
+ return base::wait (max_wait_time, rd);
+}
+
diff --git a/TAO/tao/Wait_On_LF_No_Upcall.h b/TAO/tao/Wait_On_LF_No_Upcall.h
new file mode 100644
index 00000000000..8b9b40b0c99
--- /dev/null
+++ b/TAO/tao/Wait_On_LF_No_Upcall.h
@@ -0,0 +1,51 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Wait_On_LF_No_Upcall.h
+ *
+ * $Id$
+ *
+ * @author Chris Cleeland <cleeland@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_WAIT_ON_LF_NO_UPCALL_H
+#define TAO_WAIT_ON_LF_NO_UPCALL_H
+#include "ace/pre.h"
+
+#include "tao/Wait_On_Leader_Follower.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class TAO_Wait_On_LF_No_Upcall
+ *
+ * @brief Wait according to the Leader-Follower model (like
+ * TAO_Wait_On_Leader_Follower), but do not allow nested upcalls.
+ *
+ * This implementation sets a thread-specific flag on entering wait()
+ * that indicates that the thread is unavailable to service upcalls.
+ * Connection handler that are acting in a server role cooperate by
+ * checking this flag in their handle_input, and returning if they're
+ * in a thread that is currently suspending upcalls. The flag gets
+ * reset once the reply is received.
+ */
+
+class TAO_Export TAO_Wait_On_LF_No_Upcall : public TAO_Wait_On_Leader_Follower
+{
+public:
+ typedef TAO_Wait_On_Leader_Follower base;
+
+ TAO_Wait_On_LF_No_Upcall (TAO_Transport *t) : TAO_Wait_On_Leader_Follower (t) { }
+ virtual ~TAO_Wait_On_LF_No_Upcall (void);
+
+ virtual int wait (ACE_Time_Value *max_wait_time,
+ TAO_Synch_Reply_Dispatcher &rd);
+};
+
+#include "ace/post.h"
+#endif /* TAO_WAIT_ON_LF_NO_UPCALL_H */
diff --git a/TAO/tao/default_client.cpp b/TAO/tao/default_client.cpp
index 1dd4d84c1a7..97b905e3798 100644
--- a/TAO/tao/default_client.cpp
+++ b/TAO/tao/default_client.cpp
@@ -4,6 +4,7 @@
#include "Wait_On_Read.h"
#include "Wait_On_Reactor.h"
#include "Wait_On_Leader_Follower.h"
+#include "Wait_On_LF_No_Upcall.h"
#include "Exclusive_TMS.h"
#include "Muxed_TMS.h"
#include "Blocked_Connect_Strategy.h"
@@ -108,7 +109,10 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBClientConnectionHandler")) == 0)
+ ACE_LIB_TEXT("-ORBClientConnectionHandler")) == 0
+ ||
+ ACE_OS::strcasecmp (argv[curarg],
+ ACE_LIB_TEXT("-ORBWaitStrategy")) == 0)
{
curarg++;
if (curarg < argc)
@@ -124,6 +128,9 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
else if (ACE_OS::strcasecmp (name,
ACE_TEXT("RW")) == 0)
this->wait_strategy_ = TAO_WAIT_ON_READ;
+ else if (ACE_OS::strcasecmp (name,
+ ACE_LIB_TEXT("MT_NOUPCALL")) == 0)
+ this->wait_strategy_ = TAO_WAIT_ON_LF_NO_UPCALL;
else
this->report_option_value_error (ACE_TEXT("-ORBClientConnectionHandler"), name);
}
@@ -287,6 +294,10 @@ TAO_Default_Client_Strategy_Factory::create_wait_strategy (TAO_Transport *transp
ACE_NEW_RETURN (ws,
TAO_Wait_On_Reactor (transport),
0);
+ else if (this->wait_strategy_ == TAO_WAIT_ON_LF_NO_UPCALL)
+ ACE_NEW_RETURN (ws,
+ TAO_Wait_On_LF_No_Upcall (transport),
+ 0);
else
{
// = Leader follower model.
diff --git a/TAO/tao/default_client.h b/TAO/tao/default_client.h
index d1958ff4aeb..6dd566dd682 100644
--- a/TAO/tao/default_client.h
+++ b/TAO/tao/default_client.h
@@ -87,7 +87,8 @@ private:
{
TAO_WAIT_ON_LEADER_FOLLOWER,
TAO_WAIT_ON_REACTOR,
- TAO_WAIT_ON_READ
+ TAO_WAIT_ON_READ,
+ TAO_WAIT_ON_LF_NO_UPCALL
};
/// The wait-for-reply strategy.
diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc
index b97d53fe24f..44b4d265263 100644
--- a/TAO/tao/tao.mpc
+++ b/TAO/tao/tao.mpc
@@ -202,6 +202,7 @@ project(TAO) : acelib, taoversion, core, tao_output, taodefaults, pidl, extra_co
Wait_On_Read.cpp
Wait_On_Reactor.cpp
Wait_On_Leader_Follower.cpp
+ Wait_On_LF_No_Upcall.cpp
Transport_Mux_Strategy.cpp
Exclusive_TMS.cpp
Muxed_TMS.cpp