From 15ea7d66b8a06acba82534d027b13a24762a8669 Mon Sep 17 00:00:00 2001 From: coryan Date: Mon, 5 Mar 2007 18:04:10 +0000 Subject: Mon Mar 5 18:01:36 UTC 2007 Carlos O'Ryan --- ACE/ChangeLog | 14 ++++++++++++++ ACE/ace/Notification_Queue.cpp | 14 +++++++++++--- ACE/ace/Select_Reactor_Base.cpp | 13 +++++++++++++ ACE/tests/run_test.lst | 1 + 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/ACE/ChangeLog b/ACE/ChangeLog index e59e8b67aff..b4d3394f0c0 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,17 @@ +Mon Mar 5 18:01:36 UTC 2007 Carlos O'Ryan + + * ace/Notification_Queue.cpp: + When deleting the queue we must decrease the reference count on + all the event handlers stored there. + + * ace/Select_Reactor_Base.cpp: + When the notification pipe is destroyed we must read the data + stored there and release all the event handlers. Otherwise the + reference counts are broken. + + * tests/run_test.lst: + Add Bug_2820_Regression_Test to the list. + Mon Mar 5 17:16:16 UTC 2007 Carlos O'Ryan * tests/Bug_2820_Regression_Test.cpp: diff --git a/ACE/ace/Notification_Queue.cpp b/ACE/ace/Notification_Queue.cpp index 0b2ca59e831..f8985f8060f 100644 --- a/ACE/ace/Notification_Queue.cpp +++ b/ACE/ace/Notification_Queue.cpp @@ -41,9 +41,16 @@ reset() { ACE_TRACE ("ACE_Notification_Queue::reset"); - // Free up the dynamically allocated resources. - ACE_Notification_Queue_Node **b = 0; + // Release all the event handlers still in the queue ... + for (ACE_Notification_Queue_Node * node = notify_queue_.head(); + node != 0; + node = node->next()) + { + (void) node->get().eh_->remove_reference(); + } + // ... free up the dynamically allocated resources ... + ACE_Notification_Queue_Node **b = 0; for (ACE_Unbounded_Queue_Iterator alloc_iter (this->alloc_queue_); alloc_iter.next (b) != 0; alloc_iter.advance ()) @@ -52,9 +59,10 @@ reset() *b = 0; } + // ... cleanup the list of allocated blocks ... this->alloc_queue_.reset (); - // Swap with an empty list to reset the contents + // ... swap with empty lists to reset the contents ... Buffer_List().swap(notify_queue_); Buffer_List().swap(free_queue_); } diff --git a/ACE/ace/Select_Reactor_Base.cpp b/ACE/ace/Select_Reactor_Base.cpp index 0306fc7007a..73412037931 100644 --- a/ACE/ace/Select_Reactor_Base.cpp +++ b/ACE/ace/Select_Reactor_Base.cpp @@ -640,6 +640,19 @@ ACE_Select_Reactor_Notify::close (void) #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) notification_queue_.reset(); +#else + // Please see Bug 2820, if we just close the pipe then we break the + // reference counting rules. Basically, all the event handlers + // "stored" in the pipe had their reference counts increased. We + // need to decrease them before closing the pipe.... + ACE_Notification_Buffer b; + for (int r = 0; + r = read_notify_pipe(notification_pipe_.read_handle(), b); + r != -1) + { + if (b.eh_ == 0) continue; + b.eh_->remove_reference(); + } #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ return this->notification_pipe_.close (); diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst index 10e6e76a8a0..a9e36f266f0 100644 --- a/ACE/tests/run_test.lst +++ b/ACE/tests/run_test.lst @@ -37,6 +37,7 @@ Bug_2540_Regression_Test Bug_2659_Regression_Test: !ST Bug_2653_Regression_Test: !ST Bug_2815_Regression_Test +Bug_2820_Regression_Test CDR_Array_Test: !ACE_FOR_TAO CDR_File_Test: !ACE_FOR_TAO CDR_Test -- cgit v1.2.1