summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbala <balanatarajan@users.noreply.github.com>2002-10-22 04:05:54 +0000
committerbala <balanatarajan@users.noreply.github.com>2002-10-22 04:05:54 +0000
commit34601941fc60330b7f79f0fc72be1ff087b3e242 (patch)
treed880c443ad8630445fe84dc1edb257706575a052
parent312ed9cf7ffc44100f5a88c2178d067341d500a5 (diff)
downloadATCD-34601941fc60330b7f79f0fc72be1ff087b3e242.tar.gz
ChangeLogTag:Mon Oct 21 22:45:02 2002 Balachandran Natarajan <bala@isis-server.isis.vanderbilt.edu>
-rw-r--r--TAO/ChangeLog66
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp12
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.h2
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp14
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h2
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp12
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h2
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.cpp13
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.h2
-rw-r--r--TAO/tao/Connection_Handler.cpp357
-rw-r--r--TAO/tao/Connection_Handler.h52
-rw-r--r--TAO/tao/Connection_Handler.inl19
-rw-r--r--TAO/tao/Connector_Impl.cpp2
-rw-r--r--TAO/tao/IIOP_Connection_Handler.cpp12
-rw-r--r--TAO/tao/IIOP_Connection_Handler.h2
-rw-r--r--TAO/tao/IIOP_Connector.cpp2
-rw-r--r--TAO/tao/IIOP_Transport.cpp13
-rw-r--r--TAO/tao/IIOP_Transport.h2
-rw-r--r--TAO/tao/Invocation.cpp6
-rw-r--r--TAO/tao/LF_Connect_Strategy.cpp20
-rw-r--r--TAO/tao/Muxed_TMS.cpp3
-rw-r--r--TAO/tao/Notify_Handler.cpp21
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.cpp12
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.h2
-rw-r--r--TAO/tao/Strategies/DIOP_Transport.cpp12
-rw-r--r--TAO/tao/Strategies/DIOP_Transport.h2
-rw-r--r--TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp12
-rw-r--r--TAO/tao/Strategies/SHMIOP_Connection_Handler.h2
-rw-r--r--TAO/tao/Strategies/SHMIOP_Transport.cpp12
-rw-r--r--TAO/tao/Strategies/SHMIOP_Transport.h3
-rw-r--r--TAO/tao/Strategies/UIOP_Connection_Handler.cpp12
-rw-r--r--TAO/tao/Strategies/UIOP_Connection_Handler.h2
-rw-r--r--TAO/tao/Strategies/UIOP_Transport.cpp12
-rw-r--r--TAO/tao/Strategies/UIOP_Transport.h3
-rw-r--r--TAO/tao/Synch_Refcountable.cpp1
-rw-r--r--TAO/tao/TAO_Server_Request.cpp5
-rw-r--r--TAO/tao/Transport.cpp86
-rw-r--r--TAO/tao/Transport.h11
38 files changed, 518 insertions, 307 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 4fe478d6494..3359481b2d7 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,4 +1,68 @@
-Mon Oct 21 21:51:07 2002 Balachandran Natarajan <bala@cs.wustl.edu>
+Mon Oct 21 22:45:02 2002 Balachandran Natarajan <bala@isis-server.isis.vanderbilt.edu>
+
+ Bug fix for [BUGID 1269]. Thanks to Carlos O'Ryan for donating
+ this patch.
+
+ * tao/Connection_Handler.cpp:
+ * tao/Connection_Handler.h:
+ * tao/Connection_Handler.inl:
+ * tao/Connector_Impl.cpp:
+ * tao/IIOP_Connection_Handler.cpp:
+ * tao/IIOP_Connection_Handler.h:
+ * tao/Invocation.cpp:
+ * tao/LF_Connect_Strategy.cpp:
+ * tao/Muxed_TMS.cpp:
+ * tao/Notify_Handler.cpp:
+ * tao/Synch_Refcountable.cpp:
+ * tao/TAO_Server_Request.cpp:
+ * tao/IIOP_Connector.cpp:
+ * tao/IIOP_Transport.cpp:
+ * tao/IIOP_Transport.h:
+ * tao/Transport.cpp:
+ * tao/Transport.h: Changes to the ORB Core. The details are as
+ follows
+
+ - It eliminates the two refcounts in the connection handler and
+ combines as one refcount.
+
+ - The transport_ field in the Connection_Handler class is
+ atomically modified.
+
+ - Closing connections are also atomic.
+
+ - When the connection is closed all the activations in the
+ reactor are removed.
+
+ For all the other gory details like the motivation for these
+ changes, it is advised you refer to BUGID's 1202, 1269 and
+ 1270.
+
+ * tao/Strategies/DIOP_Connection_Handler.cpp:
+ * tao/Strategies/DIOP_Connection_Handler.h:
+ * tao/Strategies/DIOP_Transport.cpp:
+ * tao/Strategies/DIOP_Transport.h:
+ * tao/Strategies/SHMIOP_Connection_Handler.cpp:
+ * tao/Strategies/SHMIOP_Connection_Handler.h:
+ * tao/Strategies/SHMIOP_Transport.cpp:
+ * tao/Strategies/SHMIOP_Transport.h:
+ * tao/Strategies/UIOP_Connection_Handler.cpp:
+ * tao/Strategies/UIOP_Connection_Handler.h:
+ * tao/Strategies/UIOP_Transport.cpp:
+ * tao/Strategies/UIOP_Transport.h:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.h:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h:
+ * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp:
+ * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h:
+ * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.cpp:
+ * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.h:
+
+ Changes to the pluggable protocols to reflect the changes in the
+ ORB Core.
+
+
+Mon Oct 21 21:51:07 2002 Balachandran Natarajan <bala@isis-server.isis.vanderbilt.edu>
* tests/DLL_ORB/Makefile.Tests_Client_Module: Added TAO_ROOT
definition to fix the compileation problems.
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp
index ef447ea3ee1..a2252e797bd 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp
@@ -221,6 +221,12 @@ TAO_UIPMC_Connection_Handler::resume_handler (void)
}
int
+TAO_UIPMC_Connection_Handler::close_connection (void)
+{
+ return this->close_connection_eh (this);
+}
+
+int
TAO_UIPMC_Connection_Handler::handle_input (ACE_HANDLE h)
{
return this->handle_input_eh (h, this);
@@ -239,12 +245,6 @@ TAO_UIPMC_Connection_Handler::handle_close (ACE_HANDLE handle,
return this->handle_close_eh (handle, rm, this);
}
-void
-TAO_UIPMC_Connection_Handler::handle_close_i (void)
-{
- this->handle_close_i_eh (this);
-}
-
int
TAO_UIPMC_Connection_Handler::release_os_resources (void)
{
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.h
index d50a28ddba7..8f9b832a3dc 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.h
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.h
@@ -111,6 +111,7 @@ public:
/** @name Event Handler overloads
*/
virtual int resume_handler (void);
+ virtual int close_connection (void);
virtual int handle_input (ACE_HANDLE);
virtual int handle_output (ACE_HANDLE);
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
@@ -164,7 +165,6 @@ protected:
/**
* @name TAO_Connection Handler overloads
*/
- void handle_close_i (void);
virtual int release_os_resources (void);
//@}
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp
index d7e4702c92c..3829cd25b82 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp
@@ -35,6 +35,14 @@ TAO_UIPMC_Transport::TAO_UIPMC_Transport (TAO_UIPMC_Connection_Handler *handler,
, connection_handler_ (handler)
, messaging_object_ (0)
{
+ if (connection_handler_ != 0)
+ {
+ // REFCNT: Matches one of
+ // TAO_Transport::connection_handler_close() or
+ // TAO_Transport::close_connection_shared.
+ this->connection_handler_->incr_refcount();
+ }
+
// Use the normal GIOP object
ACE_NEW (this->messaging_object_,
TAO_GIOP_Message_Base (orb_core,
@@ -49,8 +57,8 @@ TAO_UIPMC_Transport::TAO_UIPMC_Transport (TAO_UIPMC_Connection_Handler *handler,
TAO_UIPMC_Transport::~TAO_UIPMC_Transport (void)
{
+ ACE_ASSERT(this->connection_handler_ == 0);
delete this->messaging_object_;
- this->messaging_object_ = 0;
}
ACE_Event_Handler *
@@ -544,10 +552,10 @@ TAO_UIPMC_Transport::messaging_init (CORBA::Octet major,
return 1;
}
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_UIPMC_Transport::invalidate_event_handler_i (void)
{
- ACE_Event_Handler * eh = this->connection_handler_;
+ TAO_Connection_Handler * eh = this->connection_handler_;
this->connection_handler_ = 0;
return eh;
}
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h
index 6490d89a1b4..96467c88f8e 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h
@@ -72,7 +72,7 @@ protected:
virtual ACE_Event_Handler * event_handler_i (void);
virtual TAO_Connection_Handler *connection_handler_i (void);
- virtual ACE_Event_Handler * invalidate_event_handler_i (void);
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void);
virtual TAO_Pluggable_Messaging *messaging_object (void);
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp
index a7705c13d0e..d6406eb84de 100644
--- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp
@@ -213,6 +213,12 @@ TAO_SSLIOP_Connection_Handler::resume_handler (void)
}
int
+TAO_SSLIOP_Connection_Handler::close_connection (void)
+{
+ return this->close_connection_eh (this);
+}
+
+int
TAO_SSLIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
return this->handle_input_eh (h, this);
@@ -231,12 +237,6 @@ TAO_SSLIOP_Connection_Handler::handle_close (ACE_HANDLE handle,
return this->handle_close_eh (handle, rm, this);
}
-void
-TAO_SSLIOP_Connection_Handler::handle_close_i (void)
-{
- this->handle_close_i_eh (this);
-}
-
int
TAO_SSLIOP_Connection_Handler::release_os_resources (void)
{
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h
index 0fb5a28c322..8640fa052b7 100644
--- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h
@@ -85,6 +85,7 @@ public:
/** @name Event Handler overloads
*/
virtual int resume_handler (void);
+ virtual int close_connection (void);
virtual int handle_input (ACE_HANDLE);
virtual int handle_output (ACE_HANDLE);
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
@@ -112,7 +113,6 @@ protected:
/**
* @name TAO_Connection Handler overloads
*/
- void handle_close_i (void);
virtual int release_os_resources (void);
virtual void pos_io_hook (int & return_value);
//@}
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.cpp
index f5b1790033d..9e04e168a8a 100644
--- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.cpp
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.cpp
@@ -29,6 +29,14 @@ TAO_SSLIOP_Transport::TAO_SSLIOP_Transport (
connection_handler_ (handler),
messaging_object_ (0)
{
+ if (connection_handler_ != 0)
+ {
+ // REFCNT: Matches one of
+ // TAO_Transport::connection_handler_close() or
+ // TAO_Transport::close_connection_shared.
+ this->connection_handler_->incr_refcount();
+ }
+
// Use the normal GIOP object
ACE_NEW (this->messaging_object_,
TAO_GIOP_Message_Base (orb_core));
@@ -37,6 +45,7 @@ TAO_SSLIOP_Transport::TAO_SSLIOP_Transport (
TAO_SSLIOP_Transport::~TAO_SSLIOP_Transport (void)
{
+ ACE_ASSERT(this->connection_handler_ == 0);
delete this->messaging_object_;
}
@@ -402,10 +411,10 @@ TAO_SSLIOP_Transport::get_listen_point (
return 1;
}
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_SSLIOP_Transport::invalidate_event_handler_i (void)
{
- ACE_Event_Handler * eh = this->connection_handler_;
+ TAO_Connection_Handler * eh = this->connection_handler_;
this->connection_handler_ = 0;
return eh;
}
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.h b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.h
index 3eee7effe6a..fb979d8798d 100644
--- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.h
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Transport.h
@@ -88,7 +88,7 @@ protected:
virtual ACE_Event_Handler * event_handler_i (void);
virtual TAO_Connection_Handler *connection_handler_i (void);
- virtual ACE_Event_Handler * invalidate_event_handler_i (void);
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void);
virtual TAO_Pluggable_Messaging *messaging_object (void);
diff --git a/TAO/tao/Connection_Handler.cpp b/TAO/tao/Connection_Handler.cpp
index c75b807808e..8983deff106 100644
--- a/TAO/tao/Connection_Handler.cpp
+++ b/TAO/tao/Connection_Handler.cpp
@@ -22,17 +22,18 @@ ACE_RCSID (tao,
"$Id$")
TAO_Connection_Handler::TAO_Connection_Handler (TAO_ORB_Core *orb_core)
- : orb_core_ (orb_core),
- transport_ (0),
- tss_resources_ (orb_core->get_tss_resources ()),
- pending_upcalls_ (1),
- reference_count_ (1),
- pending_upcall_lock_ (0)
+ : orb_core_ (orb_core)
+ , transport_ (0)
+ , tss_resources_ (orb_core->get_tss_resources ())
+ , reference_count_ (1)
{
- // NOTE: Why should the refcount be
// @@todo: We need to have a distinct option/ method in the resource
// factory for this and TAO_Transport.
- this->pending_upcall_lock_ =
+
+ this->refcount_lock_ =
+ this->orb_core_->resource_factory ()->create_cached_connection_lock ();
+
+ this->lock_ =
this->orb_core_->resource_factory ()->create_cached_connection_lock ();
// Put ourselves in the connection wait state as soon as we get
@@ -43,14 +44,12 @@ TAO_Connection_Handler::TAO_Connection_Handler (TAO_ORB_Core *orb_core)
TAO_Connection_Handler::~TAO_Connection_Handler (void)
{
- // Set some of the pointers that we hold to zero explicitly, so that
- // nobody tries to access these
- this->orb_core_ = 0;
- this->tss_resources_ = 0;
- TAO_Transport::release (this->transport_);
-
- delete this->pending_upcall_lock_;
- this->pending_upcall_lock_ = 0;
+ ACE_ASSERT(this->transport_ == 0);
+ ACE_ASSERT(this->reference_count_ == 0);
+
+ // @@ TODO Use auto_ptr<>
+ delete this->lock_;
+ delete this->refcount_lock_;
}
@@ -138,13 +137,15 @@ TAO_Connection_Handler::svc_i (void)
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) TAO_Connection_Handler::svc_i - ")
- ACE_TEXT ("loop <%d>\n"), current_timeout.msec ()));
+ "TAO (%P|%t) - Connection_Handler::svc_i - "
+ "loop <%d>\n", current_timeout.msec ()
+ ));
}
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) TAO_Connection_Handler::svc_i end\n")));
+ "TAO (%P|%t) - Connection_Handler::svc_i end\n"
+ ));
return result;
}
@@ -152,58 +153,46 @@ TAO_Connection_Handler::svc_i (void)
void
TAO_Connection_Handler::transport (TAO_Transport* transport)
{
- if (this->transport_ != 0) {
- this->transport_->connection_handler_closing ();
+ // The transport can be reset, but not changed!
+ ACE_ASSERT(this->transport_ == 0 || transport == 0);
+
+ TAO_Transport * tmp = 0;
+ {
+ // Make the change atomic
+ ACE_GUARD (ACE_Lock, ace_mon, *this->lock_);
+ tmp = this->transport_;
+ this->transport_ = TAO_Transport::_duplicate (transport);
}
- this->transport_ = TAO_Transport::_duplicate (transport);
+ if (tmp != 0) {
+ tmp->connection_handler_closing ();
+ TAO_Transport::release (tmp);
+ }
}
-int
+long
TAO_Connection_Handler::incr_refcount (void)
{
- ACE_GUARD_RETURN (ACE_Lock,
- ace_mon,
- *this->pending_upcall_lock_, -1);
+ ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->refcount_lock_, -1);
+ ACE_ASSERT(this->reference_count_ > 0);
return ++this->reference_count_;
}
-void
+long
TAO_Connection_Handler::decr_refcount (void)
{
{
- ACE_GUARD (ACE_Lock,
- ace_mon,
- *this->pending_upcall_lock_);
+ ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->refcount_lock_, -1);
- --this->reference_count_;
+ if(--this->reference_count_ > 0)
+ return this->reference_count_;
}
- if (this->reference_count_ == 0)
- this->handle_close_i ();
-}
-
-int
-TAO_Connection_Handler::incr_pending_upcalls (void)
-{
- ACE_GUARD_RETURN (ACE_Lock,
- ace_mon,
- *this->pending_upcall_lock_, -1);
-
- return ++this->pending_upcalls_;
-
-
-}
-
-int
-TAO_Connection_Handler::decr_pending_upcalls (void)
-{
- ACE_GUARD_RETURN (ACE_Lock,
- ace_mon,
- *this->pending_upcall_lock_, -1);
+ ACE_ASSERT(this->reference_count_ == 0);
+ delete this;
- return --this->pending_upcalls_;
+ return 0;
}
int
@@ -220,68 +209,23 @@ TAO_Connection_Handler::handle_close_eh (
my_handle, handle, reactor_mask));
}
- if(my_handle == ACE_INVALID_HANDLE)
+ if (this->close_connection () == 0)
{
+ if (TAO_debug_level)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - IIOP_Connection_Handler[%d]::"
+ "handle_close, connection closing or already closed\n",
+ my_handle));
return 0;
}
- // Just close the socket irrespective of what the upcall count is,
- // we need to cleanup OS resources ASAP.
- this->release_os_resources ();
-
- // Set the handle to be INVALID_HANDLE
- eh->set_handle (ACE_INVALID_HANDLE);
-
- this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED);
-
- // @@ TODO All this code dealing with upcalls is fishy, upcalls are
- // incremented/decremented in handle_input_i(), and only
- // decremented here! Also: the reference count is decremented
- // here, while it is incremented in a selected few other places,
- // in a very confusing ways.
- long upcalls = this->decr_pending_upcalls ();
-
- ACE_ASSERT(upcalls >= 0);
-
- // If the upcall count is zero start the cleanup.
- if (upcalls == 0)
- this->decr_refcount ();
-
- return 0;
-}
-
-void
-TAO_Connection_Handler::handle_close_i_eh (
- ACE_Event_Handler * eh)
-{
if (TAO_debug_level)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Connection_Handler[%d]::handle_close_i, "
- "\n",
- this->transport ()->id ()));
-
- if (this->transport ()->wait_strategy ()->is_registered ())
- {
- // Make sure there are no timers.
- ACE_ASSERT(eh->reactor() != 0);
- eh->reactor ()->cancel_timer (eh);
-
- // Set the flag to indicate that it is no longer registered with
- // the reactor, so that it isn't included in the set that is
- // passed to the reactor on ORB destruction.
- this->transport ()->wait_strategy ()->is_registered (0);
- }
-
- // Close the handle..
- // Remove the entry as it is invalid
- this->transport ()->purge_entry ();
-
- // Signal the transport that we will no longer have
- // a reference to it. This will eventually call
- // TAO_Transport::release ().
- this->transport (0);
+ "TAO (%P|%t) - IIOP_Connection_Handler[%d]::"
+ "handle_close, connection fully closed\n",
+ my_handle));
- delete this;
+ return 0;
}
int
@@ -297,6 +241,7 @@ TAO_Connection_Handler::handle_output_eh (
this->pre_io_hook (return_value);
if (return_value != 0)
{
+ resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
return return_value;
}
@@ -316,26 +261,30 @@ TAO_Connection_Handler::handle_input_eh (
ACE_HANDLE h, ACE_Event_Handler * eh)
{
// Increase the reference count on the upcall that have passed us.
- long upcalls = this->incr_pending_upcalls ();
+ //
+ // REFCNT: Matches decr_refcount() in this function...
+ long refcount = this->incr_refcount ();
+ ACE_ASSERT (refcount > 0);
if (TAO_debug_level > 6)
{
ACE_HANDLE handle = eh->get_handle();
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - IIOP_Connection_Handler[%d]::handle_input, "
- "handle = %d/%d, upcalls = %d\n",
- this->transport()->id(), handle, h, upcalls));
+ "handle = %d/%d, refcount = %d\n",
+ this->transport()->id(), handle, h, refcount));
}
- ACE_ASSERT (upcalls > 0);
- TAO_Resume_Handle resume_handle (this->orb_core (),
- eh->get_handle ());
+ TAO_Resume_Handle resume_handle (this->orb_core (), eh->get_handle ());
int return_value = 0;
this->pre_io_hook (return_value);
if (return_value != 0)
{
+ // REFCNT: Matches incr_refcount() at the beginning...
+ refcount = this->decr_refcount ();
+ ACE_ASSERT (refcount >= 0);
return return_value;
}
@@ -343,30 +292,20 @@ TAO_Connection_Handler::handle_input_eh (
this->pos_io_hook(return_value);
- // The upcall is done. Bump down the reference count
- upcalls = this->decr_pending_upcalls ();
+ // REFCNT: Matches incr_refcount() at the beginning...
+ refcount = this->decr_refcount ();
+ ACE_ASSERT (refcount >= 0);
if (TAO_debug_level > 6)
{
ACE_HANDLE handle = eh->get_handle();
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - IIOP_Connection_Handler[%d]::handle_input, "
- "handle = %d/%d, upcalls = %d, retval = %d\n",
- this->transport()->id(), handle, h, upcalls, return_value));
- }
- ACE_ASSERT (upcalls >= 0);
-
- if (upcalls == 0)
- {
- this->decr_refcount ();
-
- // As we have already performed the handle closing (indirectly)
- // we dont want to return a -1. Doing so would make the reactor
- // call handle_close () which could be harmful.
- return_value = 0;
+ "handle = %d/%d, refcount = %d, retval = %d\n",
+ this->transport()->id(), handle, h, refcount, return_value));
}
- if (return_value != 0 || upcalls == 0)
+ if (return_value == -1 || refcount == 0)
{
// This is really a odd case. We could have a race condition if
// we dont do this. Looks like this what happens
@@ -393,6 +332,162 @@ TAO_Connection_Handler::handle_input_eh (
}
int
+TAO_Connection_Handler::close_connection_eh (ACE_Event_Handler * eh)
+{
+ // Perform a double checked locking on the underlying ACE_HANDLE
+ ACE_HANDLE handle = eh->get_handle();
+
+ // If the handle is ACE_INVALID_HANDLE then there is no work to be
+ // done in this function, and we return immediately. Returning 0
+ // indicates the caller (handle_close() most likely), that there is
+ // no work to be done.
+ if (handle == ACE_INVALID_HANDLE)
+ {
+ return 0;
+ }
+
+ int id = -1;
+ {
+ ACE_GUARD_RETURN(ACE_Lock, ace_mon, *this->lock_, 0);
+
+ handle = eh->get_handle();
+ if(handle == ACE_INVALID_HANDLE)
+ {
+ return 0;
+ }
+
+ // Before closing the socket we need to remove ourselves from the
+ // Reactor. Sounds silly, as supposedly handle_close() was called
+ // *BY* the Reactor, but the Reactor calls handle_close() with
+ // only the masks implied by the handle_XXX() call that returned
+ // -1, and it does *NOT* remove the Event Handler from all masks.
+ // Furthermore, this method is also called outside the Reactor
+ // event loop, for example, when an I/O error is detected during a
+ // write().
+
+ // The following assertion is true because:
+ //
+ //
+ // 1) When a connection handler is initialized Transport is not zero
+ // and the handle is *NOT* ACE_INVALID_HANDLE.
+ // 2) The code here is run only once, if we get to this point the
+ // handle was not ACE_INVALID_HANDLE
+ // 3) this->transport() is only reset after we run this code
+ // successfully
+ //
+ // Or: for this code to run the handle must have changed state from
+ // something valid to ACE_INVALID_HANDLE, and the transport() field
+ // will not be changed before that state transition.
+ //
+ ACE_ASSERT(this->transport () != 0);
+
+ // Save the ID for debugging messages
+ id = this->transport()->id();
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, purging entry from cache\n",
+ id));
+ }
+ this->transport ()->purge_entry ();
+
+ // The Reactor must not be null, otherwise something else is
+ // horribly broken.
+ ACE_Reactor * reactor = this->transport()->orb_core()->reactor ();
+ ACE_ASSERT(reactor != 0);
+
+ {
+ ACE_Reactor * orb_core_reactor = this->orb_core_->reactor ();
+ ACE_ASSERT(reactor == orb_core_reactor);
+
+ ACE_Reactor * eh_reactor = eh->reactor ();
+ ACE_ASSERT(eh_reactor == 0 || eh_reactor == reactor);
+ }
+
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, removing from the reactor\n",
+ id));
+ }
+ int r =
+ reactor->remove_handler (handle,
+ (ACE_Event_Handler::ALL_EVENTS_MASK
+ | ACE_Event_Handler::DONT_CALL));
+ if(r == -1 && TAO_debug_level)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, error in remove_handler (%d)\n",
+ id, r));
+ }
+
+ // Also cancel any timers, we may create those for time-limited
+ // buffering
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, cancel all timers\n",
+ id));
+ }
+ r = reactor->cancel_timer (eh);
+ if (r == -1 && TAO_debug_level)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, error cancelling timers\n",
+ id));
+ }
+
+ // @@ This seems silly, the reactor is a much better authority to
+ // find out if a handle is registered...
+ this->transport ()->wait_strategy ()->is_registered (0);
+
+ // Close the socket, implicitly this makes:
+ // get_handle() == ACE_INVALID_HANDLE
+ // At this point any further calls to handle_close() or
+ // close_connection() become no-ops
+ r = this->release_os_resources ();
+ if (r == -1 && TAO_debug_level)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, release_os_resources() failed %p\n",
+ id, ""));
+ }
+
+ ACE_ASSERT(eh->get_handle() == ACE_INVALID_HANDLE);
+ }
+
+ ACE_ASSERT(this->transport () != 0);
+
+ this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED);
+
+ // Signal the transport that we will no longer have
+ // a reference to it. This will eventually call
+ // TAO_Transport::release ().
+ this->transport (0);
+
+ // The Reactor (or the Connector) holds an implicit reference.
+ // REFCNT: Matches start count
+ // REFCNT: only this or handle_input_eh() are called
+ long refcount = this->decr_refcount ();
+
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Connection_Handler[%d]::"
+ "close_connection, refcount = %d\n",
+ id, refcount));
+ }
+
+ return 1;
+}
+
+int
TAO_Connection_Handler::release_os_resources (void)
{
return 0;
diff --git a/TAO/tao/Connection_Handler.h b/TAO/tao/Connection_Handler.h
index 43724480e2e..c72d1c92c6f 100644
--- a/TAO/tao/Connection_Handler.h
+++ b/TAO/tao/Connection_Handler.h
@@ -69,8 +69,19 @@ public:
/// Increment and decrement the refcount. The object is deleted when
/// the refcount reaches zero.
- int incr_refcount (void);
- void decr_refcount (void);
+ long incr_refcount (void);
+ long decr_refcount (void);
+
+ /// Close the underlying connection.
+ /**
+ * Used by the ORB to actively close connections that are idle,
+ * stale or somehow are determined to be broken before the Reactor
+ * does.
+ *
+ * @return Return 0 if the connection was already closed, non-zero
+ * otherwise.
+ */
+ virtual int close_connection (void) = 0;
/// The event handler calls, here so that other objects who hold a
/// reference to this object can call the event handler methods.
@@ -103,9 +114,6 @@ protected:
/// Query the upcall count
int pending_upcalls (void) const;
- /// Shutdown the object
- virtual void handle_close_i (void) = 0;
-
//@{
/**
* @name Helper methods for Event_Handler-based derived classes.
@@ -122,16 +130,18 @@ protected:
unsigned long reactor_mask,
ACE_Event_Handler * eh);
- /// Implement the handle_close_i() template method.
- void handle_close_i_eh (ACE_Event_Handler * eh);
-
/// Implement the handle_output() callback
int handle_output_eh (ACE_HANDLE h, ACE_Event_Handler * eh);
/// Implement the handle_input() callback
int handle_input_eh (ACE_HANDLE h, ACE_Event_Handler * eh);
- /// Release the OS resources related to this handler, used in handle_close_eh()
+ /// Implement close_connection() for Connection_Handlers that are
+ /// also Event_Handlers.
+ int close_connection_eh (ACE_Event_Handler * eh);
+
+ /// Release the OS resources related to this handler, used in
+ /// handle_close_eh()
virtual int release_os_resources (void);
/// Pre-invocation hook for I/O operations (handle_input() &
@@ -159,25 +169,15 @@ private:
/// Cached tss resources of the ORB that activated this object.
TAO_ORB_Core_TSS_Resources *tss_resources_;
- /// Count nested upcalls on this
- /// svc_handler i.e., the connection can close during nested upcalls,
- /// you should not delete the svc_handler until the stack unwinds
- /// from the nested upcalls.
- long pending_upcalls_;
-
- /* Have a count of the number of references to the
- * handler. Theoretically this should be in the reactor. As we dont
- * have this in the reactor we are providing it here.
- *
- * NOTE: Please dont try to combine this with the pending
- * upcalls. They are for two completely different things.
- * @@todo: Need to be moved into the reactor at a later date
- */
+ /// Pretty obvious
long reference_count_;
- /// Lock for the <pending_upcalls_>. We can have more than one
- /// thread trying to access.
- ACE_Lock *pending_upcall_lock_;
+ /// Lock for the reference count
+ ACE_Lock *refcount_lock_;
+
+ /// Internal state lock, needs to be separate from the reference
+ /// count / pending upcalls lock because they interleave.
+ ACE_Lock * lock_;
};
#if defined (__ACE_INLINE__)
diff --git a/TAO/tao/Connection_Handler.inl b/TAO/tao/Connection_Handler.inl
index 0b8117b0b9c..5c1df839f72 100644
--- a/TAO/tao/Connection_Handler.inl
+++ b/TAO/tao/Connection_Handler.inl
@@ -2,16 +2,6 @@
//
//$Id$
-ACE_INLINE
-TAO_Connection_Handler::TAO_Connection_Handler (void)
- : orb_core_ (0),
- transport_ (0),
- tss_resources_ (0),
- pending_upcalls_ (1),
- pending_upcall_lock_ (0)
-{
-}
-
ACE_INLINE TAO_ORB_Core *
TAO_Connection_Handler::orb_core (void)
{
@@ -33,8 +23,7 @@ TAO_Connection_Handler::transport (void)
ACE_INLINE int
TAO_Connection_Handler::is_connect_complete (void) const
{
- return this->successful () ||
- this->error_detected ();
+ return this->successful () || this->error_detected ();
}
ACE_INLINE int
@@ -42,9 +31,3 @@ TAO_Connection_Handler::is_connect_successful (void) const
{
return (this->error_detected () == 0);
}
-
-ACE_INLINE int
-TAO_Connection_Handler::pending_upcalls (void) const
-{
- return this->pending_upcalls_;
-}
diff --git a/TAO/tao/Connector_Impl.cpp b/TAO/tao/Connector_Impl.cpp
index 757a511d2ae..a4bb4cee8c0 100644
--- a/TAO/tao/Connector_Impl.cpp
+++ b/TAO/tao/Connector_Impl.cpp
@@ -42,6 +42,8 @@ TAO_Connect_Creation_Strategy<SVC_HANDLER>::make_svc_handler (SVC_HANDLER *&sh)
// Add a reference count. Why is this needed? We need this to make
// sure that the connector doesnt delete this handler when we are
// waiting for non-blocking connects to complete.
+
+ // REFCNT: matches decr_refcount() in XXX_Connector::make_connection()
sh->incr_refcount ();
return 0;
diff --git a/TAO/tao/IIOP_Connection_Handler.cpp b/TAO/tao/IIOP_Connection_Handler.cpp
index 53702a5db48..50fccb14468 100644
--- a/TAO/tao/IIOP_Connection_Handler.cpp
+++ b/TAO/tao/IIOP_Connection_Handler.cpp
@@ -196,6 +196,12 @@ TAO_IIOP_Connection_Handler::resume_handler (void)
}
int
+TAO_IIOP_Connection_Handler::close_connection (void)
+{
+ return this->close_connection_eh (this);
+}
+
+int
TAO_IIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
return this->handle_input_eh (h, this);
@@ -214,12 +220,6 @@ TAO_IIOP_Connection_Handler::handle_close (ACE_HANDLE handle,
return this->handle_close_eh (handle, rm, this);
}
-void
-TAO_IIOP_Connection_Handler::handle_close_i (void)
-{
- this->handle_close_i_eh (this);
-}
-
int
TAO_IIOP_Connection_Handler::release_os_resources (void)
{
diff --git a/TAO/tao/IIOP_Connection_Handler.h b/TAO/tao/IIOP_Connection_Handler.h
index 4f626c49bcb..2868103c8d8 100644
--- a/TAO/tao/IIOP_Connection_Handler.h
+++ b/TAO/tao/IIOP_Connection_Handler.h
@@ -112,6 +112,7 @@ public:
/** @name Event Handler overloads
*/
virtual int resume_handler (void);
+ virtual int close_connection (void);
virtual int handle_input (ACE_HANDLE);
virtual int handle_output (ACE_HANDLE);
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
@@ -144,7 +145,6 @@ protected:
/**
* @name TAO_Connection Handler overloads
*/
- void handle_close_i (void);
virtual int release_os_resources (void);
//@}
diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp
index c76a1d6987e..fcbdfe29e52 100644
--- a/TAO/tao/IIOP_Connector.cpp
+++ b/TAO/tao/IIOP_Connector.cpp
@@ -202,6 +202,8 @@ TAO_IIOP_Connector::make_connection (TAO_GIOP_Invocation *invocation,
// increment to the handler is done in make_svc_handler (). Now
// that we dont need the reference to it anymore we can decrement
// the refcount whether the connection is successful ot not.
+
+ // REFCNT: Matches with TAO_Connect_Strategy<>::make_svc_handler()
svc_handler->decr_refcount ();
if (result == -1)
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp
index 839eff992d1..3b0e521da54 100644
--- a/TAO/tao/IIOP_Transport.cpp
+++ b/TAO/tao/IIOP_Transport.cpp
@@ -36,6 +36,13 @@ TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Connection_Handler *handler,
, connection_handler_ (handler)
, messaging_object_ (0)
{
+ if (connection_handler_ != 0)
+ {
+ // REFCNT: Matches one of
+ // TAO_Transport::connection_handler_close() or
+ // TAO_Transport::close_connection_shared.
+ this->connection_handler_->incr_refcount();
+ }
if (flag)
{
// Use the lite version of the protocol
@@ -51,8 +58,8 @@ TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Connection_Handler *handler,
}
TAO_IIOP_Transport::~TAO_IIOP_Transport (void)
-
{
+ ACE_ASSERT(this->connection_handler_ == 0);
delete this->messaging_object_;
}
@@ -449,10 +456,10 @@ TAO_IIOP_Transport::get_listen_point (
return 1;
}
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_IIOP_Transport::invalidate_event_handler_i (void)
{
- ACE_Event_Handler * eh = this->connection_handler_;
+ TAO_Connection_Handler * eh = this->connection_handler_;
this->connection_handler_ = 0;
return eh;
}
diff --git a/TAO/tao/IIOP_Transport.h b/TAO/tao/IIOP_Transport.h
index 5c77d336d66..ede1267e165 100644
--- a/TAO/tao/IIOP_Transport.h
+++ b/TAO/tao/IIOP_Transport.h
@@ -75,7 +75,7 @@ protected:
//@{
virtual ACE_Event_Handler * event_handler_i (void);
- virtual ACE_Event_Handler * invalidate_event_handler_i (void);
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void);
/// Access the underlying messaging object
virtual TAO_Pluggable_Messaging *messaging_object (void);
diff --git a/TAO/tao/Invocation.cpp b/TAO/tao/Invocation.cpp
index 2459e750f00..c48ddbe44d2 100644
--- a/TAO/tao/Invocation.cpp
+++ b/TAO/tao/Invocation.cpp
@@ -99,6 +99,9 @@ TAO_GIOP_Invocation::TAO_GIOP_Invocation (void)
received_location_forward_ (0),
profile_index_ (0)
{
+#if defined (ACE_HAS_PURIFY)
+ ACE_OS::memset(buffer_, 0, sizeof(buffer_));
+#endif /* ACE_HAS_PURIFY */
}
TAO_GIOP_Invocation::TAO_GIOP_Invocation (TAO_Stub *stub,
@@ -134,6 +137,9 @@ TAO_GIOP_Invocation::TAO_GIOP_Invocation (TAO_Stub *stub,
received_location_forward_ (0),
profile_index_ (0)
{
+#if defined (ACE_HAS_PURIFY)
+ ACE_OS::memset(buffer_, 0, sizeof(buffer_));
+#endif /* ACE_HAS_PURIFY */
}
TAO_GIOP_Invocation::~TAO_GIOP_Invocation (void)
diff --git a/TAO/tao/LF_Connect_Strategy.cpp b/TAO/tao/LF_Connect_Strategy.cpp
index 83ce6483ed1..e20cc3b3aa0 100644
--- a/TAO/tao/LF_Connect_Strategy.cpp
+++ b/TAO/tao/LF_Connect_Strategy.cpp
@@ -45,15 +45,26 @@ int
TAO_LF_Connect_Strategy::wait (TAO_Connection_Handler *ch,
ACE_Time_Value *max_wait_time)
{
- TAO_Transport *transport =
- ch->transport ();
+ ACE_ASSERT(ch != 0);
+
+ // @@todo We need to use a auto_ptr<>-like object here!
+ // TAO_Transport * transport = ch->get_transport_locked();
+ TAO_Transport *transport = ch->transport ();
+
+ // Basically the connection was EINPROGRESS, but before we could
+ // wait for it some other thread detected a failure and cleaned up
+ // the connection handler.
+ if(transport == 0)
+ {
+ return -1;
+ }
if (TAO_debug_level > 2)
{
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - LF_Connect_Strategy::wait, "
"waiting for Transport[%d]\n",
- transport->id()));
+ transport->id ()));
}
TAO_Leader_Follower &leader_follower =
@@ -76,5 +87,8 @@ TAO_LF_Connect_Strategy::wait (TAO_Connection_Handler *ch,
transport->id(), result));
}
+ // @@todo We need to use a auto_ptr<>-like object here!
+ // TAO_Transport::release(transport);
+
return result;
}
diff --git a/TAO/tao/Muxed_TMS.cpp b/TAO/tao/Muxed_TMS.cpp
index 88d7207d0e7..5f9a12bff1e 100644
--- a/TAO/tao/Muxed_TMS.cpp
+++ b/TAO/tao/Muxed_TMS.cpp
@@ -48,7 +48,8 @@ TAO_Muxed_TMS::request_id (void)
if (TAO_debug_level > 4)
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%P|%t) TAO_Muxed_TMS::request_id - <%d>\n"),
+ "TAO (%P|%t) - Muxed_TMS[%d]::request_id, <%d>\n",
+ this->transport_->id (),
this->request_id_generator_));
return this->request_id_generator_;
diff --git a/TAO/tao/Notify_Handler.cpp b/TAO/tao/Notify_Handler.cpp
index cb3b6391740..428644e2f34 100644
--- a/TAO/tao/Notify_Handler.cpp
+++ b/TAO/tao/Notify_Handler.cpp
@@ -8,8 +8,19 @@ ACE_RCSID (tao,
Notify_Handler,
"$Id$")
+TAO_Notify_Handler::TAO_Notify_Handler (TAO_Connection_Handler *ch,
+ ACE_Allocator *alloc)
+ : ACE_Event_Handler (ch->transport ()->orb_core ()->reactor ()),
+ ch_ (ch),
+ allocator_ (alloc)
+{
+ // REFCNT: Matches with Notify_Handler::~Notify_Handler()
+ this->ch_->incr_refcount ();
+}
+
TAO_Notify_Handler::~TAO_Notify_Handler (void)
{
+ // REFCNT: Matches with Notify_Handler::Notify_Handler()
this->ch_->decr_refcount ();
}
@@ -69,13 +80,3 @@ TAO_Notify_Handler::handle_close (ACE_HANDLE /*fd*/,
TAO_Notify_Handler::destroy_handler (this);
return 0;
}
-
-
-TAO_Notify_Handler::TAO_Notify_Handler (TAO_Connection_Handler *ch,
- ACE_Allocator *alloc)
- : ACE_Event_Handler (ch->transport ()->orb_core ()->reactor ()),
- ch_ (ch),
- allocator_ (alloc)
-{
- this->ch_->incr_refcount ();
-}
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
index 7eff396e38a..5dbad7978d5 100644
--- a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
@@ -208,6 +208,12 @@ TAO_DIOP_Connection_Handler::resume_handler (void)
}
int
+TAO_DIOP_Connection_Handler::close_connection (void)
+{
+ return this->close_connection_eh (this);
+}
+
+int
TAO_DIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
return this->handle_input_eh (h, this);
@@ -226,12 +232,6 @@ TAO_DIOP_Connection_Handler::handle_close (ACE_HANDLE handle,
return this->handle_close_eh (handle, rm, this);
}
-void
-TAO_DIOP_Connection_Handler::handle_close_i (void)
-{
- this->handle_close_i_eh (this);
-}
-
int
TAO_DIOP_Connection_Handler::release_os_resources (void)
{
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.h b/TAO/tao/Strategies/DIOP_Connection_Handler.h
index 861ee92bec5..7a021b3cee0 100644
--- a/TAO/tao/Strategies/DIOP_Connection_Handler.h
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.h
@@ -115,6 +115,7 @@ public:
/** @name Event Handler overloads
*/
virtual int resume_handler (void);
+ virtual int close_connection (void);
virtual int handle_input (ACE_HANDLE);
virtual int handle_output (ACE_HANDLE);
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
@@ -159,7 +160,6 @@ protected:
/**
* @name TAO_Connection Handler overloads
*/
- void handle_close_i (void);
virtual int release_os_resources (void);
//@}
diff --git a/TAO/tao/Strategies/DIOP_Transport.cpp b/TAO/tao/Strategies/DIOP_Transport.cpp
index 3047e157f95..82274b7cec7 100644
--- a/TAO/tao/Strategies/DIOP_Transport.cpp
+++ b/TAO/tao/Strategies/DIOP_Transport.cpp
@@ -36,6 +36,13 @@ TAO_DIOP_Transport::TAO_DIOP_Transport (TAO_DIOP_Connection_Handler *handler,
, connection_handler_ (handler)
, messaging_object_ (0)
{
+ if (connection_handler_ != 0)
+ {
+ // REFCNT: Matches one of
+ // TAO_Transport::connection_handler_close() or
+ // TAO_Transport::close_connection_shared.
+ this->connection_handler_->incr_refcount();
+ }
// @@ Michael: Set the input CDR size to ACE_MAX_DGRAM_SIZE so that
// we read the whole UDP packet on a single read.
if (flag)
@@ -56,6 +63,7 @@ TAO_DIOP_Transport::TAO_DIOP_Transport (TAO_DIOP_Connection_Handler *handler,
TAO_DIOP_Transport::~TAO_DIOP_Transport (void)
{
+ ACE_ASSERT(this->connection_handler_ == 0);
delete this->messaging_object_;
}
@@ -470,10 +478,10 @@ TAO_DIOP_Transport::get_listen_point (
}
*/
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_DIOP_Transport::invalidate_event_handler_i (void)
{
- ACE_Event_Handler * eh = this->connection_handler_;
+ TAO_Connection_Handler * eh = this->connection_handler_;
this->connection_handler_ = 0;
return eh;
}
diff --git a/TAO/tao/Strategies/DIOP_Transport.h b/TAO/tao/Strategies/DIOP_Transport.h
index 7c42929342b..c47c60d1a93 100644
--- a/TAO/tao/Strategies/DIOP_Transport.h
+++ b/TAO/tao/Strategies/DIOP_Transport.h
@@ -75,7 +75,7 @@ protected:
virtual ACE_Event_Handler * event_handler_i (void);
virtual TAO_Connection_Handler *connection_handler_i (void);
- virtual ACE_Event_Handler * invalidate_event_handler_i (void);
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void);
virtual TAO_Pluggable_Messaging *messaging_object (void);
/// Write the complete Message_Block chain to the connection.
diff --git a/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp b/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp
index 4fc91e75f87..a419525fd1e 100644
--- a/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp
@@ -169,6 +169,12 @@ TAO_SHMIOP_Connection_Handler::resume_handler (void)
}
int
+TAO_SHMIOP_Connection_Handler::close_connection (void)
+{
+ return this->close_connection_eh (this);
+}
+
+int
TAO_SHMIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
return this->handle_input_eh (h, this);
@@ -187,12 +193,6 @@ TAO_SHMIOP_Connection_Handler::handle_close (ACE_HANDLE handle,
return this->handle_close_eh (handle, rm, this);
}
-void
-TAO_SHMIOP_Connection_Handler::handle_close_i (void)
-{
- this->handle_close_i_eh (this);
-}
-
int
TAO_SHMIOP_Connection_Handler::release_os_resources (void)
{
diff --git a/TAO/tao/Strategies/SHMIOP_Connection_Handler.h b/TAO/tao/Strategies/SHMIOP_Connection_Handler.h
index 863ddeefeca..6995d830a25 100644
--- a/TAO/tao/Strategies/SHMIOP_Connection_Handler.h
+++ b/TAO/tao/Strategies/SHMIOP_Connection_Handler.h
@@ -85,6 +85,7 @@ public:
/** @name Event Handler overloads
*/
virtual int resume_handler (void);
+ virtual int close_connection (void);
virtual int handle_input (ACE_HANDLE);
virtual int handle_output (ACE_HANDLE);
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
@@ -99,7 +100,6 @@ protected:
/**
* @name TAO_Connection Handler overloads
*/
- void handle_close_i (void);
virtual int release_os_resources (void);
//@}
diff --git a/TAO/tao/Strategies/SHMIOP_Transport.cpp b/TAO/tao/Strategies/SHMIOP_Transport.cpp
index 521291088da..7ce4130fa5b 100644
--- a/TAO/tao/Strategies/SHMIOP_Transport.cpp
+++ b/TAO/tao/Strategies/SHMIOP_Transport.cpp
@@ -34,6 +34,13 @@ TAO_SHMIOP_Transport::TAO_SHMIOP_Transport (TAO_SHMIOP_Connection_Handler *handl
connection_handler_ (handler),
messaging_object_ (0)
{
+ if (connection_handler_ != 0)
+ {
+ // REFCNT: Matches one of
+ // TAO_Transport::connection_handler_close() or
+ // TAO_Transport::close_connection_shared.
+ this->connection_handler_->incr_refcount();
+ }
if (flag)
{
// Use the lite version of the protocol
@@ -50,6 +57,7 @@ TAO_SHMIOP_Transport::TAO_SHMIOP_Transport (TAO_SHMIOP_Connection_Handler *handl
TAO_SHMIOP_Transport::~TAO_SHMIOP_Transport (void)
{
+ ACE_ASSERT(this->connection_handler_ == 0);
delete this->messaging_object_;
}
@@ -281,10 +289,10 @@ TAO_SHMIOP_Transport::messaging_init (CORBA::Octet major,
return 1;
}
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_SHMIOP_Transport::invalidate_event_handler_i (void)
{
- ACE_Event_Handler * eh = this->connection_handler_;
+ TAO_Connection_Handler * eh = this->connection_handler_;
this->connection_handler_ = 0;
return eh;
}
diff --git a/TAO/tao/Strategies/SHMIOP_Transport.h b/TAO/tao/Strategies/SHMIOP_Transport.h
index 21430b34000..b41197303ae 100644
--- a/TAO/tao/Strategies/SHMIOP_Transport.h
+++ b/TAO/tao/Strategies/SHMIOP_Transport.h
@@ -69,8 +69,7 @@ protected:
//@{
virtual ACE_Event_Handler * event_handler_i (void);
virtual TAO_Connection_Handler *connection_handler_i (void);
- virtual ACE_Event_Handler * invalidate_event_handler_i (void);
-
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void);
virtual TAO_Pluggable_Messaging *messaging_object (void);
/// Write the complete Message_Block chain to the connection.
diff --git a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
index 8093f178a7d..51e02d17761 100644
--- a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
@@ -152,6 +152,12 @@ TAO_UIOP_Connection_Handler::resume_handler (void)
}
int
+TAO_UIOP_Connection_Handler::close_connection (void)
+{
+ return this->close_connection_eh (this);
+}
+
+int
TAO_UIOP_Connection_Handler::handle_input (ACE_HANDLE h)
{
return this->handle_input_eh (h, this);
@@ -170,12 +176,6 @@ TAO_UIOP_Connection_Handler::handle_close (ACE_HANDLE handle,
return this->handle_close_eh (handle, rm, this);
}
-void
-TAO_UIOP_Connection_Handler::handle_close_i (void)
-{
- this->handle_close_i_eh (this);
-}
-
int
TAO_UIOP_Connection_Handler::release_os_resources (void)
{
diff --git a/TAO/tao/Strategies/UIOP_Connection_Handler.h b/TAO/tao/Strategies/UIOP_Connection_Handler.h
index bb1eb7ee2af..4a86e13dd64 100644
--- a/TAO/tao/Strategies/UIOP_Connection_Handler.h
+++ b/TAO/tao/Strategies/UIOP_Connection_Handler.h
@@ -104,6 +104,7 @@ public:
/** @name Event Handler overloads
*/
virtual int resume_handler (void);
+ virtual int close_connection (void);
virtual int handle_input (ACE_HANDLE);
virtual int handle_output (ACE_HANDLE);
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
@@ -118,7 +119,6 @@ protected:
/**
* @name TAO_Connection Handler overloads
*/
- void handle_close_i (void);
virtual int release_os_resources (void);
//@}
diff --git a/TAO/tao/Strategies/UIOP_Transport.cpp b/TAO/tao/Strategies/UIOP_Transport.cpp
index 46056bcbe8a..14823585184 100644
--- a/TAO/tao/Strategies/UIOP_Transport.cpp
+++ b/TAO/tao/Strategies/UIOP_Transport.cpp
@@ -33,6 +33,13 @@ TAO_UIOP_Transport::TAO_UIOP_Transport (TAO_UIOP_Connection_Handler *handler,
, connection_handler_ (handler)
, messaging_object_ (0)
{
+ if (connection_handler_ != 0)
+ {
+ // REFCNT: Matches one of
+ // TAO_Transport::connection_handler_close() or
+ // TAO_Transport::close_connection_shared.
+ this->connection_handler_->incr_refcount();
+ }
if (flag)
{
// Use the lite version of the protocol
@@ -49,6 +56,7 @@ TAO_UIOP_Transport::TAO_UIOP_Transport (TAO_UIOP_Connection_Handler *handler,
TAO_UIOP_Transport::~TAO_UIOP_Transport (void)
{
+ ACE_ASSERT(this->connection_handler_ == 0);
delete this->messaging_object_;
}
@@ -211,10 +219,10 @@ TAO_UIOP_Transport::messaging_init (CORBA::Octet major,
return 1;
}
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_UIOP_Transport::invalidate_event_handler_i (void)
{
- ACE_Event_Handler * eh = this->connection_handler_;
+ TAO_Connection_Handler * eh = this->connection_handler_;
this->connection_handler_ = 0;
return eh;
}
diff --git a/TAO/tao/Strategies/UIOP_Transport.h b/TAO/tao/Strategies/UIOP_Transport.h
index 082bd31e7b6..cb504621570 100644
--- a/TAO/tao/Strategies/UIOP_Transport.h
+++ b/TAO/tao/Strategies/UIOP_Transport.h
@@ -68,8 +68,7 @@ protected:
virtual ACE_Event_Handler * event_handler_i (void);
virtual TAO_Connection_Handler *connection_handler_i (void);
- virtual ACE_Event_Handler * invalidate_event_handler_i (void);
-
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void);
virtual TAO_Pluggable_Messaging *messaging_object (void);
/// Write the complete Message_Block chain to the connection.
diff --git a/TAO/tao/Synch_Refcountable.cpp b/TAO/tao/Synch_Refcountable.cpp
index 4bd6b1fc0ab..05f2a835ad1 100644
--- a/TAO/tao/Synch_Refcountable.cpp
+++ b/TAO/tao/Synch_Refcountable.cpp
@@ -18,5 +18,6 @@ TAO_Synch_Refcountable::TAO_Synch_Refcountable (ACE_Lock *lock,
TAO_Synch_Refcountable::~TAO_Synch_Refcountable (void)
{
+ ACE_ASSERT(this->refcount_ == 0);
delete this->refcount_lock_;
}
diff --git a/TAO/tao/TAO_Server_Request.cpp b/TAO/tao/TAO_Server_Request.cpp
index c4b8c4a7759..2dd24445b54 100644
--- a/TAO/tao/TAO_Server_Request.cpp
+++ b/TAO/tao/TAO_Server_Request.cpp
@@ -278,7 +278,7 @@ TAO_ServerRequest::tao_send_reply_exception (CORBA::Exception &ex)
// Create a new output CDR stream
-# if 0
+#if 0
#if defined(ACE_HAS_PURIFY)
// Only inititialize the buffer if we're compiling with Purify.
// Otherwise, there is no real need to do so, especially since
@@ -288,8 +288,6 @@ TAO_ServerRequest::tao_send_reply_exception (CORBA::Exception &ex)
#else
char repbuf[ACE_CDR::DEFAULT_BUFSIZE];
#endif /* ACE_HAS_PURIFY */
-#endif /*if 0*/
- /*
TAO_OutputCDR output (repbuf,
sizeof repbuf,
TAO_ENCAP_BYTE_ORDER,
@@ -301,6 +299,7 @@ TAO_ServerRequest::tao_send_reply_exception (CORBA::Exception &ex)
TAO_DEF_GIOP_MINOR,
this->orb_core_->to_iso8859 (),
this->orb_core_->to_unicode ());*/
+#endif /* 0 */
// Make the reply message
if (this->mesg_base_->generate_exception_reply (*this->outgoing_,
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index e2859142b3d..a6a0bc92830 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -126,25 +126,18 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
TAO_Transport::~TAO_Transport (void)
{
+ ACE_ASSERT(this->refcount() == 0);
+
delete this->ws_;
- this->ws_ = 0;
delete this->tms_;
- this->tms_ = 0;
delete this->handler_lock_;
- while (this->head_ != 0)
- {
- TAO_Queued_Message *i = this->head_;
- this->head_ = i->next ();
- i->destroy ();
- }
-
- // Avoid making the call if we can. This may be redundant, unless
- // someone called handle_close() on the connection handler from
- // outside the TAO_Transport.
- this->transport_cache_manager ().purge_entry (this->cache_map_entry_);
+ // By the time the destructor is reached all the connection stuff
+ // *must* have been cleaned up
+ ACE_ASSERT(this->head_ == 0);
+ ACE_ASSERT(this->cache_map_entry_ == 0);
}
@@ -280,7 +273,7 @@ TAO_Transport::tear_listen_point_list (TAO_InputCDR &)
void
TAO_Transport::close_connection (void)
{
- ACE_Event_Handler * eh = this->invalidate_event_handler ();
+ TAO_Connection_Handler * eh = this->invalidate_event_handler ();
this->close_connection_shared (1, eh);
}
@@ -344,12 +337,15 @@ TAO_Transport::connection_handler_closing (void)
// error. Basically all the other methods in the Transport
// cooperate via check_event_handler_i()
- (void) this->invalidate_event_handler ();
+ TAO_Connection_Handler * eh = this->invalidate_event_handler ();
this->send_connection_closed_notifications ();
- // Can't hold the lock while we release, b/c the release could
- // invoke the destructor! This should be the last thing we do here
- TAO_Transport::release (this);
+ if (eh != 0)
+ {
+ // REFCNT: Matches incr_refcnt in XXX_Transport::XXX_Transport
+ // REFCNT: Only one of this or close_connection_shared() run
+ eh->decr_refcount();
+ }
}
int
@@ -669,21 +665,20 @@ TAO_Transport::send_synch_message_helper_i (TAO_Synch_Queued_Message &synch_mess
void
TAO_Transport::close_connection_i (void)
{
- ACE_Event_Handler * eh = this->invalidate_event_handler_i ();
+ TAO_Connection_Handler * eh = this->invalidate_event_handler_i ();
this->close_connection_shared (1, eh);
}
void
TAO_Transport::close_connection_no_purge (void)
{
- ACE_Event_Handler * eh = this->invalidate_event_handler ();
+ TAO_Connection_Handler * eh = this->invalidate_event_handler ();
this->close_connection_shared (0, eh);
}
-
void
TAO_Transport::close_connection_shared (int disable_purge,
- ACE_Event_Handler * eh)
+ TAO_Connection_Handler * eh)
{
// Purge the entry
if (!disable_purge)
@@ -697,30 +692,13 @@ TAO_Transport::close_connection_shared (int disable_purge,
return;
}
- int retval = 0;
-
- // We first try to remove the handler from the reactor. After that
- // we destroy the handler using handle_close (). The remove handler
- // is necessary because if the handle_closed is called directly, the
- // reactor would be left with a dangling pointer.
- if (this->ws_->is_registered ())
- {
- retval = this->orb_core_->reactor ()->remove_handler (
- eh,
- ACE_Event_Handler::ALL_EVENTS_MASK |
- ACE_Event_Handler::DONT_CALL);
- }
-
- // Yet another protocol using the Reactor. If a thread is not able
- // to remove the handler from the Reactor, then he has no business
- // to close down the handler.
- if (retval == 0)
- {
- (void) eh->handle_close (ACE_INVALID_HANDLE,
- ACE_Event_Handler::ALL_EVENTS_MASK);
- }
+ eh->close_connection ();
this->send_connection_closed_notifications ();
+
+ // REFCNT: Matches incr_refcnt in XXX_Transport::XXX_Transport
+ // REFCNT: Only one of this or connection_handler_closing() run
+ eh->decr_refcount ();
}
int
@@ -1062,13 +1040,13 @@ TAO_Transport::report_invalid_event_handler (const char *caller)
if (TAO_debug_level > 0)
{
ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) - Transport[%d]::report_invalid_event_handler"
+ "TAO (%P|%t) - Transport[%d]::report_invalid_event_handler"
"(%s) no longer associated with handler [tag=%d]\n",
this->id (), caller, this->tag_));
}
}
-ACE_Event_Handler *
+TAO_Connection_Handler *
TAO_Transport::invalidate_event_handler (void)
{
ACE_MT (ACE_GUARD_RETURN (ACE_Lock, guard, *this->handler_lock_, 0));
@@ -1079,6 +1057,14 @@ TAO_Transport::invalidate_event_handler (void)
void
TAO_Transport::send_connection_closed_notifications (void)
{
+ ACE_MT (ACE_GUARD (ACE_Lock, guard, *this->handler_lock_));
+
+ this->send_connection_closed_notifications_i ();
+}
+
+void
+TAO_Transport::send_connection_closed_notifications_i (void)
+{
while (this->head_ != 0)
{
TAO_Queued_Message *i = this->head_;
@@ -1160,6 +1146,14 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub,
// server ...
if (errno != EWOULDBLOCK && errno != ETIME)
{
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Transport[%d]::send_message_i, "
+ "fatal error in "
+ "send_message_block_chain_i %p\n",
+ this->id (), ""));
+ }
return -1;
}
}
diff --git a/TAO/tao/Transport.h b/TAO/tao/Transport.h
index b3a3426d3a0..1f0afb780ef 100644
--- a/TAO/tao/Transport.h
+++ b/TAO/tao/Transport.h
@@ -459,7 +459,7 @@ protected:
*
* @return The old event handler
*/
- virtual ACE_Event_Handler * invalidate_event_handler_i (void) = 0;
+ virtual TAO_Connection_Handler * invalidate_event_handler_i (void) = 0;
/// Return the messaging object that is used to format the data that
/// needs to be sent.
@@ -845,7 +845,7 @@ private:
/// not pending
void reset_flush_timer (void);
-
+
/// Print out error messages if the event handler is not valid
void report_invalid_event_handler (const char *caller);
@@ -863,12 +863,15 @@ private:
int notify_reactor (void);
/// Grab the mutex and then call invalidate_event_handler_i()
- ACE_Event_Handler * invalidate_event_handler (void);
+ TAO_Connection_Handler * invalidate_event_handler (void);
/// Notify all the components inside a Transport when the underlying
/// connection is closed.
void send_connection_closed_notifications (void);
+ /// Assume the lock is held
+ void send_connection_closed_notifications_i (void);
+
/// Implement close_connection() assuming the handler_lock_ is held.
void close_connection_i (void);
@@ -883,7 +886,7 @@ private:
/// Close the underlying connection, implements the code shared by
/// all the close_connection_* variants.
void close_connection_shared (int disable_purge,
- ACE_Event_Handler * eh);
+ TAO_Connection_Handler * eh);
/// Prohibited
ACE_UNIMPLEMENTED_FUNC (TAO_Transport (const TAO_Transport&))