summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcorino <mcorino@users.noreply.github.com>2011-12-19 13:38:49 +0000
committermcorino <mcorino@users.noreply.github.com>2011-12-19 13:38:49 +0000
commit6a490b646bb1389e01575026ae0ea1430d58d837 (patch)
treef52ef403e37a2e1303f3e8ae692e099338dfada1
parentde9d4fad74b7b026ce6679f9137c097a080cb4f0 (diff)
downloadATCD-6a490b646bb1389e01575026ae0ea1430d58d837.tar.gz
Mon Dec 19 13:28:16 UTC 2011 Martin Corino <mcorino@remedy.nl>
* ace/Abstract_Timer_Queue.h: * ace/Timer_Hash_T.h: * ace/Timer_Hash_T.cpp: * ace/Timer_Heap_T.h: * ace/Timer_Heap_T.cpp: * ace/Timer_List_T.h: * ace/Timer_List_T.cpp: * ace/Timer_Queue_Adapters.inl: * ace/Timer_Queue_Adapters.cpp: * ace/Timer_Wheel_T.h: * ace/Timer_Wheel_T.cpp: Added close() method. * ace/Dev_Poll_Reactor.cpp: * ace/Proactor.cpp: * ace/Select_Reactor_T.cpp: * ace/WFMO_Reactor.cpp: Implemented support for timer queue close (). The rationale for these changes is that when using reactors with user defined timer queues the reactor does not delete the timer queue when being deleted itself. Without any other cleanup this created the possibility (as encountered in TAO/tests/Bug_3837_Regression after introduction of the TIME_POLICY changes) of outstanding timer handlers in the queue being triggered and attempting to access the reactor after the reactor has been destroyed. Calling close () for timer queues the reactor does not delete solves this potential problem.
-rw-r--r--ACE/ChangeLog33
-rw-r--r--ACE/ace/Abstract_Timer_Queue.h5
-rw-r--r--ACE/ace/Dev_Poll_Reactor.cpp8
-rw-r--r--ACE/ace/Proactor.cpp9
-rw-r--r--ACE/ace/Select_Reactor_T.cpp14
-rw-r--r--ACE/ace/Timer_Hash_T.cpp23
-rw-r--r--ACE/ace/Timer_Hash_T.h5
-rw-r--r--ACE/ace/Timer_Heap_T.cpp39
-rw-r--r--ACE/ace/Timer_Heap_T.h5
-rw-r--r--ACE/ace/Timer_List_T.cpp17
-rw-r--r--ACE/ace/Timer_List_T.h5
-rw-r--r--ACE/ace/Timer_Queue_Adapters.cpp5
-rw-r--r--ACE/ace/Timer_Queue_Adapters.inl2
-rw-r--r--ACE/ace/Timer_Wheel_T.cpp22
-rw-r--r--ACE/ace/Timer_Wheel_T.h5
-rw-r--r--ACE/ace/WFMO_Reactor.cpp17
16 files changed, 192 insertions, 22 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index 72f69d1967c..9705f2b0fa3 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,36 @@
+Mon Dec 19 13:28:16 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Abstract_Timer_Queue.h:
+ * ace/Timer_Hash_T.h:
+ * ace/Timer_Hash_T.cpp:
+ * ace/Timer_Heap_T.h:
+ * ace/Timer_Heap_T.cpp:
+ * ace/Timer_List_T.h:
+ * ace/Timer_List_T.cpp:
+ * ace/Timer_Queue_Adapters.inl:
+ * ace/Timer_Queue_Adapters.cpp:
+ * ace/Timer_Wheel_T.h:
+ * ace/Timer_Wheel_T.cpp:
+
+ Added close() method.
+
+ * ace/Dev_Poll_Reactor.cpp:
+ * ace/Proactor.cpp:
+ * ace/Select_Reactor_T.cpp:
+ * ace/WFMO_Reactor.cpp:
+
+ Implemented support for timer queue close ().
+
+ The rationale for these changes is that when using reactors with
+ user defined timer queues the reactor does not delete the timer queue
+ when being deleted itself. Without any other cleanup this created the
+ possibility (as encountered in TAO/tests/Bug_3837_Regression after
+ introduction of the TIME_POLICY changes) of outstanding timer handlers
+ in the queue being triggered and attempting to access the reactor after
+ the reactor has been destroyed.
+ Calling close () for timer queues the reactor does not delete solves
+ this potential problem.
+
Mon Dec 19 12:12:37 UTC 2011 Johnny Willemsen <jwillemsen@remedy.nl>
* bin/fuzz.pl:
diff --git a/ACE/ace/Abstract_Timer_Queue.h b/ACE/ace/Abstract_Timer_Queue.h
index 7c52e397826..258cd8cb2dd 100644
--- a/ACE/ace/Abstract_Timer_Queue.h
+++ b/ACE/ace/Abstract_Timer_Queue.h
@@ -158,6 +158,11 @@ public:
int dont_call_handle_close = 1) = 0;
/**
+ * Close timer queue. Cancels all timers.
+ */
+ virtual int close (void) = 0;
+
+ /**
* Returns the current time of day. This method allows different
* implementations of the timer queue to use special high resolution
* timers.
diff --git a/ACE/ace/Dev_Poll_Reactor.cpp b/ACE/ace/Dev_Poll_Reactor.cpp
index 6da3c4b5bb3..101777fe34b 100644
--- a/ACE/ace/Dev_Poll_Reactor.cpp
+++ b/ACE/ace/Dev_Poll_Reactor.cpp
@@ -802,12 +802,13 @@ ACE_Dev_Poll_Reactor::timer_queue (ACE_Timer_Queue *tq)
{
if (this->delete_timer_queue_)
delete this->timer_queue_;
+ else if (this->timer_queue_)
+ this->timer_queue_->close ();
this->timer_queue_ = tq;
this->delete_timer_queue_ = false;
return 0;
-
}
ACE_Timer_Queue *
@@ -859,6 +860,11 @@ ACE_Dev_Poll_Reactor::close (void)
this->timer_queue_ = 0;
this->delete_timer_queue_ = false;
}
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ this->timer_queue_ = 0;
+ }
if (this->notify_handler_ != 0)
this->notify_handler_->close ();
diff --git a/ACE/ace/Proactor.cpp b/ACE/ace/Proactor.cpp
index 9606917872d..b757b43e27f 100644
--- a/ACE/ace/Proactor.cpp
+++ b/ACE/ace/Proactor.cpp
@@ -638,6 +638,11 @@ ACE_Proactor::close (void)
this->timer_queue_ = 0;
this->delete_timer_queue_ = 0;
}
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ this->timer_queue_ = 0;
+ }
return 0;
}
@@ -768,6 +773,10 @@ ACE_Proactor::timer_queue (ACE_Proactor_Timer_Queue *tq)
delete this->timer_queue_;
this->delete_timer_queue_ = 0;
}
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ }
// New timer queue.
if (tq == 0)
diff --git a/ACE/ace/Select_Reactor_T.cpp b/ACE/ace/Select_Reactor_T.cpp
index 3fb2ebfe4e9..66bc3b92241 100644
--- a/ACE/ace/Select_Reactor_T.cpp
+++ b/ACE/ace/Select_Reactor_T.cpp
@@ -461,7 +461,14 @@ template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::timer_queue
(ACE_Timer_Queue *tq)
{
- delete this->timer_queue_;
+ if (this->delete_timer_queue_)
+ {
+ delete this->timer_queue_;
+ }
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ }
this->timer_queue_ = tq;
this->delete_timer_queue_ = false;
return 0;
@@ -576,6 +583,11 @@ ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::close (void)
this->timer_queue_ = 0;
this->delete_timer_queue_ = false;
}
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ this->timer_queue_ = 0;
+ }
if (this->notify_handler_ != 0)
this->notify_handler_->close ();
diff --git a/ACE/ace/Timer_Hash_T.cpp b/ACE/ace/Timer_Hash_T.cpp
index 9b9767f13ff..2965ae2dc77 100644
--- a/ACE/ace/Timer_Hash_T.cpp
+++ b/ACE/ace/Timer_Hash_T.cpp
@@ -349,14 +349,37 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::~ACE_Timer_Hash_
delete iterator_;
+ this->close ();
+
for (size_t i = 0;
i < this->table_size_;
++i)
delete this->table_[i];
+
delete [] this->table_;
}
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> int
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::close (void)
+{
+ ACE_TRACE ("ACE_Timer_Hash_T::close");
+ ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
+
+ // Remove all remaining items from the queue.
+ while (!this->is_empty())
+ {
+ ACE_Timer_Node_T<TYPE>* n = this->remove_first();
+ this->upcall_functor ().deletion (*this,
+ n->get_type(),
+ n->get_act());
+ this->free_node (n);
+ }
+
+ // leave the rest to destructor
+ return 0;
+}
+
// Checks if queue is empty.
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> bool
diff --git a/ACE/ace/Timer_Hash_T.h b/ACE/ace/Timer_Hash_T.h
index 486508e24f0..6d488d60cf4 100644
--- a/ACE/ace/Timer_Hash_T.h
+++ b/ACE/ace/Timer_Hash_T.h
@@ -243,6 +243,11 @@ public:
int dont_call_handle_close = 1);
/**
+ * Destroy timer queue. Cancels all timers.
+ */
+ virtual int close (void);
+
+ /**
* Run the <functor> for all timers whose values are <=
* gettimeofday. Also accounts for <timer_skew>. Returns
* the number of timers canceled.
diff --git a/ACE/ace/Timer_Heap_T.cpp b/ACE/ace/Timer_Heap_T.cpp
index 47ad9994b98..411d0be5eb8 100644
--- a/ACE/ace/Timer_Heap_T.cpp
+++ b/ACE/ace/Timer_Heap_T.cpp
@@ -212,6 +212,29 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Heap_T (void)
delete iterator_;
+ this->close ();
+
+ delete [] this->heap_;
+ delete [] this->timer_ids_;
+
+ // clean up any preallocated timer nodes
+ if (preallocated_nodes_ != 0)
+ {
+ ACE_Unbounded_Set_Iterator<ACE_Timer_Node_T<TYPE> *>
+ set_iterator (this->preallocated_node_set_);
+
+ for (ACE_Timer_Node_T<TYPE> **entry = 0;
+ set_iterator.next (entry) !=0;
+ set_iterator.advance ())
+ delete [] *entry;
+ }
+}
+
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::close (void)
+{
+ ACE_TRACE ("ACE_Timer_Heap_T::close");
+
size_t current_size =
this->cur_size_;
@@ -228,20 +251,8 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Heap_T (void)
this->upcall_functor ().deletion (*this, eh, act);
}
- delete [] this->heap_;
- delete [] this->timer_ids_;
-
- // clean up any preallocated timer nodes
- if (preallocated_nodes_ != 0)
- {
- ACE_Unbounded_Set_Iterator<ACE_Timer_Node_T<TYPE> *>
- set_iterator (this->preallocated_node_set_);
-
- for (ACE_Timer_Node_T<TYPE> **entry = 0;
- set_iterator.next (entry) !=0;
- set_iterator.advance ())
- delete [] *entry;
- }
+ // leave the rest to the destructor
+ return 0;
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
diff --git a/ACE/ace/Timer_Heap_T.h b/ACE/ace/Timer_Heap_T.h
index 5fd55f9b603..c3489b581a4 100644
--- a/ACE/ace/Timer_Heap_T.h
+++ b/ACE/ace/Timer_Heap_T.h
@@ -165,6 +165,11 @@ public:
const void **act = 0,
int dont_call_handle_close = 1);
+ /**
+ * Destroy timer queue. Cancels all timers.
+ */
+ virtual int close (void);
+
/// Returns a pointer to this ACE_Timer_Queue's iterator.
virtual ACE_Timer_Queue_Iterator_T<TYPE> &iter (void);
diff --git a/ACE/ace/Timer_List_T.cpp b/ACE/ace/Timer_List_T.cpp
index fe0af558479..5508c1b6a58 100644
--- a/ACE/ace/Timer_List_T.cpp
+++ b/ACE/ace/Timer_List_T.cpp
@@ -129,6 +129,19 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_List_T (void)
delete iterator_;
+ this->close ();
+
+ // delete the dummy node
+ delete this->head_;
+}
+
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::close (void)
+{
+ ACE_TRACE ("ACE_Timer_List_T::close");
+ ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
+
+ // Remove all remaining items in the list.
if (!this->is_empty())
{
for (ACE_Timer_Node_T<TYPE>* n = this->get_first();
@@ -148,8 +161,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_List_T (void)
}
}
- // delete the dummy node
- delete this->head_;
+ // Leave rest to destructor
+ return 0;
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
diff --git a/ACE/ace/Timer_List_T.h b/ACE/ace/Timer_List_T.h
index 2e020e94cd2..72958dc39f1 100644
--- a/ACE/ace/Timer_List_T.h
+++ b/ACE/ace/Timer_List_T.h
@@ -147,6 +147,11 @@ public:
const void** act = 0,
int dont_call_handle_close = 1);
+ /**
+ * Destroy timer queue. Cancels all timers.
+ */
+ virtual int close (void);
+
/// Returns a pointer to this ACE_Timer_Queue's iterator.
virtual ACE_Timer_Queue_Iterator_T<TYPE>& iter (void);
diff --git a/ACE/ace/Timer_Queue_Adapters.cpp b/ACE/ace/Timer_Queue_Adapters.cpp
index 55f539b23a3..1697072e238 100644
--- a/ACE/ace/Timer_Queue_Adapters.cpp
+++ b/ACE/ace/Timer_Queue_Adapters.cpp
@@ -182,6 +182,11 @@ ACE_Thread_Timer_Queue_Adapter<TQ, TYPE>::~ACE_Thread_Timer_Queue_Adapter (void)
this->timer_queue_ = 0;
this->delete_timer_queue_ = false;
}
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ this->timer_queue_ = 0;
+ }
}
template<class TQ, class TYPE> ACE_SYNCH_RECURSIVE_MUTEX &
diff --git a/ACE/ace/Timer_Queue_Adapters.inl b/ACE/ace/Timer_Queue_Adapters.inl
index 16901a15bd6..ad160682566 100644
--- a/ACE/ace/Timer_Queue_Adapters.inl
+++ b/ACE/ace/Timer_Queue_Adapters.inl
@@ -15,6 +15,8 @@ ACE_Thread_Timer_Queue_Adapter<TQ, TYPE>::timer_queue (TQ *tq)
{
if (this->delete_timer_queue_)
delete this->timer_queue_;
+ else if (this->timer_queue_)
+ this->timer_queue_->close ();
this->timer_queue_ = tq;
this->delete_timer_queue_ = false;
return 0;
diff --git a/ACE/ace/Timer_Wheel_T.cpp b/ACE/ace/Timer_Wheel_T.cpp
index d99cf1b8225..73cc2318dc5 100644
--- a/ACE/ace/Timer_Wheel_T.cpp
+++ b/ACE/ace/Timer_Wheel_T.cpp
@@ -171,6 +171,23 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Wheel_T (voi
delete iterator_;
+ this->close ();
+ for (u_int i = 0; i < this->spoke_count_; ++i)
+ {
+ // Free all the nodes starting at the root
+ ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
+ delete root;
+ }
+
+ delete[] this->spokes_;
+}
+
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::close (void)
+{
+ ACE_TRACE ("ACE_Timer_Wheel_T::close");
+
+ // Remove any remaining nodes
for (u_int i = 0; i < this->spoke_count_; ++i)
{
// Free all the nodes starting at the root
@@ -184,9 +201,10 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Wheel_T (voi
this->free_node (n);
n = next;
}
- delete root;
}
- delete[] this->spokes_;
+
+ // Leave rest for destructor
+ return 0;
}
/// Searches for a node by timer_id within one spoke.
diff --git a/ACE/ace/Timer_Wheel_T.h b/ACE/ace/Timer_Wheel_T.h
index 83d293b9470..2e55b1bdf49 100644
--- a/ACE/ace/Timer_Wheel_T.h
+++ b/ACE/ace/Timer_Wheel_T.h
@@ -143,6 +143,11 @@ public:
const void** act = 0,
int dont_call_handle_close = 1);
+ /**
+ * Destroy timer queue. Cancels all timers.
+ */
+ virtual int close (void);
+
/// Run the <functor> for all timers whose values are <=
/// <ACE_OS::gettimeofday>. Also accounts for <timer_skew>. Returns
/// the number of timers canceled.
diff --git a/ACE/ace/WFMO_Reactor.cpp b/ACE/ace/WFMO_Reactor.cpp
index dc31128812b..ab826cc5eb4 100644
--- a/ACE/ace/WFMO_Reactor.cpp
+++ b/ACE/ace/WFMO_Reactor.cpp
@@ -1153,6 +1153,8 @@ ACE_WFMO_Reactor::open (size_t size,
// Timer Queue
if (this->delete_timer_queue_)
delete this->timer_queue_;
+ else if (this->timer_queue_)
+ this->timer_queue_->close ();
if (tq == 0)
{
@@ -1283,8 +1285,14 @@ ACE_WFMO_Reactor::timer_queue (void) const
int
ACE_WFMO_Reactor::timer_queue (ACE_Timer_Queue *tq)
{
- if (this->timer_queue_ != 0 && this->delete_timer_queue_)
- delete this->timer_queue_;
+ if (this->delete_timer_queue_)
+ {
+ delete this->timer_queue_;
+ }
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ }
this->timer_queue_ = tq;
this->delete_timer_queue_ = false;
return 0;
@@ -1326,6 +1334,11 @@ ACE_WFMO_Reactor::~ACE_WFMO_Reactor (void)
this->timer_queue_ = 0;
this->delete_timer_queue_ = false;
}
+ else if (this->timer_queue_)
+ {
+ this->timer_queue_->close ();
+ this->timer_queue_ = 0;
+ }
if (this->delete_signal_handler_)
{