summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authormsmit <msmit@remedy.nl>2009-03-31 10:06:45 +0000
committermsmit <msmit@remedy.nl>2009-03-31 10:06:45 +0000
commit990644326411e525e737d688105a0b9505485e20 (patch)
tree492f575f48613dacbe7458477d7f2c538d99ffea /TAO
parentd955bd531bef53000b03603b8e342b3e94ce66f3 (diff)
downloadATCD-990644326411e525e737d688105a0b9505485e20.tar.gz
Tue Mar 31 10:44:16 UTC 2009 Marcel Smit <msmit@remedy.nl>
* tao/Asynch_Reply_Dispatcher_Base.cpp: * tao/Asynch_Reply_Dispatcher_Base.h: * tao/Asynch_Reply_Dispatcher_Base.inl: * tao/DynamicInterface/DII_Reply_Dispatcher.cpp: * tao/Exclusive_TMS.cpp: * tao/Exclusive_TMS.h: * tao/LocateRequest_Invocation.cpp: * tao/Messaging/Asynch_Reply_Dispatcher.cpp: * tao/Muxed_TMS.cpp: * tao/Muxed_TMS.h: * tao/Reply_Dispatcher.cpp: * tao/Reply_Dispatcher.h: * tao/Synch_Invocation.cpp: * tao/Transport_Mux_Strategy.h: Refactored Reply Dispatchers. It's now possible to make a CORBA call (synchronous or asynchronous) during an AMI reply dispatch without running into a deadlock. Also, the reply dispatchers are now created on the heap, using an ACE_Intrusive_Auto_Ptr. This fixes Bugzilla 3567. * tests/Big_AMI/client.cpp: Using a different CORBA:Object_var for ior. * NEWS: Listed this change.
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog30
-rw-r--r--TAO/NEWS4
-rw-r--r--TAO/tao/Asynch_Reply_Dispatcher_Base.cpp44
-rw-r--r--TAO/tao/Asynch_Reply_Dispatcher_Base.h14
-rw-r--r--TAO/tao/Asynch_Reply_Dispatcher_Base.inl2
-rw-r--r--TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp8
-rw-r--r--TAO/tao/Exclusive_TMS.cpp6
-rw-r--r--TAO/tao/Exclusive_TMS.h6
-rw-r--r--TAO/tao/LocateRequest_Invocation.cpp18
-rw-r--r--TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp6
-rw-r--r--TAO/tao/Muxed_TMS.cpp32
-rw-r--r--TAO/tao/Muxed_TMS.h5
-rw-r--r--TAO/tao/Reply_Dispatcher.cpp36
-rw-r--r--TAO/tao/Reply_Dispatcher.h17
-rw-r--r--TAO/tao/Synch_Invocation.cpp18
-rw-r--r--TAO/tao/Transport_Mux_Strategy.h4
-rw-r--r--TAO/tests/Big_AMI/client.cpp4
17 files changed, 151 insertions, 103 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 62b0d366c75..d3cb177cd8d 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,33 @@
+Tue Mar 31 10:44:16 UTC 2009 Marcel Smit <msmit@remedy.nl>
+
+ * tao/Asynch_Reply_Dispatcher_Base.cpp:
+ * tao/Asynch_Reply_Dispatcher_Base.h:
+ * tao/Asynch_Reply_Dispatcher_Base.inl:
+ * tao/DynamicInterface/DII_Reply_Dispatcher.cpp:
+ * tao/Exclusive_TMS.cpp:
+ * tao/Exclusive_TMS.h:
+ * tao/LocateRequest_Invocation.cpp:
+ * tao/Messaging/Asynch_Reply_Dispatcher.cpp:
+ * tao/Muxed_TMS.cpp:
+ * tao/Muxed_TMS.h:
+ * tao/Reply_Dispatcher.cpp:
+ * tao/Reply_Dispatcher.h:
+ * tao/Synch_Invocation.cpp:
+ * tao/Transport_Mux_Strategy.h:
+ Refactored Reply Dispatchers. It's now possible to make a CORBA
+ call (synchronous or asynchronous) during an AMI reply
+ dispatch without running into a deadlock.
+ Also, the reply dispatchers are now created on the heap,
+ using an ACE_Intrusive_Auto_Ptr.
+ This fixes Bugzilla 3567.
+
+ * tests/Big_AMI/client.cpp:
+ Using a different CORBA:Object_var for ior.
+
+ * NEWS:
+ Listed this change.
+
+
Mon Mar 30 07:39:16 UTC 2009 Marcel Smit <msmit@remedy.nl>
* tests/RTCORBA/MT_Client_Protocol_Priority/run_test.pl:
diff --git a/TAO/NEWS b/TAO/NEWS
index 27b3b069231..066d392790b 100644
--- a/TAO/NEWS
+++ b/TAO/NEWS
@@ -4,6 +4,10 @@ PLANNED MAJOR CHANGES "SOMETIME IN THE FUTURE" (i.e., exact beta not known)
USER VISIBLE CHANGES BETWEEN TAO-1.6.8 and TAO-1.6.9
====================================================
+ Reply Dispatchers are refactored. No deadlock occurs
+ when an (a)synchronous CORBA call is made during dispatching
+ a reply.
+
. Fixed IDL compiler bug that in some cases caused code
generation for inherited operations to be skipped.
diff --git a/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp b/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp
index f2d00f91526..1ed5613102e 100644
--- a/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp
+++ b/TAO/tao/Asynch_Reply_Dispatcher_Base.cpp
@@ -19,9 +19,9 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL
// Constructor.
TAO_Asynch_Reply_Dispatcher_Base::TAO_Asynch_Reply_Dispatcher_Base (
TAO_ORB_Core *orb_core,
- ACE_Allocator *allocator
- )
- : db_ (sizeof buf_,
+ ACE_Allocator *allocator)
+ : TAO_Reply_Dispatcher (allocator)
+ , db_ (sizeof buf_,
ACE_Message_Block::MB_DATA,
this->buf_,
orb_core->input_cdr_buffer_allocator (),
@@ -36,9 +36,7 @@ TAO_Asynch_Reply_Dispatcher_Base::TAO_Asynch_Reply_Dispatcher_Base (
orb_core)
, transport_ (0)
, lock_ (0)
- , refcount_ (1)
, is_reply_dispatched_ (false)
- , allocator_ (allocator)
{
// @@ NOTE: Need a seperate option for this..
this->lock_ =
@@ -67,42 +65,6 @@ TAO_Asynch_Reply_Dispatcher_Base::transport (TAO_Transport *t)
this->transport_->add_reference ();
}
-void
-TAO_Asynch_Reply_Dispatcher_Base::incr_refcount (void)
-{
- ACE_GUARD (ACE_Lock,
- mutex,
- *this->lock_);
- ++this->refcount_;
-}
-
-void
-TAO_Asynch_Reply_Dispatcher_Base::decr_refcount (void)
-{
- {
- ACE_GUARD (ACE_Lock,
- mutex,
- *this->lock_);
- --this->refcount_;
-
- if (this->refcount_ > 0)
- return;
- }
-
- if (this->allocator_)
- {
- ACE_DES_FREE (this,
- this->allocator_->free,
- TAO_Asynch_Reply_Dispatcher_Base);
- }
- else
- {
- delete this;
- }
-
- return;
-}
-
bool
TAO_Asynch_Reply_Dispatcher_Base::try_dispatch_reply (void)
{
diff --git a/TAO/tao/Asynch_Reply_Dispatcher_Base.h b/TAO/tao/Asynch_Reply_Dispatcher_Base.h
index 14198c5d6f4..5366382b5f5 100644
--- a/TAO/tao/Asynch_Reply_Dispatcher_Base.h
+++ b/TAO/tao/Asynch_Reply_Dispatcher_Base.h
@@ -56,11 +56,6 @@ public:
/// Install the timeout handler
virtual long schedule_timer (CORBA::ULong , const ACE_Time_Value &) = 0;
- /// @name Mutators for refcount
- //@{
- void incr_refcount (void);
- void decr_refcount (void);
- //@}
/// A helper method that can be used by the subclasses
/**
@@ -113,18 +108,11 @@ protected:
TAO_Transport *transport_;
private:
- /// Lock to protect refcount and @c is_reply_dispatched_ flag.
+ /// Lock to protect @c is_reply_dispatched_ flag.
ACE_Lock *lock_;
- /// Refcount paraphernalia for this class
- CORBA::ULong refcount_;
-
/// Has the reply been dispatched?
bool is_reply_dispatched_;
-
- /// Allocator that was used to allocate this reply dispatcher. In case of
- /// zero we come from the heap.
- ACE_Allocator *allocator_;
};
namespace TAO
diff --git a/TAO/tao/Asynch_Reply_Dispatcher_Base.inl b/TAO/tao/Asynch_Reply_Dispatcher_Base.inl
index 77f9bbd831d..6ce1e3f556f 100644
--- a/TAO/tao/Asynch_Reply_Dispatcher_Base.inl
+++ b/TAO/tao/Asynch_Reply_Dispatcher_Base.inl
@@ -10,7 +10,7 @@ namespace TAO
ARDB_Refcount_Functor::operator () (
TAO_Asynch_Reply_Dispatcher_Base *ardb) throw ()
{
- (void) ardb->decr_refcount ();
+ (void) ardb->intrusive_remove_ref (ardb);
}
}
diff --git a/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp b/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp
index e8734e54b21..4d28e8f3b51 100644
--- a/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp
+++ b/TAO/tao/DynamicInterface/DII_Reply_Dispatcher.cpp
@@ -90,7 +90,7 @@ TAO_DII_Deferred_Reply_Dispatcher::dispatch_reply (
}
// This was dynamically allocated. Now the job is done.
- (void) this->decr_refcount ();
+ this->intrusive_remove_ref (this);
return 1;
}
@@ -122,7 +122,7 @@ TAO_DII_Deferred_Reply_Dispatcher::connection_closed (void)
}
}
- (void) this->decr_refcount ();
+ this->intrusive_remove_ref (this);
}
TAO_DII_Asynch_Reply_Dispatcher::TAO_DII_Asynch_Reply_Dispatcher (
@@ -202,7 +202,7 @@ TAO_DII_Asynch_Reply_Dispatcher::dispatch_reply (
}
}
// This was dynamically allocated. Now the job is done.
- (void) this->decr_refcount ();
+ this->intrusive_remove_ref (this);
return 1;
}
@@ -236,6 +236,6 @@ TAO_DII_Asynch_Reply_Dispatcher::connection_closed (void)
}
}
- (void) this->decr_refcount ();
+ this->intrusive_remove_ref (this);
}
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Exclusive_TMS.cpp b/TAO/tao/Exclusive_TMS.cpp
index 8f9da78eec5..6ac09430d52 100644
--- a/TAO/tao/Exclusive_TMS.cpp
+++ b/TAO/tao/Exclusive_TMS.cpp
@@ -55,7 +55,7 @@ TAO_Exclusive_TMS::request_id (void)
// Bind the handler with the request id.
int
TAO_Exclusive_TMS::bind_dispatcher (CORBA::ULong request_id,
- TAO_Reply_Dispatcher *rd)
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd)
{
this->request_id_ = request_id;
this->rd_ = rd;
@@ -96,7 +96,7 @@ TAO_Exclusive_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
return 0;
}
- TAO_Reply_Dispatcher *rd = this->rd_;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd (this->rd_.get (), false);
this->request_id_ = 0; // @@ What is a good value???
this->rd_ = 0;
@@ -121,7 +121,7 @@ TAO_Exclusive_TMS::reply_timed_out (CORBA::ULong request_id)
return 0;
}
- TAO_Reply_Dispatcher *rd = this->rd_;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd (this->rd_.get (), false);
this->request_id_ = 0; // @@ What is a good value???
this->rd_ = 0;
diff --git a/TAO/tao/Exclusive_TMS.h b/TAO/tao/Exclusive_TMS.h
index 27f6fdb7f34..62bc1333222 100644
--- a/TAO/tao/Exclusive_TMS.h
+++ b/TAO/tao/Exclusive_TMS.h
@@ -22,6 +22,8 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+#include "ace/Intrusive_Auto_Ptr.h"
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
class TAO_Pluggable_Reply_Params;
@@ -56,7 +58,7 @@ public:
//@{
virtual CORBA::ULong request_id (void);
virtual int bind_dispatcher (CORBA::ULong request_id,
- TAO_Reply_Dispatcher *rh);
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd);
virtual int unbind_dispatcher (CORBA::ULong request_id);
virtual int dispatch_reply (TAO_Pluggable_Reply_Params &params);
@@ -78,7 +80,7 @@ protected:
/// Reply Dispatcher corresponding to the request. If this is zero we don't
/// have a reply, if it not zero we have one
- TAO_Reply_Dispatcher *rd_;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd_;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/LocateRequest_Invocation.cpp b/TAO/tao/LocateRequest_Invocation.cpp
index d49efd9d707..e64ab434271 100644
--- a/TAO/tao/LocateRequest_Invocation.cpp
+++ b/TAO/tao/LocateRequest_Invocation.cpp
@@ -9,6 +9,7 @@
#include "tao/Profile.h"
#include "tao/ORB_Constants.h"
#include "tao/SystemException.h"
+#include "ace/Intrusive_Auto_Ptr.h"
#include "ace/Countdown_Time.h"
@@ -36,13 +37,20 @@ namespace TAO
{
ACE_Countdown_Time countdown (max_wait_time);
- TAO_Synch_Reply_Dispatcher rd (this->resolver_.stub ()->orb_core (),
- this->details_.reply_service_info ());
+ TAO_Synch_Reply_Dispatcher *rd_p = 0;
+ ACE_NEW_NORETURN (rd_p, TAO_Synch_Reply_Dispatcher (this->resolver_.stub ()->orb_core (),
+ this->details_.reply_service_info ()));
+ if (!rd_p)
+ {
+ throw ::CORBA::NO_MEMORY ();
+ }
+
+ ACE_Intrusive_Auto_Ptr<TAO_Synch_Reply_Dispatcher> rd(rd_p, false);
// Register a reply dispatcher for this invocation. Use the
// preallocated reply dispatcher.
TAO_Bind_Dispatcher_Guard dispatch_guard (this->details_.request_id (),
- &rd,
+ rd.get (),
this->resolver_.transport ()->tms ());
if (dispatch_guard.status () != 0)
@@ -84,9 +92,9 @@ namespace TAO
if (this->resolver_.transport ()->idle_after_send ())
this->resolver_.transport_released ();
- s = this->wait_for_reply (max_wait_time, rd, dispatch_guard);
+ s = this->wait_for_reply (max_wait_time, *rd.get (), dispatch_guard);
- s = this->check_reply (rd);
+ s = this->check_reply (*rd.get ());
// For some strategies one may want to release the transport
// back to cache after receiving the reply. If the idling is
diff --git a/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp b/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp
index 2a2d66ad5f2..9075cd3247c 100644
--- a/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp
+++ b/TAO/tao/Messaging/Asynch_Reply_Dispatcher.cpp
@@ -138,7 +138,7 @@ TAO_Asynch_Reply_Dispatcher::dispatch_reply (TAO_Pluggable_Reply_Params &params)
}
}
- this->decr_refcount ();
+ this->intrusive_remove_ref (this);
return 1;
}
@@ -187,7 +187,7 @@ TAO_Asynch_Reply_Dispatcher::connection_closed (void)
}
- (void) this->decr_refcount ();
+ this->intrusive_remove_ref (this);
}
// AMI Timeout Handling Begin
@@ -241,7 +241,7 @@ TAO_Asynch_Reply_Dispatcher::reply_timed_out (void)
}
}
- (void) this->decr_refcount ();
+ this->intrusive_remove_ref (this);
}
long
diff --git a/TAO/tao/Muxed_TMS.cpp b/TAO/tao/Muxed_TMS.cpp
index ed9b87bbf1b..06036f4f116 100644
--- a/TAO/tao/Muxed_TMS.cpp
+++ b/TAO/tao/Muxed_TMS.cpp
@@ -66,7 +66,7 @@ TAO_Muxed_TMS::request_id (void)
/// Bind the dispatcher with the request id.
int
TAO_Muxed_TMS::bind_dispatcher (CORBA::ULong request_id,
- TAO_Reply_Dispatcher *rd)
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd)
{
ACE_GUARD_RETURN (ACE_Lock,
ace_mon,
@@ -126,15 +126,16 @@ int
TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
{
int result = 0;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd(0);
+
// Grab the reply dispatcher for this id.
{
ACE_GUARD_RETURN (ACE_Lock,
ace_mon,
*this->lock_,
-1);
-
- TAO_Reply_Dispatcher *rd = 0;
result = this->dispatcher_table_.unbind (params.request_id_, rd);
+ }
if (result == 0 && rd)
{
@@ -144,11 +145,6 @@ TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
ACE_TEXT ("id = %d\n"),
params.request_id_));
- // 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
- // with a dangling pointer and may crash. To safeguard against such
- // cases we dispatch with the lock held.
// Dispatch the reply.
// They return 1 on success, and -1 on failure.
result = rd->dispatch_reply (params);
@@ -162,13 +158,13 @@ TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
params.request_id_,
result));
- // Result = 0 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.
- result = 0;
- }
- }
+ // Result = 0 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.
+ result = 0;
+ }
+
return result;
}
@@ -177,7 +173,7 @@ int
TAO_Muxed_TMS::reply_timed_out (CORBA::ULong request_id)
{
int result = 0;
- TAO_Reply_Dispatcher *rd = 0;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd(0);
// Grab the reply dispatcher for this id.
{
@@ -269,7 +265,7 @@ TAO_Muxed_TMS::clear_cache_i (void)
REQUEST_DISPATCHER_TABLE::ITERATOR const end =
this->dispatcher_table_.end ();
- ACE_Unbounded_Stack <TAO_Reply_Dispatcher *> ubs;
+ ACE_Unbounded_Stack <ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> > ubs;
for (REQUEST_DISPATCHER_TABLE::ITERATOR i =
this->dispatcher_table_.begin ();
@@ -284,7 +280,7 @@ TAO_Muxed_TMS::clear_cache_i (void)
for (size_t k = 0 ; k != sz ; ++k)
{
- TAO_Reply_Dispatcher *rd = 0;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd(0);
if (ubs.pop (rd) == 0)
{
diff --git a/TAO/tao/Muxed_TMS.h b/TAO/tao/Muxed_TMS.h
index f18e9cf8600..4a86f144ed5 100644
--- a/TAO/tao/Muxed_TMS.h
+++ b/TAO/tao/Muxed_TMS.h
@@ -31,6 +31,7 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL
class TAO_ORB_Core;
class TAO_Pluggable_Reply_Params;
class TAO_Reply_Dispatcher;
+template <class X> class ACE_Intrusive_Auto_Ptr;
/**
* @class TAO_Muxed_TMS
@@ -60,7 +61,7 @@ public:
// = Please read the documentation in the TAO_Transport_Mux_Strategy
// class.
virtual int bind_dispatcher (CORBA::ULong request_id,
- TAO_Reply_Dispatcher *rh);
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd);
virtual int unbind_dispatcher (CORBA::ULong request_id);
virtual int dispatch_reply (TAO_Pluggable_Reply_Params &params);
@@ -88,7 +89,7 @@ private:
TAO_ORB_Core * const orb_core_;
typedef ACE_Hash_Map_Manager_Ex <CORBA::ULong,
- TAO_Reply_Dispatcher *,
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher>,
ACE_Hash <CORBA::ULong>,
ACE_Equal_To <CORBA::ULong>,
ACE_Null_Mutex>
diff --git a/TAO/tao/Reply_Dispatcher.cpp b/TAO/tao/Reply_Dispatcher.cpp
index eb6f608eaa2..e69fec458e2 100644
--- a/TAO/tao/Reply_Dispatcher.cpp
+++ b/TAO/tao/Reply_Dispatcher.cpp
@@ -13,10 +13,12 @@ ACE_RCSID (tao,
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
// Constructor.
-TAO_Reply_Dispatcher::TAO_Reply_Dispatcher (void)
+TAO_Reply_Dispatcher::TAO_Reply_Dispatcher (ACE_Allocator *allocator)
// Just an invalid reply status.
: locate_reply_status_ (GIOP::UNKNOWN_OBJECT)
, reply_status_ (GIOP::NO_EXCEPTION)
+ , refcnt_ (1)
+ , allocator_(allocator)
{
}
@@ -25,4 +27,36 @@ TAO_Reply_Dispatcher::~TAO_Reply_Dispatcher (void)
{
}
+
+void
+TAO_Reply_Dispatcher::intrusive_add_ref (TAO_Reply_Dispatcher* rd)
+{
+ if (rd != 0)
+ {
+ ++rd->refcnt_;
+ }
+}
+
+void
+TAO_Reply_Dispatcher::intrusive_remove_ref (TAO_Reply_Dispatcher* rd)
+{
+ if (rd != 0)
+ {
+ long tmp = --rd->refcnt_;
+ if (tmp <= 0)
+ {
+ if (rd->allocator_)
+ {
+ ACE_DES_FREE (rd,
+ rd->allocator_->free,
+ TAO_Reply_Dispatcher);
+ }
+ else
+ {
+ delete rd;
+ }
+ }
+ }
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Reply_Dispatcher.h b/TAO/tao/Reply_Dispatcher.h
index e291148edfe..89049d70e5a 100644
--- a/TAO/tao/Reply_Dispatcher.h
+++ b/TAO/tao/Reply_Dispatcher.h
@@ -27,10 +27,14 @@
#include "tao/Basic_Types.h"
#include "tao/GIOPC.h"
+#include "ace/Atomic_Op.h"
+#include "ace/Intrusive_Auto_Ptr.h"
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward Declarations.
class TAO_Pluggable_Reply_Params;
+class ACE_Allocator;
/**
* @class TAO_Reply_Dispatcher
@@ -52,7 +56,7 @@ class TAO_Export TAO_Reply_Dispatcher
public:
/// Constructor.
- TAO_Reply_Dispatcher (void);
+ TAO_Reply_Dispatcher (ACE_Allocator *allocator = 0);
/// Destructor.
virtual ~TAO_Reply_Dispatcher (void);
@@ -86,12 +90,23 @@ public:
GIOP::ReplyStatusType reply_status (void) const;
+ static void intrusive_add_ref (TAO_Reply_Dispatcher*);
+ static void intrusive_remove_ref (TAO_Reply_Dispatcher*);
+
protected:
/// LocateReply status.
GIOP::LocateStatusType locate_reply_status_;
// RequestReply status
GIOP::ReplyStatusType reply_status_;
+
+private:
+ /// Support for intrusive reference counting
+ ACE_Atomic_Op<TAO_SYNCH_MUTEX, long> refcnt_;
+
+ /// Allocator that was used to allocate this reply dispatcher. In case of
+ /// zero we come from the heap.
+ ACE_Allocator *allocator_;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Synch_Invocation.cpp b/TAO/tao/Synch_Invocation.cpp
index dab407a556f..e0ad08a0a55 100644
--- a/TAO/tao/Synch_Invocation.cpp
+++ b/TAO/tao/Synch_Invocation.cpp
@@ -15,6 +15,7 @@
#include "tao/ORB_Core.h"
#include "tao/Service_Context.h"
#include "tao/SystemException.h"
+#include "ace/Intrusive_Auto_Ptr.h"
#if TAO_HAS_INTERCEPTORS == 1
# include "tao/PortableInterceptorC.h"
@@ -55,8 +56,15 @@ namespace TAO
{
ACE_Countdown_Time countdown (max_wait_time);
- TAO_Synch_Reply_Dispatcher rd (this->resolver_.stub ()->orb_core (),
- this->details_.reply_service_info ());
+ TAO_Synch_Reply_Dispatcher *rd_p = 0;
+ ACE_NEW_NORETURN (rd_p, TAO_Synch_Reply_Dispatcher (this->resolver_.stub ()->orb_core (),
+ this->details_.reply_service_info ()));
+ if (!rd_p)
+ {
+ throw ::CORBA::NO_MEMORY ();
+ }
+
+ ACE_Intrusive_Auto_Ptr<TAO_Synch_Reply_Dispatcher> rd(rd_p, false);
Invocation_Status s = TAO_INVOKE_FAILURE;
@@ -101,7 +109,7 @@ namespace TAO
// preallocated reply dispatcher.
TAO_Bind_Dispatcher_Guard dispatch_guard (
this->details_.request_id (),
- &rd,
+ rd.get (),
transport->tms ());
if (dispatch_guard.status () != 0)
@@ -163,7 +171,7 @@ namespace TAO
// (explicitly coded) handlers called. We assume a POSIX.1c/C/C++
// environment.
- s = this->wait_for_reply (max_wait_time, rd, dispatch_guard);
+ s = this->wait_for_reply (max_wait_time, *rd.get (), dispatch_guard);
#if TAO_HAS_INTERCEPTORS == 1
if (s == TAO_INVOKE_RESTART)
@@ -182,7 +190,7 @@ namespace TAO
// What happens when the above call returns an error through
// the return value? That would be bogus as per the contract
// in the interface. The call violated the contract
- s = this->check_reply_status (rd);
+ s = this->check_reply_status (*rd.get ());
// For some strategies one may want to release the transport
// back to cache after receiving the reply.
diff --git a/TAO/tao/Transport_Mux_Strategy.h b/TAO/tao/Transport_Mux_Strategy.h
index 34ecd995d5f..cd2b6fac2cd 100644
--- a/TAO/tao/Transport_Mux_Strategy.h
+++ b/TAO/tao/Transport_Mux_Strategy.h
@@ -22,6 +22,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/Basic_Types.h"
+#include "tao/Reply_Dispatcher.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Lock;
@@ -29,7 +30,6 @@ ACE_END_VERSIONED_NAMESPACE_DECL
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-class TAO_Reply_Dispatcher;
class TAO_Transport;
class TAO_Pluggable_Reply_Params;
@@ -58,7 +58,7 @@ public:
/// Bind the dispatcher with the request id. Commonalities in the
/// derived class implementations is kept here.
virtual int bind_dispatcher (CORBA::ULong request_id,
- TAO_Reply_Dispatcher *rd) = 0;
+ ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd) = 0;
/**
* Unbind the dispatcher, the client is no longer waiting for the
diff --git a/TAO/tests/Big_AMI/client.cpp b/TAO/tests/Big_AMI/client.cpp
index a8b4332aed0..ac7a4292842 100644
--- a/TAO/tests/Big_AMI/client.cpp
+++ b/TAO/tests/Big_AMI/client.cpp
@@ -143,10 +143,10 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
return 1;
// We reuse the object_var smart pointer!
- object_var = orb->string_to_object (ior);
+ CORBA::Object_var ior_object = orb->string_to_object (ior);
A::AMI_Test_var ami_test_var =
- A::AMI_Test::_narrow (object_var.in ());
+ A::AMI_Test::_narrow (ior_object.in ());
if (CORBA::is_nil (ami_test_var.in ()))
{