summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TAO/ChangeLog65
-rw-r--r--TAO/tao/Asynch_Reply_Dispatcher_Base.cpp66
-rw-r--r--TAO/tao/Asynch_Reply_Dispatcher_Base.h92
-rw-r--r--TAO/tao/Asynch_Reply_Dispatcher_Base.i13
-rw-r--r--TAO/tao/Auto_Functor.cpp (renamed from TAO/tao/Utils/Auto_Functor.cpp)0
-rw-r--r--TAO/tao/Auto_Functor.h (renamed from TAO/tao/Utils/Auto_Functor.h)0
-rw-r--r--TAO/tao/Auto_Functor.inl (renamed from TAO/tao/Utils/Auto_Functor.inl)0
-rw-r--r--TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp1
-rw-r--r--TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp25
-rw-r--r--TAO/tao/DynamicInterface/DII_Reply_Dispatcher.h25
-rw-r--r--TAO/tao/Makefile.tao1
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation.cpp64
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp11
-rw-r--r--TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp72
-rw-r--r--TAO/tao/Messaging/Asynch_Reply_Dispatcher.h2
-rw-r--r--TAO/tao/Messaging/Asynch_Timeout_Handler.cpp9
-rw-r--r--TAO/tao/Muxed_TMS.cpp16
-rw-r--r--TAO/tao/Utils/Implicit_Deactivator.h2
-rw-r--r--TAO/tao/Utils/Makefile90
-rw-r--r--TAO/tao/Utils/ORB_Destroyer.h2
20 files changed, 394 insertions, 162 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index b6eb46d8fb6..85e458832e9 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,68 @@
+Sat Dec 6 23:42:13 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu>
+
+ This checkin is a fix for the various race conditions in Asynch
+ Invocation reported by Cyrille Chepelov. The various race
+ conditions were
+
+ - Race between threads trying to dispatch replies and timeouts
+ - Race between threads propogating timeouts and propogating
+ replies.
+
+ The crux of the changes involved adding refcounts to the
+ Asynch_Reply_Dispatcher and Asynch_Timeout_Handler. To handle
+ these cleanly I have made some supplementary change like moving
+ Auto_Functor to the TAO library from Utils library, since it is
+ more useful for a bunch of things.
+
+ * tao/Asynch_Reply_Dispatcher_Base.cpp
+ * tao/Asynch_Reply_Dispatcher_Base.h:
+ * tao/Asynch_Reply_Dispatcher_Base.i:
+
+ Added refcounting to this class. Further added a Functor which
+ can be used by Auto_Functor.
+
+ * tao/Muxed_TMS.cpp:
+
+ Fixed a duplicate debug statement in dispatch_reply ().
+
+ * tao/Messaging/Asynch_Invocation.cpp:
+ * tao/Messaging/Asynch_Invocation_Adapter.cpp:
+
+ Use Auto_Functor instead of auto_ptr <> since the reply
+ dispatcher cannot be deleted, but can only be refcounted.
+
+ * tao/Messaging/Asynch_Reply_Dispatcher.cpp::
+ * tao/Messaging/Asynch_Reply_Dispatcher.h:
+
+ The reply dispatcher creates a timeout handler when
+ schedule_timer is called and holds a refcount of the timeout
+ handler. The calls close_connection (), dispatch_reply () and
+ reply_timed_out () doesn't call delete this, but decrements the
+ refcount.
+
+ * tao/Messaging/Asynch_Timeout_Handler.cpp:
+
+ Enable refcounting of the timeout handler. This object holds a
+ refcounted reply dispatcher object. Will decrement the refcount
+ of the reply dispatcher when the object is destroyed.
+
+ * tao/Makefile.tao:
+ * tao/Auto_Functor.{h,cpp,inl}:
+ Moved the autofunctor class form the Utils library to the TAO
+ library.
+
+ * tao/DynamicInterface/DII_Invocation_Adapter.cpp:
+ * tao/DynamicInterface/DII_Reply_Dispatcher.cpp:
+ * tao/DynamicInterface/DII_Reply_Dispatcher.h:
+
+ Replicated the changes made in the Asynch classes to DII
+ classes.
+
+ * tao/Utils/Implicit_Deactivator.h:
+ * tao/Utils/ORB_Destroyer.h:
+
+ Changed the include path for Auto_Functor.h
+
Sat Dec 6 20:35:28 2003 Jeff Parsons <j.parsons@vanderbilt.edu>
* TAO_IDL/be/be_visitor_traits.cpp:
diff --git a/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp b/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp
index be1ca213b97..f22223763b8 100644
--- a/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp
+++ b/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp
@@ -30,9 +30,15 @@ TAO_Asynch_Reply_Dispatcher_Base::TAO_Asynch_Reply_Dispatcher_Base (
TAO_ENCAP_BYTE_ORDER,
TAO_DEF_GIOP_MAJOR,
TAO_DEF_GIOP_MINOR,
- orb_core),
- transport_ (0)
+ orb_core)
+ , transport_ (0)
+ , lock_ (0)
+ , refcount_ (1)
+ , is_reply_dispatched_ (false)
{
+ // @@ NOTE: Need a seperate option for this..
+ this->lock_ =
+ orb_core->resource_factory ()->create_cached_connection_lock ();
}
// Destructor.
@@ -41,6 +47,9 @@ TAO_Asynch_Reply_Dispatcher_Base::~TAO_Asynch_Reply_Dispatcher_Base (void)
// Release the transport that we own
if (this->transport_ != 0)
this->transport_->remove_reference ();
+
+ if (this->lock_)
+ delete this->lock_;
}
void
@@ -50,6 +59,7 @@ TAO_Asynch_Reply_Dispatcher_Base::transport (TAO_Transport *t)
this->transport_->remove_reference ();
this->transport_ = t;
+
this->transport_->add_reference ();
}
@@ -80,3 +90,55 @@ TAO_Asynch_Reply_Dispatcher_Base::schedule_timer (
{
return 0;
}
+
+long
+TAO_Asynch_Reply_Dispatcher_Base::incr_refcount (void)
+{
+ ACE_GUARD_RETURN (ACE_Lock,
+ mutex,
+ *this->lock_,
+ -1);
+ return ++this->refcount_;
+}
+
+long
+TAO_Asynch_Reply_Dispatcher_Base::decr_refcount (void)
+{
+ {
+ ACE_GUARD_RETURN (ACE_Lock,
+ mutex,
+ *this->lock_,
+ -1);
+ --this->refcount_;
+
+ if (this->refcount_ > 0)
+ return this->refcount_;
+ }
+
+ delete this;
+
+ return 0;
+}
+
+bool
+TAO_Asynch_Reply_Dispatcher_Base::try_dispatch_reply (void)
+{
+ if (this->is_reply_dispatched_)
+ return false;
+
+ if (!this->is_reply_dispatched_)
+ {
+ ACE_GUARD_RETURN (ACE_Lock,
+ mutex,
+ *this->lock_,
+ false);
+
+ if (!this->is_reply_dispatched_)
+ {
+ this->is_reply_dispatched_ = true;
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/TAO/tao/Asynch_Reply_Dispatcher_Base.h b/TAO/tao/Asynch_Reply_Dispatcher_Base.h
index e5f80b202df..4857cdb3bc8 100644
--- a/TAO/tao/Asynch_Reply_Dispatcher_Base.h
+++ b/TAO/tao/Asynch_Reply_Dispatcher_Base.h
@@ -27,35 +27,62 @@ class TAO_Pluggable_Reply_Params;
class TAO_ORB_Core ;
class ACE_Time_Value;
class TAO_Transport;
+class ACE_Lock;
-/// Base class for TAO_Asynch_Reply_Dispatcher and
-/// TAO_DII_Deferred_Reply_Dispatcher
-class TAO_Export TAO_Asynch_Reply_Dispatcher_Base
+/**
+ * @class TAO_Asynch_Reply_Dispatcher_Base
+ *
+ * @brief Base class for TAO_Asynch_Reply_Dispatcher and
+ * TAO_DII_Deferred_Reply_Dispatcher
+ */
+
+class TAO_Export TAO_Asynch_Reply_Dispatcher_Base
: public TAO_Reply_Dispatcher
{
public:
/// Default constructor.
TAO_Asynch_Reply_Dispatcher_Base (TAO_ORB_Core *orb_core);
- /// Destructor.
- virtual ~TAO_Asynch_Reply_Dispatcher_Base (void);
-
/// Sets the transport for this invocation.
void transport (TAO_Transport *t);
// = The Reply Dispatcher methods
- virtual int dispatch_reply (TAO_Pluggable_Reply_Params &params);
-
- // virtual TAO_GIOP_Message_State *message_state (void);
+ virtual int dispatch_reply (TAO_Pluggable_Reply_Params &) = 0;
- virtual void connection_closed (void);
+ virtual void connection_closed (void) = 0;
- /// Inform that the reply timed out
- virtual void reply_timed_out (void);
+ /// Inform that the reply timed out
+ virtual void reply_timed_out (void) = 0;
/// Install the timeout handler
- virtual long schedule_timer (CORBA::ULong request_id,
- const ACE_Time_Value &max_wait_time);
+ virtual long schedule_timer (CORBA::ULong ,
+ const ACE_Time_Value &)= 0;
+
+ /// Mutators for refcount
+ long incr_refcount (void);
+ long decr_refcount (void);
+
+ /// A helper method that can be used by the sublcasses
+ /**
+ * The semantics of this helper method needs careful attention. A
+ * call to this method will do the following
+ *
+ * - If the reply has already been dispatched, the return value
+ * will be false to signify not to try.
+ *
+ * - If the reply has not been dispatched, this method will set
+ * the flag to be true and return a true value to signify that
+ * the caller thread can go ahead and dispatch reply.
+ *
+ * Why are we clumping everything in one method. Answer is we need
+ * atomicity?
+ */
+ bool try_dispatch_reply (void);
+
+protected:
+
+ /// Destructor.
+ virtual ~TAO_Asynch_Reply_Dispatcher_Base (void);
protected:
/// The service context list.
@@ -80,8 +107,45 @@ protected:
/// This invocation is using this transport, may change...
TAO_Transport *transport_;
+
+private:
+ /// Lock to protect recount and <is_reply_dispatched_> flag.
+ ACE_Lock *lock_;
+
+ /// Refcount paraphernalia for this class
+ long refcount_;
+
+ /// Has the reply been dispatched?
+ bool is_reply_dispatched_;
};
+namespace TAO
+{
+ /**
+ * @class ARDB_Refcount_Functor
+ *
+ * @brief Functor for refcounting of Asynch_Reply_Dispatcher_Base
+ *
+ * This is used to safely handle the destruction of
+ * Asynch_Reply_Dispatcher_Base objects which are created on the
+ * heap. We cannot use auto_ptr <> since it calls delete on the
+ * pointer, and calling delete on Asynch_Reply_Dispatcher_Base *
+ * will not work. Hence this functor will be used with Auto_Functor
+ * class to handle the memory safely.
+ *
+ * @TODO: Ideally, this class can be a generic class. But that
+ * requires quite a bit of cleanup within TAO to be more useful.
+ */
+ class ARDB_Refcount_Functor
+ {
+ public:
+ void operator() (TAO_Asynch_Reply_Dispatcher_Base *ardb
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC (());
+ };
+
+}
+
#if defined (__ACE_INLINE__)
#include "tao/Asynch_Reply_Dispatcher_Base.i"
#endif /* __ACE_INLINE__ */
diff --git a/TAO/tao/Asynch_Reply_Dispatcher_Base.i b/TAO/tao/Asynch_Reply_Dispatcher_Base.i
index a0fb65140bb..145f1347084 100644
--- a/TAO/tao/Asynch_Reply_Dispatcher_Base.i
+++ b/TAO/tao/Asynch_Reply_Dispatcher_Base.i
@@ -1,2 +1,13 @@
-
// $Id$
+
+namespace TAO
+{
+ ACE_INLINE void
+ ARDB_Refcount_Functor::operator () (
+ TAO_Asynch_Reply_Dispatcher_Base *ardb
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC (())
+ {
+ (void) ardb->decr_refcount (ACE_ENV_SINGLE_ARG_PARAMETER);
+ }
+}
diff --git a/TAO/tao/Utils/Auto_Functor.cpp b/TAO/tao/Auto_Functor.cpp
index 46bd44f5450..46bd44f5450 100644
--- a/TAO/tao/Utils/Auto_Functor.cpp
+++ b/TAO/tao/Auto_Functor.cpp
diff --git a/TAO/tao/Utils/Auto_Functor.h b/TAO/tao/Auto_Functor.h
index 0bfd96ba241..0bfd96ba241 100644
--- a/TAO/tao/Utils/Auto_Functor.h
+++ b/TAO/tao/Auto_Functor.h
diff --git a/TAO/tao/Utils/Auto_Functor.inl b/TAO/tao/Auto_Functor.inl
index b880c94fd76..b880c94fd76 100644
--- a/TAO/tao/Utils/Auto_Functor.inl
+++ b/TAO/tao/Auto_Functor.inl
diff --git a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
index 7f02ee53009..7c1e1588e90 100644
--- a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
+++ b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
@@ -151,7 +151,6 @@ namespace TAO
this->rd_,
this->request_);
-
Invocation_Status status =
synch.remote_invocation (max_wait_time
ACE_ENV_ARG_PARAMETER);
diff --git a/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp b/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp
index bf713b3a628..12b659004f6 100644
--- a/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp
+++ b/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp
@@ -20,21 +20,8 @@ ACE_RCSID(DynamicInterface,
TAO_DII_Deferred_Reply_Dispatcher::TAO_DII_Deferred_Reply_Dispatcher (
const CORBA::Request_ptr req,
TAO_ORB_Core *orb_core)
- : TAO_Asynch_Reply_Dispatcher_Base (orb_core),
- db_ (sizeof buf_,
- ACE_Message_Block::MB_DATA,
- this->buf_,
- orb_core->input_cdr_buffer_allocator (),
- orb_core->locking_strategy (),
- ACE_Message_Block::DONT_DELETE,
- orb_core->input_cdr_dblock_allocator ()),
- reply_cdr_ (&db_,
- ACE_Message_Block::DONT_DELETE,
- TAO_ENCAP_BYTE_ORDER,
- TAO_DEF_GIOP_MAJOR,
- TAO_DEF_GIOP_MINOR,
- orb_core),
- req_ (req)
+ : TAO_Asynch_Reply_Dispatcher_Base (orb_core)
+ , req_ (req)
{
}
@@ -109,9 +96,8 @@ TAO_DII_Deferred_Reply_Dispatcher::dispatch_reply (
}
ACE_ENDTRY;
- // This was dynamically allocated. Now the job is done. Commit
- // suicide here.
- delete this;
+ // This was dynamically allocated. Now the job is done.
+ (void) this->decr_refcount ();
return 1;
}
@@ -150,4 +136,7 @@ TAO_DII_Deferred_Reply_Dispatcher::connection_closed (void)
}
}
ACE_ENDTRY;
+ ACE_CHECK;
+
+ (void) this->decr_refcount ();
}
diff --git a/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.h b/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.h
index 2ded472819a..d0f084bacdd 100644
--- a/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.h
+++ b/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.h
@@ -48,28 +48,27 @@ class TAO_DynamicInterface_Export TAO_DII_Deferred_Reply_Dispatcher
public:
TAO_DII_Deferred_Reply_Dispatcher (const CORBA::Request_ptr req,
TAO_ORB_Core *orb_core);
- // Constructor.
- virtual ~TAO_DII_Deferred_Reply_Dispatcher (void);
- // Destructor.
+
// = The Reply_Dispatcher methods
virtual int dispatch_reply (TAO_Pluggable_Reply_Params &param);
virtual void connection_closed (void);
-private:
-
- /// The buffer that is used to initialise the data block
- char buf_[ACE_CDR::DEFAULT_BUFSIZE];
+ /// The following methods are not needed for this class..
+ virtual void reply_timed_out (void) {}
+ virtual long schedule_timer (CORBA::ULong ,
+ const ACE_Time_Value &)
+ {
+ return 0;
+ }
- /// datablock that is created on teh stack to initialise the CDR
- /// stream underneath.
- ACE_Data_Block db_;
-
- /// CDR stream for reading the input.
- TAO_InputCDR reply_cdr_;
+protected:
+ // Destructor.
+ ~TAO_DII_Deferred_Reply_Dispatcher (void);
+private:
/// Where the reply needs to go.
const CORBA::Request_ptr req_;
};
diff --git a/TAO/tao/Makefile.tao b/TAO/tao/Makefile.tao
index 5bfa9a77142..a225c60e535 100644
--- a/TAO/tao/Makefile.tao
+++ b/TAO/tao/Makefile.tao
@@ -329,6 +329,7 @@ DYNAMIC_ANY_FILES =
TEMPLATE_FILES = \
Acceptor_Impl \
+ Auto_Functor \
Connector_Impl \
Connector_Impl \
Sequence_T \
diff --git a/TAO/tao/Messaging/Asynch_Invocation.cpp b/TAO/tao/Messaging/Asynch_Invocation.cpp
index d380639154e..21fde283895 100644
--- a/TAO/tao/Messaging/Asynch_Invocation.cpp
+++ b/TAO/tao/Messaging/Asynch_Invocation.cpp
@@ -9,6 +9,7 @@
#include "tao/Transport.h"
#include "tao/Muxed_TMS.h"
#include "tao/Pluggable_Messaging.h"
+#include "tao/Auto_Functor.h"
#include "tao/ORB_Constants.h"
ACE_RCSID (tao,
@@ -36,22 +37,6 @@ namespace TAO
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::Exception))
{
- // Register a reply dispatcher for this invocation. Use the
- // preallocated reply dispatcher.
- TAO_Bind_Dispatcher_Guard dispatch_guard (this->details_.request_id (),
- this->rd_,
- this->resolver_.transport ()->tms ());
-
-
- if (dispatch_guard.status () != 0)
- {
- // @@ What is the right way to handle this error? Do we need
- // to call the interceptors in this case?
- ACE_THROW_RETURN (CORBA::INTERNAL (TAO_DEFAULT_MINOR_CODE,
- CORBA::COMPLETED_NO),
- TAO_INVOKE_FAILURE);
- }
-
TAO_Target_Specification tspec;
this->init_target_spec (tspec ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
@@ -62,7 +47,8 @@ namespace TAO
// This auto_ptr is required when interceptors are called. If any
// of the interceptors throws an exception or returns with an
// error we need to delete the reply handler.
- auto_ptr<TAO_Asynch_Reply_Dispatcher_Base> safe_rd (this->rd_);
+ TAO::Utils::Auto_Functor <TAO_Asynch_Reply_Dispatcher_Base,
+ TAO::ARDB_Refcount_Functor> safe_rd (this->rd_);
s =
this->send_request_interception (ACE_ENV_SINGLE_ARG_PARAMETER);
@@ -75,6 +61,28 @@ namespace TAO
return s;
#endif /*TAO_HAS_INTERCEPTORS */
+ // Register a reply dispatcher for this invocation. Use the
+ // preallocated reply dispatcher.
+ TAO_Bind_Dispatcher_Guard dispatch_guard (
+ this->details_.request_id (),
+ this->rd_,
+ this->resolver_.transport ()->tms ());
+
+ if (dispatch_guard.status () != 0)
+ {
+ // @@ What is the right way to handle this error? Do we need
+ // to call the interceptors in this case?
+ ACE_THROW_RETURN (CORBA::INTERNAL (TAO_DEFAULT_MINOR_CODE,
+ CORBA::COMPLETED_NO),
+ TAO_INVOKE_FAILURE);
+ }
+
+ // Do not unbind during destruction. We need the entry to be
+ // there in the map since the reply dispatcher depends on
+ // that. This is also a trigger to loose the ownership of the
+ // reply dispatcher.
+ dispatch_guard.status (TAO_Bind_Dispatcher_Guard::NO_UNBIND);
+
TAO_OutputCDR &cdr =
this->resolver_.transport ()->messaging_object ()->out_stream ();
@@ -103,10 +111,14 @@ namespace TAO
ACE_TRY_CHECK;
#if TAO_HAS_INTERCEPTORS == 1
- // This auto_ptr is required when interceptors are called. If any
- // of the interceptors throws an exception or returns with an
- // error we need to delete the reply handler.
- auto_ptr<TAO_Asynch_Reply_Dispatcher_Base> safe_rd2 (this->rd_);
+ // NOTE: We don't need to do the auto_ptr <> trick. We got here
+ // in the first place since the message was sent properly,
+ // which implies a reply would be available. Therefore the
+ // reply dispatcher should be available for another thread to
+ // collect and dispatch the reply. In MT cases, things are
+ // more hairy. Just imagine what happens when another thread
+ // is collecting the reply when we are happily invoking
+ // interceptors?
// Nothing great on here. If we get a restart during send or a
// proper send, we are supposed to call receiver_other ()
@@ -115,9 +127,6 @@ namespace TAO
this->receive_other_interception (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
- if (tmp != TAO_INVOKE_FAILURE)
- safe_rd2.release ();
-
// We got an error during the interception.
if (s == TAO_INVOKE_SUCCESS && tmp != TAO_INVOKE_SUCCESS)
s = tmp;
@@ -125,14 +134,11 @@ namespace TAO
// If an error occurred just return. At this point all the
// endpoint interception would have been invoked. The callee
- // wold take care of the rest.
+ // would take care of the rest.
if (s != TAO_INVOKE_SUCCESS)
return s;
- // Do not unbind during destruction. We need the entry to be
- // there in the map since the reply dispctaher depends on
- // that.
- dispatch_guard.status (TAO_Bind_Dispatcher_Guard::NO_UNBIND);
+
// NOTE: Not sure how things are handles with exclusive muxed
// strategy.
diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
index 7285d998471..5876ceb3698 100644
--- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
+++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
@@ -10,7 +10,7 @@
#include "tao/Muxed_TMS.h"
#include "tao/ORB_Constants.h"
#include "tao/debug.h"
-#include "ace/Auto_Ptr.h"
+#include "tao/Auto_Functor.h"
#if !defined (__ACE_INLINE__)
#include "Asynch_Invocation_Adapter.inl"
@@ -112,8 +112,15 @@ namespace TAO
if (this->get_timeout (r.stub (),
tmp))
{
+ TAO::Utils::Auto_Functor<TAO_Asynch_Reply_Dispatcher_Base,
+ TAO::ARDB_Refcount_Functor> safe_rd (this->rd_);
+
this->rd_->schedule_timer (op.request_id (),
- *max_wait_time);
+ *max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ safe_rd.release ();
}
}
diff --git a/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp b/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp
index 786ad3d90c8..7a9ff2a78b8 100644
--- a/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp
+++ b/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp
@@ -8,6 +8,8 @@
#include "tao/ORB_Core.h"
#include "tao/Transport.h"
+#include "ace/CORBA_macros.h"
+
#if !defined (__ACE_INLINE__)
#include "Asynch_Reply_Dispatcher.i"
#endif /* __ACE_INLINE__ */
@@ -21,10 +23,10 @@ TAO_Asynch_Reply_Dispatcher::TAO_Asynch_Reply_Dispatcher (
Messaging::ReplyHandler_ptr reply_handler,
TAO_ORB_Core *orb_core
)
- :TAO_Asynch_Reply_Dispatcher_Base (orb_core),
- reply_handler_skel_ (reply_handler_skel),
- reply_handler_ (Messaging::ReplyHandler::_duplicate (reply_handler)),
- timeout_handler_ (this, orb_core->reactor ())
+ :TAO_Asynch_Reply_Dispatcher_Base (orb_core)
+ , reply_handler_skel_ (reply_handler_skel)
+ , reply_handler_ (Messaging::ReplyHandler::_duplicate (reply_handler))
+ , timeout_handler_ (0)
{
}
@@ -42,10 +44,17 @@ TAO_Asynch_Reply_Dispatcher::dispatch_reply (
if (params.input_cdr_ == 0)
return -1;
- // AMI Timeout Handling Begin
- timeout_handler_.cancel ();
- // AMI Timeout Handling End
+ if (this->timeout_handler_)
+ {
+ // If we had registered timeout handlers just cancel them and
+ // loose ownership of the handlers
+ this->timeout_handler_->cancel ();
+ this->timeout_handler_->remove_reference ();
+ this->timeout_handler_ = 0;
+ // AMI Timeout Handling End
+ }
+
this->reply_status_ = params.reply_status_;
@@ -87,6 +96,9 @@ TAO_Asynch_Reply_Dispatcher::dispatch_reply (
ACE_TEXT ("dispatch_reply\n")));
}
+ if (!this->try_dispatch_reply ())
+ return 0;
+
CORBA::ULong reply_error = TAO_AMI_REPLY_NOT_OK;
switch (this->reply_status_)
{
@@ -129,9 +141,7 @@ TAO_Asynch_Reply_Dispatcher::dispatch_reply (
ACE_ENDTRY;
}
- // This was dynamically allocated. Now the job is done. Commit
- // suicide here.
- delete this;
+ this->decr_refcount ();
return 1;
}
@@ -141,9 +151,14 @@ TAO_Asynch_Reply_Dispatcher::connection_closed (void)
{
ACE_TRY_NEW_ENV
{
- // AMI Timeout Handling Begin
-
- timeout_handler_.cancel ();
+ if (this->timeout_handler_)
+ {
+ // If we had registered timeout handlers just cancel them and
+ // loose ownership of the handlers
+ this->timeout_handler_->cancel ();
+ this->timeout_handler_->remove_reference ();
+ this->timeout_handler_ = 0;
+ }
// AMI Timeout Handling End
@@ -179,8 +194,7 @@ TAO_Asynch_Reply_Dispatcher::connection_closed (void)
}
ACE_ENDTRY;
- // Commit suicide.
- delete this;
+ (void) this->decr_refcount ();
}
// AMI Timeout Handling Begin
@@ -202,6 +216,9 @@ TAO_Asynch_Reply_Dispatcher::reply_timed_out (void)
timeout_failure._tao_encode (out_cdr ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
+ if (!this->try_dispatch_reply ())
+ return;
+
// Turn into an output CDR
TAO_InputCDR cdr (out_cdr);
@@ -224,17 +241,28 @@ TAO_Asynch_Reply_Dispatcher::reply_timed_out (void)
}
ACE_ENDTRY;
+ ACE_CHECK;
- // This was dynamically allocated. Now the job is done. Commit
- // suicide here.
- delete this;
+ (void) this->decr_refcount ();
}
long
TAO_Asynch_Reply_Dispatcher::schedule_timer (CORBA::ULong request_id,
- const ACE_Time_Value &max_wait_time)
+ const ACE_Time_Value &max_wait_time
+ ACE_ENV_ARG_DECL)
{
- return this->timeout_handler_.schedule_timer (this->transport_->tms (),
- request_id,
- max_wait_time);
+ if (this->timeout_handler_ == 0)
+ {
+ // @@ Need to use the pool for this..
+ ACE_NEW_THROW_EX (this->timeout_handler_,
+ TAO_Asynch_Timeout_Handler (
+ this,
+ this->transport_->orb_core ()->reactor ()),
+ CORBA::NO_MEMORY ());
+ }
+
+ return this->timeout_handler_->schedule_timer (
+ this->transport_->tms (),
+ request_id,
+ max_wait_time);
}
diff --git a/TAO/tao/Messaging/Asynch_Reply_Dispatcher.h b/TAO/tao/Messaging/Asynch_Reply_Dispatcher.h
index 623cb8c24ed..d4babe11403 100644
--- a/TAO/tao/Messaging/Asynch_Reply_Dispatcher.h
+++ b/TAO/tao/Messaging/Asynch_Reply_Dispatcher.h
@@ -61,7 +61,7 @@ private:
Messaging::ReplyHandler_var reply_handler_;
/// Timeout Handler in case of AMI timeouts
- TAO_Asynch_Timeout_Handler timeout_handler_;
+ TAO_Asynch_Timeout_Handler *timeout_handler_;
};
diff --git a/TAO/tao/Messaging/Asynch_Timeout_Handler.cpp b/TAO/tao/Messaging/Asynch_Timeout_Handler.cpp
index 29f3b80c1f6..c16a8903d1f 100644
--- a/TAO/tao/Messaging/Asynch_Timeout_Handler.cpp
+++ b/TAO/tao/Messaging/Asynch_Timeout_Handler.cpp
@@ -18,12 +18,18 @@ TAO_Asynch_Timeout_Handler::TAO_Asynch_Timeout_Handler (
request_id_ (0),
reactor_ (reactor)
{
+ // Enable reference counting on the event handler.
+ this->reference_counting_policy ().value (
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
+ // We own a reference
+ (void) this->rd_->incr_refcount ();
}
TAO_Asynch_Timeout_Handler::~TAO_Asynch_Timeout_Handler ()
{
-
+ // Forget rd's reference
+ (void) this->rd_->decr_refcount ();
}
@@ -65,4 +71,3 @@ TAO_Asynch_Timeout_Handler::cancel ()
this->reactor_->cancel_timer (this);
}
}
-
diff --git a/TAO/tao/Muxed_TMS.cpp b/TAO/tao/Muxed_TMS.cpp
index ee9e0f90f45..0e7403b7540 100644
--- a/TAO/tao/Muxed_TMS.cpp
+++ b/TAO/tao/Muxed_TMS.cpp
@@ -134,6 +134,7 @@ TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
"id = %d\n",
params.request_id_));
+
if (result != 0)
{
if (TAO_debug_level > 0 && result != 0)
@@ -156,21 +157,6 @@ TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
"id = %d\n",
params.request_id_));
- if (result != 0)
- {
- if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::dispatch_reply: ")
- ACE_TEXT ("unbind dispatcher failed: result = %d\n"),
- result));
-
- // This return value means that the mux strategy was not able
- // to find a registered reply handler, either because the reply
- // was not our reply - just forget about it - or it was ours, but
- // the reply timed out - just forget about the reply.
- return 0;
- }
-
// Do not move it outside the scope of the lock. A follower thread
// could have timedout unwinding the stack and the reply
// dispatcher, and that would mean the present thread could be left
diff --git a/TAO/tao/Utils/Implicit_Deactivator.h b/TAO/tao/Utils/Implicit_Deactivator.h
index 34befe31259..8cdd14f753d 100644
--- a/TAO/tao/Utils/Implicit_Deactivator.h
+++ b/TAO/tao/Utils/Implicit_Deactivator.h
@@ -13,13 +13,13 @@
#include /**/ "ace/pre.h"
#include "utils_export.h"
-#include "Auto_Functor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/PortableServer/PortableServer.h"
+#include "tao/Auto_Functor.h"
namespace TAO
diff --git a/TAO/tao/Utils/Makefile b/TAO/tao/Utils/Makefile
index 9b623eca08a..bd73570db5f 100644
--- a/TAO/tao/Utils/Makefile
+++ b/TAO/tao/Utils/Makefile
@@ -20,7 +20,6 @@ CPP_SRCS += \
PolicyList_Destroyer
TEMPLATE_FILES = \
- Auto_Functor \
RIR_Narrow \
Servant_Var
@@ -57,17 +56,18 @@ CPPFLAGS += -I$(TAO_ROOT)
.obj/ORB_Destroyer.o .obj/ORB_Destroyer.so .shobj/ORB_Destroyer.o .shobj/ORB_Destroyer.so: ORB_Destroyer.cpp ORB_Destroyer.h \
- $(ACE_ROOT)/ace/pre.h \
- utils_export.h \
+ $(ACE_ROOT)/ace/pre.h utils_export.h \
+ $(ACE_ROOT)/ace/config-all.h \
+ $(ACE_ROOT)/ace/config.h \
+ $(ACE_ROOT)/ace/$(ACE_PLATFORM_CONFIG) \
$(ACE_ROOT)/ace/post.h \
$(ACE_ROOT)/ace/ace_wchar.h \
$(ACE_ROOT)/ace/ace_wchar.inl \
$(ACE_ROOT)/ace/OS_main.h \
- Auto_Functor.h \
- $(TAO_ROOT)/tao/Environment.h \
- $(TAO_ROOT)/tao/TAO_Export.h \
- $(TAO_ROOT)/tao/Basic_Types.h \
- $(ACE_ROOT)/ace/CDR_Base.h \
+ $(ACE_ROOT)/ace/ACE_export.h \
+ $(TAO_ROOT)/tao/ORB.h \
+ $(TAO_ROOT)/tao/Exception.h \
+ $(TAO_ROOT)/tao/orbconf.h \
$(ACE_ROOT)/ace/Basic_Types.h \
$(ACE_ROOT)/ace/os_include/os_limits.h \
$(ACE_ROOT)/ace/os_include/os_unistd.h \
@@ -85,12 +85,7 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/os_include/os_ucontext.h \
$(ACE_ROOT)/ace/os_include/sys/os_resource.h \
$(ACE_ROOT)/ace/os_include/sys/os_time.h \
- $(ACE_ROOT)/ace/ACE_export.h \
$(ACE_ROOT)/ace/Basic_Types.i \
- $(ACE_ROOT)/ace/Default_Constants.h \
- $(ACE_ROOT)/ace/CDR_Base.inl \
- $(TAO_ROOT)/tao/CORBA_methods.h \
- $(TAO_ROOT)/tao/orbconf.h \
$(ACE_ROOT)/ace/Global_Macros.h \
$(ACE_ROOT)/ace/OS_Errno.h \
$(ACE_ROOT)/ace/os_include/os_errno.h \
@@ -98,18 +93,15 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/Synch_Traits.h \
$(ACE_ROOT)/ace/Lock.h \
$(ACE_ROOT)/ace/Lock.inl \
- $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \
- $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \
- $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \
- $(TAO_ROOT)/tao/default_environment.h \
- $(TAO_ROOT)/tao/Environment.i \
- Auto_Functor.inl Auto_Functor.cpp \
- $(TAO_ROOT)/tao/ORB.h \
- $(TAO_ROOT)/tao/Exception.h \
$(ACE_ROOT)/ace/SStringfwd.h \
$(ACE_ROOT)/ace/iosfwd.h \
$(ACE_ROOT)/ace/CORBA_macros.h \
$(ACE_ROOT)/ace/Exception_Macros.h \
+ $(TAO_ROOT)/tao/TAO_Export.h \
+ $(TAO_ROOT)/tao/Basic_Types.h \
+ $(ACE_ROOT)/ace/CDR_Base.h \
+ $(ACE_ROOT)/ace/Default_Constants.h \
+ $(ACE_ROOT)/ace/CDR_Base.inl \
$(TAO_ROOT)/tao/Exception.i \
$(TAO_ROOT)/tao/objectid.h \
$(TAO_ROOT)/tao/PolicyC.h \
@@ -122,12 +114,19 @@ CPPFLAGS += -I$(TAO_ROOT)
$(TAO_ROOT)/tao/CORBA_String.h \
$(TAO_ROOT)/tao/CORBA_String.inl \
$(TAO_ROOT)/tao/Managed_Types.i \
+ $(TAO_ROOT)/tao/default_environment.h \
$(TAO_ROOT)/tao/Sequence.i \
$(TAO_ROOT)/tao/Sequence_T.h \
$(TAO_ROOT)/tao/Objref_VarOut_T.h \
$(TAO_ROOT)/tao/varbase.h \
$(TAO_ROOT)/tao/Objref_VarOut_T.inl \
$(TAO_ROOT)/tao/Objref_VarOut_T.cpp \
+ $(TAO_ROOT)/tao/Environment.h \
+ $(TAO_ROOT)/tao/CORBA_methods.h \
+ $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \
+ $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \
+ $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \
+ $(TAO_ROOT)/tao/Environment.i \
$(TAO_ROOT)/tao/Sequence_T.i \
$(TAO_ROOT)/tao/Sequence_T.cpp \
$(TAO_ROOT)/tao/Array_VarOut_T.h \
@@ -147,6 +146,7 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/os_include/os_string.h \
$(ACE_ROOT)/ace/os_include/os_ctype.h \
$(ACE_ROOT)/ace/OS_NS_wchar.inl \
+ $(ACE_ROOT)/ace/os_include/os_search.h \
$(ACE_ROOT)/ace/OS_Memory.inl \
$(TAO_ROOT)/tao/Seq_Var_T.h \
$(TAO_ROOT)/tao/Seq_Var_T.inl \
@@ -228,18 +228,26 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/RW_Mutex.inl \
$(ACE_ROOT)/ace/RW_Thread_Mutex.inl \
$(ACE_ROOT)/ace/Guard_T.cpp \
- $(TAO_ROOT)/tao/ORB.i
+ $(TAO_ROOT)/tao/ORB.i \
+ $(TAO_ROOT)/tao/Auto_Functor.h \
+ $(TAO_ROOT)/tao/Auto_Functor.inl \
+ $(TAO_ROOT)/tao/Auto_Functor.cpp
.obj/Implicit_Deactivator.o .obj/Implicit_Deactivator.so .shobj/Implicit_Deactivator.o .shobj/Implicit_Deactivator.so: Implicit_Deactivator.cpp Implicit_Deactivator.h \
- $(ACE_ROOT)/ace/pre.h \
- utils_export.h \
+ $(ACE_ROOT)/ace/pre.h utils_export.h \
+ $(ACE_ROOT)/ace/config-all.h \
+ $(ACE_ROOT)/ace/config.h \
+ $(ACE_ROOT)/ace/$(ACE_PLATFORM_CONFIG) \
$(ACE_ROOT)/ace/post.h \
$(ACE_ROOT)/ace/ace_wchar.h \
$(ACE_ROOT)/ace/ace_wchar.inl \
$(ACE_ROOT)/ace/OS_main.h \
- Auto_Functor.h \
- $(TAO_ROOT)/tao/Environment.h \
- $(TAO_ROOT)/tao/TAO_Export.h \
+ $(ACE_ROOT)/ace/ACE_export.h \
+ $(TAO_ROOT)/tao/PortableServer/PortableServer.h \
+ $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \
+ $(TAO_ROOT)/tao/Objref_VarOut_T.h \
+ $(ACE_ROOT)/ace/CORBA_macros.h \
+ $(ACE_ROOT)/ace/Exception_Macros.h \
$(TAO_ROOT)/tao/Basic_Types.h \
$(ACE_ROOT)/ace/CDR_Base.h \
$(ACE_ROOT)/ace/Basic_Types.h \
@@ -259,10 +267,14 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/os_include/os_ucontext.h \
$(ACE_ROOT)/ace/os_include/sys/os_resource.h \
$(ACE_ROOT)/ace/os_include/sys/os_time.h \
- $(ACE_ROOT)/ace/ACE_export.h \
$(ACE_ROOT)/ace/Basic_Types.i \
$(ACE_ROOT)/ace/Default_Constants.h \
$(ACE_ROOT)/ace/CDR_Base.inl \
+ $(TAO_ROOT)/tao/varbase.h \
+ $(TAO_ROOT)/tao/Objref_VarOut_T.inl \
+ $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \
+ $(TAO_ROOT)/tao/Environment.h \
+ $(TAO_ROOT)/tao/TAO_Export.h \
$(TAO_ROOT)/tao/CORBA_methods.h \
$(TAO_ROOT)/tao/orbconf.h \
$(ACE_ROOT)/ace/Global_Macros.h \
@@ -277,15 +289,6 @@ CPPFLAGS += -I$(TAO_ROOT)
$(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \
$(TAO_ROOT)/tao/default_environment.h \
$(TAO_ROOT)/tao/Environment.i \
- Auto_Functor.inl Auto_Functor.cpp \
- $(TAO_ROOT)/tao/PortableServer/PortableServer.h \
- $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \
- $(TAO_ROOT)/tao/Objref_VarOut_T.h \
- $(ACE_ROOT)/ace/CORBA_macros.h \
- $(ACE_ROOT)/ace/Exception_Macros.h \
- $(TAO_ROOT)/tao/varbase.h \
- $(TAO_ROOT)/tao/Objref_VarOut_T.inl \
- $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \
$(TAO_ROOT)/tao/PortableServer/PortableServerC.h \
$(TAO_ROOT)/tao/Exception.h \
$(ACE_ROOT)/ace/SStringfwd.h \
@@ -322,6 +325,7 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/os_include/os_string.h \
$(ACE_ROOT)/ace/os_include/os_ctype.h \
$(ACE_ROOT)/ace/OS_NS_wchar.inl \
+ $(ACE_ROOT)/ace/os_include/os_search.h \
$(ACE_ROOT)/ace/OS_Memory.inl \
$(TAO_ROOT)/tao/Seq_Var_T.h \
$(TAO_ROOT)/tao/Seq_Var_T.inl \
@@ -365,6 +369,9 @@ CPPFLAGS += -I$(TAO_ROOT)
$(TAO_ROOT)/tao/CurrentC.i \
$(TAO_ROOT)/tao/PolicyC.i \
$(TAO_ROOT)/tao/PortableServer/PortableServerC.i \
+ $(TAO_ROOT)/tao/Auto_Functor.h \
+ $(TAO_ROOT)/tao/Auto_Functor.inl \
+ $(TAO_ROOT)/tao/Auto_Functor.cpp \
$(TAO_ROOT)/tao/PortableServer/Servant_Base.h \
$(TAO_ROOT)/tao/Abstract_Servant_Base.h \
$(TAO_ROOT)/tao/Collocation_Strategy.h \
@@ -416,12 +423,15 @@ CPPFLAGS += -I$(TAO_ROOT)
$(TAO_ROOT)/tao/PortableServer/Servant_Base.i
.obj/PolicyList_Destroyer.o .obj/PolicyList_Destroyer.so .shobj/PolicyList_Destroyer.o .shobj/PolicyList_Destroyer.so: PolicyList_Destroyer.cpp PolicyList_Destroyer.h \
- $(ACE_ROOT)/ace/pre.h \
- utils_export.h \
+ $(ACE_ROOT)/ace/pre.h utils_export.h \
+ $(ACE_ROOT)/ace/config-all.h \
+ $(ACE_ROOT)/ace/config.h \
+ $(ACE_ROOT)/ace/$(ACE_PLATFORM_CONFIG) \
$(ACE_ROOT)/ace/post.h \
$(ACE_ROOT)/ace/ace_wchar.h \
$(ACE_ROOT)/ace/ace_wchar.inl \
$(ACE_ROOT)/ace/OS_main.h \
+ $(ACE_ROOT)/ace/ACE_export.h \
$(TAO_ROOT)/tao/PolicyC.h \
$(TAO_ROOT)/tao/CurrentC.h \
$(TAO_ROOT)/tao/Object.h \
@@ -451,7 +461,6 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/os_include/os_ucontext.h \
$(ACE_ROOT)/ace/os_include/sys/os_resource.h \
$(ACE_ROOT)/ace/os_include/sys/os_time.h \
- $(ACE_ROOT)/ace/ACE_export.h \
$(ACE_ROOT)/ace/Basic_Types.i \
$(ACE_ROOT)/ace/Default_Constants.h \
$(ACE_ROOT)/ace/CDR_Base.inl \
@@ -499,6 +508,7 @@ CPPFLAGS += -I$(TAO_ROOT)
$(ACE_ROOT)/ace/os_include/os_string.h \
$(ACE_ROOT)/ace/os_include/os_ctype.h \
$(ACE_ROOT)/ace/OS_NS_wchar.inl \
+ $(ACE_ROOT)/ace/os_include/os_search.h \
$(ACE_ROOT)/ace/OS_Memory.inl \
$(TAO_ROOT)/tao/Seq_Var_T.h \
$(TAO_ROOT)/tao/Seq_Var_T.inl \
diff --git a/TAO/tao/Utils/ORB_Destroyer.h b/TAO/tao/Utils/ORB_Destroyer.h
index 4a51a2b835b..3b6d1de8393 100644
--- a/TAO/tao/Utils/ORB_Destroyer.h
+++ b/TAO/tao/Utils/ORB_Destroyer.h
@@ -12,13 +12,13 @@
#define TAO_UTILS_ORB_DESTROYER_H
#include /**/ "ace/pre.h"
#include "utils_export.h"
-#include "Auto_Functor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/ORB.h"
+#include "tao/Auto_Functor.h"
namespace TAO
{