summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-06-28 22:29:08 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-06-28 22:29:08 +0000
commit525d59899aa78db156bda075e35c223ff6427853 (patch)
tree8b34e3d354b4c67e2824c8c4bc78c64d1f9a1da6
parent44f9eeafaf8d997fdd3ad635d24bb7060d16f853 (diff)
downloadATCD-525d59899aa78db156bda075e35c223ff6427853.tar.gz
Sun Jun 28 22:15:47 UTC 2009 Carlos O'Ryan <coryan@glamdring>
* ace/ace.mpc: * ace/Abstract_Timer_Queue.h: * ace/Abstract_Timer_Queue.cpp: * ace/Timer_Queue_Iterator.h: * ace/Timer_Queue_Iterator.inl: * ace/Timer_Queue_Iterator.cpp: * ace/Timer_Queuefwd.h: * ace/Timer_Queue.h: * ace/Timer_Queue_T.h: * ace/Timer_Queue_T.inl: * ace/Timer_Queue_T.cpp: * ace/Timer_List_T.h: * ace/Timer_List_T.cpp: * ace/Timer_Wheel_T.h: * ace/Timer_Wheel_T.cpp: * ace/Timer_Hash_T.h: * ace/Timer_Hash_T.cpp: * ace/Timer_Heap_T.h: * ace/Timer_Heap_T.cpp: Heavy refactoring in ACE_Timer_Queue_T class and friends. First, created a template base class (ACE_Abstract_Timer_Queue) that: 1) Only depends on the type held by the timer queue, not to lock or upcall strategy. 2) It is a pure abstract class, i.e., none of its member functions have any implementation. 3) Provides new pure virtual functions to encapsulates some logic that was spread between tests, TP_Reactor and Dev_Poll_Reactor. Then I re-wrote all the standard timer queue objects in terms of this class. In particular, the reactors use only the abstract interface. I also re-factored the Timer_Queue_Iterator to only depend on the type of objects held by the timer queue. The rest of the parameters where not used either. Implement functionality that was spread in Dev_Poll_Reactor, TP_Reactor and a test into expire_single. * ace/Proactor.h: * ace/TP_Reactor.cpp: * ace/Dev_Poll_Reactor.cpp: Both classes implemented the logic to dispatch a single timer but release a mutex before the upcall. This was confusing as well as required exposing too much detail about the Timer_Queue classes. The new mechanism is a single function in (expire_single) ACE_Abstract_Timer_Queue<> (implemented in ACE_Timer_Queue_T<>) which receives a command object to encapsulate the mutex release. * ace/Functor.h: * ace/Functor.cpp: * ace/Functor_T.h: * ace/Functor_T.inl: Add helper ACE_Command_* objects. One is a no-op, for the test below. The other is a callback that ignores the silly void* argument in the ACE_Command_Base::execute() member function. * tests/Timer_Queue_Reference_Counting_Test.cpp: Re-factored test in terms of expire_single()
-rw-r--r--ACE/ChangeLog61
-rw-r--r--ACE/ace/Abstract_Timer_Queue.cpp24
-rw-r--r--ACE/ace/Abstract_Timer_Queue.h210
-rw-r--r--ACE/ace/Dev_Poll_Reactor.cpp34
-rw-r--r--ACE/ace/Functor.cpp10
-rw-r--r--ACE/ace/Functor.h17
-rw-r--r--ACE/ace/Functor_T.h32
-rw-r--r--ACE/ace/Functor_T.inl21
-rw-r--r--ACE/ace/Proactor.h6
-rw-r--r--ACE/ace/TP_Reactor.cpp37
-rw-r--r--ACE/ace/Timer_Hash_T.cpp6
-rw-r--r--ACE/ace/Timer_Hash_T.h6
-rw-r--r--ACE/ace/Timer_Heap_T.cpp2
-rw-r--r--ACE/ace/Timer_Heap_T.h4
-rw-r--r--ACE/ace/Timer_List_T.cpp2
-rw-r--r--ACE/ace/Timer_List_T.h4
-rw-r--r--ACE/ace/Timer_Queue.h4
-rw-r--r--ACE/ace/Timer_Queue_Iterator.cpp56
-rw-r--r--ACE/ace/Timer_Queue_Iterator.h196
-rw-r--r--ACE/ace/Timer_Queue_Iterator.inl135
-rw-r--r--ACE/ace/Timer_Queue_T.cpp87
-rw-r--r--ACE/ace/Timer_Queue_T.h326
-rw-r--r--ACE/ace/Timer_Queue_T.inl128
-rw-r--r--ACE/ace/Timer_Queuefwd.h12
-rw-r--r--ACE/ace/Timer_Wheel_T.cpp2
-rw-r--r--ACE/ace/Timer_Wheel_T.h4
-rw-r--r--ACE/ace/ace.mpc2
-rw-r--r--ACE/tests/Timer_Queue_Reference_Counting_Test.cpp34
28 files changed, 870 insertions, 592 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index 78965f2f08f..2ea189eab6e 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,64 @@
+Sun Jun 28 22:15:47 UTC 2009 Carlos O'Ryan <coryan@glamdring>
+
+ * ace/ace.mpc:
+ * ace/Abstract_Timer_Queue.h:
+ * ace/Abstract_Timer_Queue.cpp:
+ * ace/Timer_Queue_Iterator.h:
+ * ace/Timer_Queue_Iterator.inl:
+ * ace/Timer_Queue_Iterator.cpp:
+ * ace/Timer_Queuefwd.h:
+ * ace/Timer_Queue.h:
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+ * ace/Timer_Queue_T.cpp:
+ * ace/Timer_List_T.h:
+ * ace/Timer_List_T.cpp:
+ * ace/Timer_Wheel_T.h:
+ * ace/Timer_Wheel_T.cpp:
+ * ace/Timer_Hash_T.h:
+ * ace/Timer_Hash_T.cpp:
+ * ace/Timer_Heap_T.h:
+ * ace/Timer_Heap_T.cpp:
+ Heavy refactoring in ACE_Timer_Queue_T class and friends.
+ First, created a template base class (ACE_Abstract_Timer_Queue) that:
+ 1) Only depends on the type held by the timer queue, not to lock
+ or upcall strategy.
+ 2) It is a pure abstract class, i.e., none of its member
+ functions have any implementation.
+ 3) Provides new pure virtual functions to encapsulates some
+ logic that was spread between tests, TP_Reactor and
+ Dev_Poll_Reactor.
+ Then I re-wrote all the standard timer queue objects in terms of
+ this class. In particular, the reactors use only the abstract
+ interface.
+ I also re-factored the Timer_Queue_Iterator to only depend on
+ the type of objects held by the timer queue. The rest of the
+ parameters where not used either.
+ Implement functionality that was spread in Dev_Poll_Reactor,
+ TP_Reactor and a test into expire_single.
+
+ * ace/Proactor.h:
+ * ace/TP_Reactor.cpp:
+ * ace/Dev_Poll_Reactor.cpp:
+ Both classes implemented the logic to dispatch a single timer
+ but release a mutex before the upcall. This was confusing as
+ well as required exposing too much detail about the Timer_Queue
+ classes.
+ The new mechanism is a single function in (expire_single)
+ ACE_Abstract_Timer_Queue<> (implemented in ACE_Timer_Queue_T<>)
+ which receives a command object to encapsulate the mutex release.
+
+ * ace/Functor.h:
+ * ace/Functor.cpp:
+ * ace/Functor_T.h:
+ * ace/Functor_T.inl:
+ Add helper ACE_Command_* objects. One is a no-op, for the test
+ below. The other is a callback that ignores the silly void*
+ argument in the ACE_Command_Base::execute() member function.
+
+ * tests/Timer_Queue_Reference_Counting_Test.cpp:
+ Re-factored test in terms of expire_single()
+
Sat Jun 27 00:55:10 UTC 2009 Johnny Willemsen <jwillemsen@remedy.nl>
* rpmbuild/ace-tao-ciao.spec:
diff --git a/ACE/ace/Abstract_Timer_Queue.cpp b/ACE/ace/Abstract_Timer_Queue.cpp
new file mode 100644
index 00000000000..021c637fe6e
--- /dev/null
+++ b/ACE/ace/Abstract_Timer_Queue.cpp
@@ -0,0 +1,24 @@
+#ifndef ACE_ABSTRACT_TIMER_QUEUE_CPP
+#define ACE_ABSTRACT_TIMER_QUEUE_CPP
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Abstract_Timer_Queue.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Even though the destructor is pure virtual you must provide an
+// implementation. Most people know this, but sometimes we all
+// forget, and we might be tempted to remove this code.
+template<typename TYPE>
+ACE_Abstract_Timer_Queue<TYPE>::
+~ACE_Abstract_Timer_Queue ()
+{
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_ABSTRACT_TIMER_QUEUE_CPP */
diff --git a/ACE/ace/Abstract_Timer_Queue.h b/ACE/ace/Abstract_Timer_Queue.h
new file mode 100644
index 00000000000..d7c08987ebf
--- /dev/null
+++ b/ACE/ace/Abstract_Timer_Queue.h
@@ -0,0 +1,210 @@
+#ifndef ACE_ABSTRACT_TIMER_QUEUE_H
+#define ACE_ABSTRACT_TIMER_QUEUE_H
+#include /**/ "ace/pre.h"
+/**
+ * @file Abstract_Timer_Queue.h
+ *
+ * @author Carlos O'Ryan <coryan@atdesk.com>
+ *
+ * Based on classes and files developed by Doug Schmidt, Darrell
+ * Brunsch, Irfan Pyarali and a cast of thousands.
+ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Forward declares
+class ACE_Time_Value;
+class ACE_Command_Base;
+template<typename TYPE> class ACE_Timer_Queue_Iterator_T;
+
+/**
+ * @class ACE_Abstract_Timer_Queue
+ *
+ * @brief Base class for all timer queues of a single type.
+ *
+ * This is a base class for all the timer queues, regardless of
+ * locking strategy, upcall mechanism, internal implementation, etc.
+ * The class was motivated by bug 3706:
+ * http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=3706
+ * In short, the Reactor (and potentially other classes) want to refer
+ * to timer queues regardless of the implementation internals.
+ */
+template<typename TYPE>
+class ACE_Abstract_Timer_Queue
+{
+public:
+ /// Destructor
+ virtual ~ACE_Abstract_Timer_Queue (void) = 0;
+
+ /// True if queue is empty, else false.
+ virtual bool is_empty (void) const = 0;
+
+ /// Returns the time of the earlier node in the Timer_Queue. Must
+ /// be called on a non-empty queue.
+ virtual const ACE_Time_Value &earliest_time (void) const = 0;
+
+ /**
+ * Schedule @a type that will expire at @a future_time, which is
+ * specified in absolute time. If it expires then @a act is passed
+ * in as the value to the <functor>. If @a interval is != to
+ * ACE_Time_Value::zero then it is used to reschedule the @a type
+ * automatically, using relative time to the current <gettimeofday>.
+ * This method returns a <timer_id> that uniquely identifies the the
+ * @a type entry in an internal list. This <timer_id> can be used to
+ * cancel the timer before it expires. The cancellation ensures
+ * that <timer_ids> are unique up to values of greater than 2
+ * billion timers. As long as timers don't stay around longer than
+ * this there should be no problems with accidentally deleting the
+ * wrong timer. Returns -1 on failure (which is guaranteed never to
+ * be a valid <timer_id>).
+ */
+ virtual long schedule (const TYPE &type,
+ const void *act,
+ const ACE_Time_Value &future_time,
+ const ACE_Time_Value &interval = ACE_Time_Value::zero) = 0;
+
+ /**
+ * Run the <functor> for all timers whose values are <= @a current_time.
+ * This does not account for <timer_skew>. Returns the number of
+ * timers canceled.
+ */
+ virtual int expire (const ACE_Time_Value &current_time) = 0;
+
+ /**
+ * Run the <functor> for all timers whose values are <=
+ * <ACE_OS::gettimeofday>. Also accounts for <timer_skew>.
+ *
+ * Depending on the resolution of the underlying OS the system calls
+ * like select()/poll() might return at time different than that is
+ * specified in the timeout. Suppose the OS guarantees a resolution of t ms.
+ * The timeline will look like
+ *
+ * A B
+ * | |
+ * V V
+ * |-------------|-------------|-------------|-------------|
+ * t t t t t
+ *
+ *
+ * If you specify a timeout value of A, then the timeout will not occur
+ * at A but at the next interval of the timer, which is later than
+ * that is expected. Similarly, if your timeout value is equal to B,
+ * then the timeout will occur at interval after B. Now depending upon the
+ * resolution of your timeouts and the accuracy of the timeouts
+ * needed for your application, you should set the value of
+ * <timer_skew>. In the above case, if you want the timeout A to fire
+ * no later than A, then you should specify your <timer_skew> to be
+ * A % t.
+ *
+ * The timeout value should be specified via the macro ACE_TIMER_SKEW
+ * in your config.h file. The default value is zero.
+ *
+ * Things get interesting if the t before the timeout value B is zero
+ * i.e your timeout is less than the interval. In that case, you are
+ * almost sure of not getting the desired timeout behaviour. Maybe you
+ * should look for a better OS :-)
+ *
+ * Returns the number of timers canceled.
+ */
+ virtual int expire (void) = 0;
+
+ /**
+ * A couple of classes using Timer_Queues need to dispatch a single
+ * event at a time. But before they dispatch the event they need to
+ * release a lock, signal other threads, etc.
+ *
+ * This member function should be used in that case. The additional
+ * operations to be called just before dispatching the event, and
+ * only if an event will be dispatched, are encapsulated in the
+ * ACE_Command_Base object.
+ */
+ virtual int expire_single(ACE_Command_Base & pre_dispatch_command) = 0;
+
+ /**
+ * Resets the interval of the timer represented by @a timer_id to
+ * @a interval, which is specified in relative time to the current
+ * <gettimeofday>. If @a interval is equal to
+ * ACE_Time_Value::zero, the timer will become a non-rescheduling
+ * timer. Returns 0 if successful, -1 if not.
+ */
+ virtual int reset_interval (long timer_id,
+ const ACE_Time_Value &interval) = 0;
+
+ /**
+ * Cancel all timer associated with @a type. If
+ * @a dont_call_handle_close is 0 then the <functor> will be invoked,
+ * which typically invokes the <handle_close> hook. Returns number
+ * of timers cancelled.
+ */
+ virtual int cancel (const TYPE &type,
+ int dont_call_handle_close = 1) = 0;
+
+ /**
+ * Cancel the single timer that matches the @a timer_id value (which
+ * was returned from the <schedule> method). If act is non-NULL
+ * then it will be set to point to the ``magic cookie'' argument
+ * passed in when the timer was registered. This makes it possible
+ * to free up the memory and avoid memory leaks. If
+ * @a dont_call_handle_close is 0 then the <functor> will be invoked,
+ * which typically calls the <handle_close> hook. Returns 1 if
+ * cancellation succeeded and 0 if the @a timer_id wasn't found.
+ */
+ virtual int cancel (long timer_id,
+ const void **act = 0,
+ int dont_call_handle_close = 1) = 0;
+
+ /**
+ * Returns the current time of day. This method allows different
+ * implementations of the timer queue to use special high resolution
+ * timers.
+ */
+ virtual ACE_Time_Value gettimeofday (void) = 0;
+
+ /**
+ * Allows applications to control how the timer queue gets the time of day.
+ */
+ virtual void gettimeofday (ACE_Time_Value (*gettimeofday)(void)) = 0;
+
+ /// Determine the next event to timeout. Returns @a max if there are
+ /// no pending timers or if all pending timers are longer than max.
+ /// This method acquires a lock internally since it modifies internal state.
+ virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max) = 0;
+
+ /**
+ * Determine the next event to timeout. Returns @a max if there are
+ * no pending timers or if all pending timers are longer than max.
+ * <the_timeout> should be a pointer to storage for the timeout value,
+ * and this value is also returned. This method does not acquire a
+ * lock internally since it doesn't modify internal state. If you
+ * need to call this method when the queue is being modified
+ * concurrently, however, you should make sure to acquire the <mutex()>
+ * externally before making the call.
+ */
+ virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max,
+ ACE_Time_Value *the_timeout) = 0;
+
+ /**
+ * Return the current time, using the right time policy and any
+ * timer skew defined in derived classes.
+ */
+ virtual ACE_Time_Value current_time() = 0;
+
+ /// Type of Iterator.
+ typedef ACE_Timer_Queue_Iterator_T<TYPE> ITERATOR;
+
+ /// Returns a pointer to this ACE_Timer_Queue's iterator.
+ virtual ITERATOR & iter (void) = 0;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Abstract_Timer_Queue.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Abstract_Timer_Queue.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_ABSTRACT_TIMER_QUEUE_H */
diff --git a/ACE/ace/Dev_Poll_Reactor.cpp b/ACE/ace/Dev_Poll_Reactor.cpp
index a49e9c40f4d..ae871efe74a 100644
--- a/ACE/ace/Dev_Poll_Reactor.cpp
+++ b/ACE/ace/Dev_Poll_Reactor.cpp
@@ -43,6 +43,7 @@ ACE_RCSID (ace,
#include "ace/Guard_T.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_sys_time.h"
+#include "ace/Functor_T.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -1084,37 +1085,10 @@ ACE_Dev_Poll_Reactor::dispatch (Token_Guard &guard)
int
ACE_Dev_Poll_Reactor::dispatch_timer_handler (Token_Guard &guard)
{
- if (this->timer_queue_->is_empty ())
- return 0; // Empty timer queue so cannot have any expired timers.
+ typedef ACE_Member_Function_Command<Token_Guard> Guard_Release;
- // Get the current time
- ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () +
- this->timer_queue_->timer_skew ());
-
- // Look for a node in the timer queue whose timer <= the present
- // time.
- ACE_Timer_Node_Dispatch_Info info;
- if (this->timer_queue_->dispatch_info (cur_time, info))
- {
- const void *upcall_act = 0;
-
- // Preinvoke (handles refcount if needed, etc.)
- this->timer_queue_->preinvoke (info, cur_time, upcall_act);
-
- // Release the token before expiration upcall.
- guard.release_token ();
-
- // call the functor
- this->timer_queue_->upcall (info, cur_time);
-
- // Postinvoke (undo refcount if needed, etc.)
- this->timer_queue_->postinvoke (info, cur_time, upcall_act);
-
- // We have dispatched a timer
- return 1;
- }
-
- return 0;
+ Guard_Release release(guard, &Token_Guard::release_token);
+ return this->timer_queue_->expire_single(release);
}
#if 0
diff --git a/ACE/ace/Functor.cpp b/ACE/ace/Functor.cpp
index 9fc3b3400c0..0d0d92fae8a 100644
--- a/ACE/ace/Functor.cpp
+++ b/ACE/ace/Functor.cpp
@@ -40,4 +40,14 @@ ACE_Command_Base::~ACE_Command_Base (void)
{
}
+ACE_Noop_Command::ACE_Noop_Command()
+{
+}
+
+int
+ACE_Noop_Command::execute(void*)
+{
+ return 0;
+}
+
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Functor.h b/ACE/ace/Functor.h
index f303bc09c97..7edcae7174c 100644
--- a/ACE/ace/Functor.h
+++ b/ACE/ace/Functor.h
@@ -77,6 +77,23 @@ public:
virtual int execute (void *arg = 0) = 0;
};
+/**
+ * @class ACE_Noop_Command
+ *
+ * Implements a ACE_Command_Base with an empty execute() body.
+ */
+
+class ACE_Export ACE_Noop_Command
+ : public ACE_Command_Base
+{
+public:
+ /// Constructor
+ ACE_Noop_Command();
+
+ /// Implement the empty execute() member function
+ virtual int execute(void*);
+};
+
////////////////////////////////////////////////////////////
// STL-style Functor Classes and Template Specializations //
////////////////////////////////////////////////////////////
diff --git a/ACE/ace/Functor_T.h b/ACE/ace/Functor_T.h
index 554820e3c0b..3b148464308 100644
--- a/ACE/ace/Functor_T.h
+++ b/ACE/ace/Functor_T.h
@@ -78,6 +78,38 @@ private:
ACTION action_;
};
+/**
+ * @class ACE_Member_Function_Command
+ *
+ * @brief Defines a class template that allows us to invoke a member
+ * function using the GoF command style callback.
+ *
+ */
+template <class RECEIVER>
+class ACE_Member_Function_Command : public ACE_Command_Base
+{
+public:
+ typedef void (RECEIVER::*PTMF)(void);
+
+ /// Con Constructor: sets the <receiver_> of the Command to recvr, and the
+ /// <action_> of the Command to <action>.
+ ACE_Member_Function_Command (RECEIVER &recvr, PTMF ptmf);
+
+ /// Virtual destructor.
+ virtual ~ACE_Member_Function_Command (void);
+
+ /// Invokes the method <action_> from the object <receiver_>. The
+ /// parameter is ignored
+ virtual int execute (void *);
+
+private:
+ /// Object where the method resides.
+ RECEIVER &receiver_;
+
+ /// Method that is going to be invoked.
+ PTMF ptmf_;
+};
+
/////////////////////////////////
// STL-style Functor Templates //
/////////////////////////////////
diff --git a/ACE/ace/Functor_T.inl b/ACE/ace/Functor_T.inl
index 6441c091b76..d6cefade1bd 100644
--- a/ACE/ace/Functor_T.inl
+++ b/ACE/ace/Functor_T.inl
@@ -4,6 +4,27 @@
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+template<class RECEIVER> ACE_INLINE
+ACE_Member_Function_Command<RECEIVER>::
+ACE_Member_Function_Command (RECEIVER &recvr, PTMF ptmf)
+ : receiver_(recvr)
+ , ptmf_(ptmf)
+{
+}
+
+template<class RECEIVER> ACE_INLINE
+ACE_Member_Function_Command<RECEIVER>::
+~ACE_Member_Function_Command (void)
+{
+}
+
+template<class RECEIVER> ACE_INLINE int
+ACE_Member_Function_Command<RECEIVER>::execute (void *)
+{
+ (this->receiver_.*ptmf_)();
+ return 0;
+}
+
template <class TYPE> ACE_INLINE unsigned long
ACE_Hash<TYPE>::operator () (const TYPE &t) const
{
diff --git a/ACE/ace/Proactor.h b/ACE/ace/Proactor.h
index 704eef416ff..2db4ab9d39c 100644
--- a/ACE/ace/Proactor.h
+++ b/ACE/ace/Proactor.h
@@ -135,10 +135,8 @@ class ACE_Export ACE_Proactor
{
// = Here are the private typedefs that the ACE_Proactor uses.
- typedef ACE_Timer_Queue_Iterator_T<ACE_Handler *,
- ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX>
- TIMER_QUEUE_ITERATOR;
+ typedef ACE_Timer_Queue_Iterator_T<ACE_Handler *>
+ TIMER_QUEUE_ITERATOR;
typedef ACE_Timer_List_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX>
diff --git a/ACE/ace/TP_Reactor.cpp b/ACE/ace/TP_Reactor.cpp
index ac9bbdada63..16eb60972dc 100644
--- a/ACE/ace/TP_Reactor.cpp
+++ b/ACE/ace/TP_Reactor.cpp
@@ -5,6 +5,7 @@
#include "ace/Timer_Queue.h"
#include "ace/Sig_Handler.h"
#include "ace/Log_Msg.h"
+#include "ace/Functor_T.h"
#include "ace/OS_NS_sys_time.h"
#if !defined (__ACE_INLINE__)
@@ -307,40 +308,10 @@ int
ACE_TP_Reactor::handle_timer_events (int & /*event_count*/,
ACE_TP_Token_Guard &guard)
{
- if (this->timer_queue_ == 0 || this->timer_queue_->is_empty())
- { // Empty timer queue so cannot have any expired timers.
- return 0;
- }
-
- // Get the current time
- ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () +
- this->timer_queue_->timer_skew ());
-
- // Look for a node in the timer queue whose timer <= the present
- // time.
- ACE_Timer_Node_Dispatch_Info info;
-
- if (this->timer_queue_->dispatch_info (cur_time, info))
- {
- const void *upcall_act = 0;
-
- // Preinvoke.
- this->timer_queue_->preinvoke (info, cur_time, upcall_act);
+ typedef ACE_Member_Function_Command<ACE_TP_Token_Guard> Guard_Release;
- // Release the token before dispatching notifies...
- guard.release_token ();
-
- // call the functor
- this->timer_queue_->upcall (info, cur_time);
-
- // Postinvoke
- this->timer_queue_->postinvoke (info, cur_time, upcall_act);
-
- // We have dispatched a timer
- return 1;
- }
-
- return 0;
+ Guard_Release release(guard, &ACE_TP_Token_Guard::release_token);
+ return this->timer_queue_->expire_single(release);
}
int
diff --git a/ACE/ace/Timer_Hash_T.cpp b/ACE/ace/Timer_Hash_T.cpp
index a2a81fc3773..15ff0b86334 100644
--- a/ACE/ace/Timer_Hash_T.cpp
+++ b/ACE/ace/Timer_Hash_T.cpp
@@ -258,7 +258,7 @@ ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::item (void)
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
+ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::iter (void)
{
this->iterator_->first ();
@@ -638,9 +638,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (const TYPE &type,
i < this->table_size_;
++i)
{
- ACE_Timer_Queue_Iterator_T<TYPE,
- ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>,
- ACE_Null_Mutex> &iter =
+ ACE_Timer_Queue_Iterator_T<TYPE> & iter =
this->table_[i]->iter ();
for (iter.first ();
diff --git a/ACE/ace/Timer_Hash_T.h b/ACE/ace/Timer_Hash_T.h
index 53072ebd51c..cc3b6b786d3 100644
--- a/ACE/ace/Timer_Hash_T.h
+++ b/ACE/ace/Timer_Hash_T.h
@@ -119,7 +119,7 @@ private:
* in the order of timeout values.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-class ACE_Timer_Hash_Iterator_T : public ACE_Timer_Queue_Iterator_T <TYPE, FUNCTOR, ACE_LOCK>
+class ACE_Timer_Hash_Iterator_T : public ACE_Timer_Queue_Iterator_T <TYPE>
{
public:
/// Constructor.
@@ -145,7 +145,7 @@ protected:
size_t position_;
/// Current iterator used on <position>'s bucket
- ACE_Timer_Queue_Iterator_T<TYPE, ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>, ACE_Null_Mutex> *iter_;
+ ACE_Timer_Queue_Iterator_T<TYPE> *iter_;
};
/**
@@ -252,7 +252,7 @@ public:
virtual int expire (const ACE_Time_Value &current_time);
/// Returns a pointer to this ACE_Timer_Queue's iterator.
- virtual ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &iter (void);
+ virtual ACE_Timer_Queue_Iterator_T<TYPE> &iter (void);
/// Removes the earliest node from the queue and returns it
virtual ACE_Timer_Node_T<TYPE> *remove_first (void);
diff --git a/ACE/ace/Timer_Heap_T.cpp b/ACE/ace/Timer_Heap_T.cpp
index c15597cf334..aef61388db2 100644
--- a/ACE/ace/Timer_Heap_T.cpp
+++ b/ACE/ace/Timer_Heap_T.cpp
@@ -317,7 +317,7 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
}
template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
+ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
{
this->iterator_->first ();
diff --git a/ACE/ace/Timer_Heap_T.h b/ACE/ace/Timer_Heap_T.h
index 00c128b1aa9..e4bcdbefced 100644
--- a/ACE/ace/Timer_Heap_T.h
+++ b/ACE/ace/Timer_Heap_T.h
@@ -39,7 +39,7 @@ class ACE_Timer_Heap_T;
* in the order of timeout values.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
-class ACE_Timer_Heap_Iterator_T : public ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>
+class ACE_Timer_Heap_Iterator_T : public ACE_Timer_Queue_Iterator_T<TYPE>
{
public:
/// Constructor.
@@ -163,7 +163,7 @@ public:
int dont_call_handle_close = 1);
/// Returns a pointer to this ACE_Timer_Queue's iterator.
- virtual ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &iter (void);
+ virtual ACE_Timer_Queue_Iterator_T<TYPE> &iter (void);
/**
* Removes the earliest node from the queue and returns it. Note that
diff --git a/ACE/ace/Timer_List_T.cpp b/ACE/ace/Timer_List_T.cpp
index e2313d0e002..c969b31ea64 100644
--- a/ACE/ace/Timer_List_T.cpp
+++ b/ACE/ace/Timer_List_T.cpp
@@ -70,7 +70,7 @@ ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
// Return our instance of the iterator
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
+template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
{
this->iterator_->first ();
diff --git a/ACE/ace/Timer_List_T.h b/ACE/ace/Timer_List_T.h
index d4ec800340e..d4180172b8e 100644
--- a/ACE/ace/Timer_List_T.h
+++ b/ACE/ace/Timer_List_T.h
@@ -34,7 +34,7 @@ class ACE_Timer_List_T;
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
class ACE_Timer_List_Iterator_T
-: public ACE_Timer_Queue_Iterator_T <TYPE, FUNCTOR, ACE_LOCK>
+: public ACE_Timer_Queue_Iterator_T <TYPE>
{
public:
typedef ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK> List;
@@ -147,7 +147,7 @@ public:
int dont_call_handle_close = 1);
/// Returns a pointer to this ACE_Timer_Queue's iterator.
- virtual ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>& iter (void);
+ virtual ACE_Timer_Queue_Iterator_T<TYPE>& iter (void);
/// Removes the earliest node from the queue and returns it
virtual ACE_Timer_Node_T<TYPE>* remove_first (void);
diff --git a/ACE/ace/Timer_Queue.h b/ACE/ace/Timer_Queue.h
index 36182f15f95..cee9f6bab84 100644
--- a/ACE/ace/Timer_Queue.h
+++ b/ACE/ace/Timer_Queue.h
@@ -40,9 +40,7 @@ typedef ACE_Timer_Node_Dispatch_Info_T<ACE_Event_Handler *>
typedef ACE_Timer_Node_T<ACE_Event_Handler *>
ACE_Timer_Node;
-typedef ACE_Timer_Queue_Iterator_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
- ACE_SYNCH_RECURSIVE_MUTEX>
+typedef ACE_Timer_Queue_Iterator_T<ACE_Event_Handler *>
ACE_Timer_Queue_Iterator;
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Queue_Iterator.cpp b/ACE/ace/Timer_Queue_Iterator.cpp
new file mode 100644
index 00000000000..d777396f489
--- /dev/null
+++ b/ACE/ace/Timer_Queue_Iterator.cpp
@@ -0,0 +1,56 @@
+#ifndef ACE_TIMER_QUEUE_ITERATOR_CPP
+#define ACE_TIMER_QUEUE_ITERATOR_CPP
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Timer_Queue_Iterator.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <class TYPE> void
+ACE_Timer_Node_T<TYPE>::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_Timer_Node_T::dump");
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nact_ = %x"), this->act_));
+ this->timer_value_.dump ();
+ this->interval_.dump ();
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nprev_ = %x"), this->prev_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnext_ = %x"), this->next_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_id_ = %d\n"), this->timer_id_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+#endif /* ACE_HAS_DUMP */
+}
+
+template <class TYPE>
+ACE_Timer_Node_T<TYPE>::ACE_Timer_Node_T (void)
+{
+ ACE_TRACE ("ACE_Timer_Node_T::ACE_Timer_Node_T");
+}
+
+template <class TYPE>
+ACE_Timer_Node_T<TYPE>::~ACE_Timer_Node_T (void)
+{
+ ACE_TRACE ("ACE_Timer_Node_T::~ACE_Timer_Node_T");
+}
+
+template <class TYPE>
+ACE_Timer_Queue_Iterator_T<TYPE>::ACE_Timer_Queue_Iterator_T (void)
+{
+}
+
+template <class TYPE>
+ACE_Timer_Queue_Iterator_T<TYPE>::~ACE_Timer_Queue_Iterator_T (void)
+{
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_TIMER_QUEUE_ITERATOR_CPP */
diff --git a/ACE/ace/Timer_Queue_Iterator.h b/ACE/ace/Timer_Queue_Iterator.h
new file mode 100644
index 00000000000..5e953dcfa1c
--- /dev/null
+++ b/ACE/ace/Timer_Queue_Iterator.h
@@ -0,0 +1,196 @@
+#ifndef ACE_TIMER_QUEUE_ITERATOR_H
+#define ACE_TIMER_QUEUE_ITERATOR_H
+#include /**/ "ace/pre.h"
+/**
+ * @file Timer_Queue_Iterator.h
+ *
+ * Re-factored from Timer_Queue_T.h
+ */
+
+#include "ace/Time_Value.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Timer_Node_Dispatch_Info_T
+ *
+ * @brief Maintains generated dispatch information for Timer nodes.
+ *
+ */
+template <class TYPE>
+class ACE_Timer_Node_Dispatch_Info_T
+{
+public:
+ /// The type of object held in the queue
+ TYPE type_;
+
+ /// Asynchronous completion token associated with the timer.
+ const void *act_;
+
+ /// Flag to check if the timer is recurring.
+ int recurring_timer_;
+};
+
+/**
+ * @class ACE_Timer_Node_T
+ *
+ * @brief Maintains the state associated with a Timer entry.
+ */
+template <class TYPE>
+class ACE_Timer_Node_T
+{
+public:
+ /// Default constructor
+ ACE_Timer_Node_T (void);
+
+ /// Destructor
+ ~ACE_Timer_Node_T (void);
+
+ /// Useful typedef ..
+ typedef ACE_Timer_Node_Dispatch_Info_T <TYPE> DISPATCH_INFO;
+
+ /// Singly linked list
+ void set (const TYPE &type,
+ const void *a,
+ const ACE_Time_Value &t,
+ const ACE_Time_Value &i,
+ ACE_Timer_Node_T<TYPE> *n,
+ long timer_id);
+
+ /// Doubly linked list version
+ void set (const TYPE &type,
+ const void *a,
+ const ACE_Time_Value &t,
+ const ACE_Time_Value &i,
+ ACE_Timer_Node_T<TYPE> *p,
+ ACE_Timer_Node_T<TYPE> *n,
+ long timer_id);
+
+ // = Accessors
+
+ /// Get the type.
+ TYPE &get_type (void);
+
+ /// Set the type.
+ void set_type (TYPE &type);
+
+ /// Get the asynchronous completion token.
+ const void *get_act (void);
+
+ /// Set the asynchronous completion token.
+ void set_act (void *act);
+
+ /// Get the timer value.
+ const ACE_Time_Value &get_timer_value (void) const;
+
+ /// Set the timer value.
+ void set_timer_value (const ACE_Time_Value &timer_value);
+
+ /// Get the timer interval.
+ const ACE_Time_Value &get_interval (void) const;
+
+ /// Set the timer interval.
+ void set_interval (const ACE_Time_Value &interval);
+
+ /// Get the previous pointer.
+ ACE_Timer_Node_T<TYPE> *get_prev (void);
+
+ /// Set the previous pointer.
+ void set_prev (ACE_Timer_Node_T<TYPE> *prev);
+
+ /// Get the next pointer.
+ ACE_Timer_Node_T<TYPE> *get_next (void);
+
+ /// Set the next pointer.
+ void set_next (ACE_Timer_Node_T<TYPE> *next);
+
+ /// Get the timer_id.
+ long get_timer_id (void) const;
+
+ /// Set the timer_id.
+ void set_timer_id (long timer_id);
+
+ /// Get the dispatch info. The dispatch information is got
+ /// through <info>. This form helps us in preventing allocation and
+ /// deleting data along the criticl path.
+ /// @@TODO: We may want to have a copying version too, so that our
+ /// interface will be complete..
+ void get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T <TYPE> &info);
+
+ /// Dump the state of an TYPE.
+ void dump (void) const;
+
+private:
+ /// Type of object stored in the Queue
+ TYPE type_;
+
+ /// Asynchronous completion token associated with the timer.
+ const void *act_;
+
+ /// Time until the timer expires.
+ ACE_Time_Value timer_value_;
+
+ /// If this is a periodic timer this holds the time until the next
+ /// timeout.
+ ACE_Time_Value interval_;
+
+ /// Pointer to previous timer.
+ ACE_Timer_Node_T<TYPE> *prev_;
+
+ /// Pointer to next timer.
+ ACE_Timer_Node_T<TYPE> *next_;
+
+ /// Id of this timer (used to cancel timers before they expire).
+ long timer_id_;
+};
+
+/**
+ * @class ACE_Timer_Queue_Iterator_T
+ *
+ * @brief Generic interface for iterating over a subclass of
+ * ACE_Timer_Queue.
+ *
+ * This is a generic iterator that can be used to visit every
+ * node of a timer queue. Be aware that it isn't guaranteed
+ * that the transversal will be in order of timeout values.
+ */
+template <class TYPE>
+class ACE_Timer_Queue_Iterator_T
+{
+public:
+ // = Initialization and termination methods.
+ /// Constructor.
+ ACE_Timer_Queue_Iterator_T (void);
+
+ /// Destructor.
+ virtual ~ACE_Timer_Queue_Iterator_T (void);
+
+ /// Positions the iterator at the earliest node in the Timer Queue
+ virtual void first (void) = 0;
+
+ /// Positions the iterator at the next node in the Timer Queue
+ virtual void next (void) = 0;
+
+ /// Returns true when there are no more nodes in the sequence
+ virtual bool isdone (void) const = 0;
+
+ /// Returns the node at the current position in the sequence
+ virtual ACE_Timer_Node_T<TYPE> *item (void) = 0;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/Timer_Queue_Iterator.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Timer_Queue_Iterator.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Timer_Queue_Iterator.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_TIMER_QUEUE_ITERATOR_H */
diff --git a/ACE/ace/Timer_Queue_Iterator.inl b/ACE/ace/Timer_Queue_Iterator.inl
new file mode 100644
index 00000000000..353f98cf128
--- /dev/null
+++ b/ACE/ace/Timer_Queue_Iterator.inl
@@ -0,0 +1,135 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set (const TYPE &type,
+ const void *a,
+ const ACE_Time_Value &t,
+ const ACE_Time_Value &i,
+ ACE_Timer_Node_T<TYPE> *n,
+ long timer_id)
+{
+ this->type_ = type;
+ this->act_ = a;
+ this->timer_value_ = t;
+ this->interval_ = i;
+ this->next_ = n;
+ this->timer_id_ = timer_id;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set (const TYPE &type,
+ const void *a,
+ const ACE_Time_Value &t,
+ const ACE_Time_Value &i,
+ ACE_Timer_Node_T<TYPE> *p,
+ ACE_Timer_Node_T<TYPE> *n,
+ long timer_id)
+{
+ this->type_ = type;
+ this->act_ = a;
+ this->timer_value_ = t;
+ this->interval_ = i;
+ this->prev_ = p;
+ this->next_ = n;
+ this->timer_id_ = timer_id;
+}
+
+template <class TYPE> ACE_INLINE TYPE &
+ACE_Timer_Node_T<TYPE>::get_type (void)
+{
+ return this->type_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_type (TYPE &type)
+{
+ this->type_ = type;
+}
+
+template <class TYPE> ACE_INLINE const void *
+ACE_Timer_Node_T<TYPE>::get_act (void)
+{
+ return this->act_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_act (void *act)
+{
+ this->act_ = act;
+}
+
+template <class TYPE> ACE_INLINE const ACE_Time_Value &
+ACE_Timer_Node_T<TYPE>::get_timer_value (void) const
+{
+ return this->timer_value_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_timer_value (const ACE_Time_Value &timer_value)
+{
+ this->timer_value_ = timer_value;
+}
+
+template <class TYPE> ACE_INLINE const ACE_Time_Value &
+ACE_Timer_Node_T<TYPE>::get_interval (void) const
+{
+ return this->interval_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_interval (const ACE_Time_Value &interval)
+{
+ this->interval_ = interval;
+}
+
+template <class TYPE> ACE_INLINE ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Node_T<TYPE>::get_prev (void)
+{
+ return this->prev_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_prev (ACE_Timer_Node_T<TYPE> *prev)
+{
+ this->prev_ = prev;
+}
+
+template <class TYPE> ACE_INLINE ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Node_T<TYPE>::get_next (void)
+{
+ return this->next_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_next (ACE_Timer_Node_T<TYPE> *next)
+{
+ this->next_ = next;
+}
+
+template <class TYPE> ACE_INLINE long
+ACE_Timer_Node_T<TYPE>::get_timer_id (void) const
+{
+ return this->timer_id_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::set_timer_id (long timer_id)
+{
+ this->timer_id_ = timer_id;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Timer_Node_T<TYPE>::get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
+{
+ // Yes, do a copy
+ info.type_ = this->type_;
+ info.act_ = this->act_;
+ info.recurring_timer_ =
+ this->interval_ > ACE_Time_Value::zero;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Queue_T.cpp b/ACE/ace/Timer_Queue_T.cpp
index 2ac9a29e9aa..07792ddb6a4 100644
--- a/ACE/ace/Timer_Queue_T.cpp
+++ b/ACE/ace/Timer_Queue_T.cpp
@@ -20,6 +20,7 @@
#include "ace/Reactor_Timer_Interface.h"
#include "ace/Null_Mutex.h"
#include "ace/OS_NS_sys_time.h"
+#include "ace/Functor.h"
#if !defined (__ACE_INLINE__)
#include "ace/Timer_Queue_T.inl"
@@ -34,44 +35,6 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
# define ACE_TIMER_SKEW 0
#endif /* ACE_TIMER_SKEW */
-template <class TYPE> void
-ACE_Timer_Node_T<TYPE>::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- ACE_TRACE ("ACE_Timer_Node_T::dump");
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nact_ = %x"), this->act_));
- this->timer_value_.dump ();
- this->interval_.dump ();
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nprev_ = %x"), this->prev_));
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnext_ = %x"), this->next_));
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_id_ = %d\n"), this->timer_id_));
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-#endif /* ACE_HAS_DUMP */
-}
-
-template <class TYPE>
-ACE_Timer_Node_T<TYPE>::ACE_Timer_Node_T (void)
-{
- ACE_TRACE ("ACE_Timer_Node_T::ACE_Timer_Node_T");
-}
-
-template <class TYPE>
-ACE_Timer_Node_T<TYPE>::~ACE_Timer_Node_T (void)
-{
- ACE_TRACE ("ACE_Timer_Node_T::~ACE_Timer_Node_T");
-}
-
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_Iterator_T (void)
-{
-}
-
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Queue_Iterator_T (void)
-{
-}
-
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time)
{
@@ -152,6 +115,14 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *m
return the_timeout;
}
+template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::current_time()
+{
+ ACE_Time_Value tv = this->gettimeofday();
+ tv += this->timer_skew();
+ return tv;
+}
+
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
{
@@ -283,6 +254,46 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value &cur_ti
return number_of_timers_expired;
}
+template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE int
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire_single (
+ ACE_Command_Base & pre_dispatch_command)
+{
+ ACE_TRACE ("ACE_Timer_Queue_T::expire_single");
+ ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
+
+ if (this->is_empty ())
+ return 0;
+
+ // Get the current time
+ ACE_Time_Value cur_time (this->gettimeofday () +
+ this->timer_skew ());
+
+ // Look for a node in the timer queue whose timer <= the present
+ // time.
+ ACE_Timer_Node_Dispatch_Info_T<TYPE> info;
+ if (this->dispatch_info_i (cur_time, info))
+ {
+ const void *upcall_act = 0;
+
+ // Preinvoke (handles refcount if needed, etc.)
+ this->preinvoke (info, cur_time, upcall_act);
+
+ // Release the token before expiration upcall.
+ pre_dispatch_command.execute();
+
+ // call the functor
+ this->upcall (info, cur_time);
+
+ // Postinvoke (undo refcount if needed, etc.)
+ this->postinvoke (info, cur_time, upcall_act);
+
+ // We have dispatched a timer
+ return 1;
+ }
+
+ return 0;
+}
+
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info_i (const ACE_Time_Value &cur_time,
ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
diff --git a/ACE/ace/Timer_Queue_T.h b/ACE/ace/Timer_Queue_T.h
index 8aef637579e..f796d9975df 100644
--- a/ACE/ace/Timer_Queue_T.h
+++ b/ACE/ace/Timer_Queue_T.h
@@ -16,185 +16,20 @@
#define ACE_TIMER_QUEUE_T_H
#include /**/ "ace/pre.h"
-#include "ace/Free_List.h"
-
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+#include "ace/Free_List.h"
#include "ace/Event_Handler.h"
#include "ace/Time_Value.h"
+#include "ace/Abstract_Timer_Queue.h"
+#include "ace/Timer_Queue_Iterator.h"
+#include "ace/Copy_Disabled.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
- * @class ACE_Timer_Node_Dispatch_Info_T
- *
- * @brief Maintains generated dispatch information for Timer nodes.
- *
- */
-template <class TYPE>
-class ACE_Timer_Node_Dispatch_Info_T
-{
-public:
- /// The type of object held in the queue
- TYPE type_;
-
- /// Asynchronous completion token associated with the timer.
- const void *act_;
-
- /// Flag to check if the timer is recurring.
- int recurring_timer_;
-};
-
-/**
- * @class ACE_Timer_Node_T
- *
- * @brief Maintains the state associated with a Timer entry.
- */
-template <class TYPE>
-class ACE_Timer_Node_T
-{
-public:
- /// Default constructor
- ACE_Timer_Node_T (void);
-
- /// Destructor
- ~ACE_Timer_Node_T (void);
-
- /// Useful typedef ..
- typedef ACE_Timer_Node_Dispatch_Info_T <TYPE> DISPATCH_INFO;
-
- /// Singly linked list
- void set (const TYPE &type,
- const void *a,
- const ACE_Time_Value &t,
- const ACE_Time_Value &i,
- ACE_Timer_Node_T<TYPE> *n,
- long timer_id);
-
- /// Doubly linked list version
- void set (const TYPE &type,
- const void *a,
- const ACE_Time_Value &t,
- const ACE_Time_Value &i,
- ACE_Timer_Node_T<TYPE> *p,
- ACE_Timer_Node_T<TYPE> *n,
- long timer_id);
-
- // = Accessors
-
- /// Get the type.
- TYPE &get_type (void);
-
- /// Set the type.
- void set_type (TYPE &type);
-
- /// Get the asynchronous completion token.
- const void *get_act (void);
-
- /// Set the asynchronous completion token.
- void set_act (void *act);
-
- /// Get the timer value.
- const ACE_Time_Value &get_timer_value (void) const;
-
- /// Set the timer value.
- void set_timer_value (const ACE_Time_Value &timer_value);
-
- /// Get the timer interval.
- const ACE_Time_Value &get_interval (void) const;
-
- /// Set the timer interval.
- void set_interval (const ACE_Time_Value &interval);
-
- /// Get the previous pointer.
- ACE_Timer_Node_T<TYPE> *get_prev (void);
-
- /// Set the previous pointer.
- void set_prev (ACE_Timer_Node_T<TYPE> *prev);
-
- /// Get the next pointer.
- ACE_Timer_Node_T<TYPE> *get_next (void);
-
- /// Set the next pointer.
- void set_next (ACE_Timer_Node_T<TYPE> *next);
-
- /// Get the timer_id.
- long get_timer_id (void) const;
-
- /// Set the timer_id.
- void set_timer_id (long timer_id);
-
- /// Get the dispatch info. The dispatch information is got
- /// through <info>. This form helps us in preventing allocation and
- /// deleting data along the criticl path.
- /// @@TODO: We may want to have a copying version too, so that our
- /// interface will be complete..
- void get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T <TYPE> &info);
-
- /// Dump the state of an TYPE.
- void dump (void) const;
-
-private:
- /// Type of object stored in the Queue
- TYPE type_;
-
- /// Asynchronous completion token associated with the timer.
- const void *act_;
-
- /// Time until the timer expires.
- ACE_Time_Value timer_value_;
-
- /// If this is a periodic timer this holds the time until the next
- /// timeout.
- ACE_Time_Value interval_;
-
- /// Pointer to previous timer.
- ACE_Timer_Node_T<TYPE> *prev_;
-
- /// Pointer to next timer.
- ACE_Timer_Node_T<TYPE> *next_;
-
- /// Id of this timer (used to cancel timers before they expire).
- long timer_id_;
-};
-
-/**
- * @class ACE_Timer_Queue_Iterator_T
- *
- * @brief Generic interface for iterating over a subclass of
- * ACE_Timer_Queue.
- *
- * This is a generic iterator that can be used to visit every
- * node of a timer queue. Be aware that it isn't guaranteed
- * that the transversal will be in order of timeout values.
- */
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-class ACE_Timer_Queue_Iterator_T
-{
-public:
- // = Initialization and termination methods.
- /// Constructor.
- ACE_Timer_Queue_Iterator_T (void);
-
- /// Destructor.
- virtual ~ACE_Timer_Queue_Iterator_T (void);
-
- /// Positions the iterator at the earliest node in the Timer Queue
- virtual void first (void) = 0;
-
- /// Positions the iterator at the next node in the Timer Queue
- virtual void next (void) = 0;
-
- /// Returns true when there are no more nodes in the sequence
- virtual bool isdone (void) const = 0;
-
- /// Returns the node at the current position in the sequence
- virtual ACE_Timer_Node_T<TYPE> *item (void) = 0;
-};
-
-/**
* @class ACE_Timer_Queue_T
*
* @brief Provides an interface to timers.
@@ -205,11 +40,10 @@ public:
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
class ACE_Timer_Queue_T
+ : public ACE_Abstract_Timer_Queue<TYPE>
+ , private ACE_Copy_Disabled
{
public:
- /// Type of Iterator.
- typedef ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> ITERATOR;
-
// = Initialization and termination methods.
/**
* Default constructor. @a upcall_functor is the instance of the
@@ -224,72 +58,24 @@ public:
/// classes.
virtual ~ACE_Timer_Queue_T (void);
- /// True if queue is empty, else false.
- virtual bool is_empty (void) const = 0;
-
- /// Returns the time of the earlier node in the Timer_Queue. Must
- /// be called on a non-empty queue.
- virtual const ACE_Time_Value &earliest_time (void) const = 0;
-
/**
- * Schedule @a type that will expire at @a future_time, which is
- * specified in absolute time. If it expires then @a act is passed
- * in as the value to the <functor>. If @a interval is != to
- * ACE_Time_Value::zero then it is used to reschedule the @a type
- * automatically, using relative time to the current <gettimeofday>.
- * This method returns a <timer_id> that uniquely identifies the the
- * @a type entry in an internal list. This <timer_id> can be used to
- * cancel the timer before it expires. The cancellation ensures
- * that <timer_ids> are unique up to values of greater than 2
- * billion timers. As long as timers don't stay around longer than
- * this there should be no problems with accidentally deleting the
- * wrong timer. Returns -1 on failure (which is guaranteed never to
- * be a valid <timer_id>).
+ * Implement ACE_Abstract_Timer_Queue<TYPE>::schedule () with the right
+ * locking strategy.
*/
virtual long schedule (const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
const ACE_Time_Value &interval = ACE_Time_Value::zero);
+ //@{
/**
- * Resets the interval of the timer represented by @a timer_id to
- * @a interval, which is specified in relative time to the current
- * <gettimeofday>. If @a interval is equal to
- * ACE_Time_Value::zero, the timer will become a non-rescheduling
- * timer. Returns 0 if successful, -1 if not.
- */
- virtual int reset_interval (long timer_id,
- const ACE_Time_Value &interval) = 0;
-
- /**
- * Cancel all timer associated with @a type. If
- * @a dont_call_handle_close is 0 then the <functor> will be invoked,
- * which typically invokes the <handle_close> hook. Returns number
- * of timers cancelled.
- */
- virtual int cancel (const TYPE &type,
- int dont_call_handle_close = 1) = 0;
-
- /**
- * Cancel the single timer that matches the @a timer_id value (which
- * was returned from the <schedule> method). If act is non-NULL
- * then it will be set to point to the ``magic cookie'' argument
- * passed in when the timer was registered. This makes it possible
- * to free up the memory and avoid memory leaks. If
- * @a dont_call_handle_close is 0 then the <functor> will be invoked,
- * which typically calls the <handle_close> hook. Returns 1 if
- * cancellation succeeded and 0 if the @a timer_id wasn't found.
- */
- virtual int cancel (long timer_id,
- const void **act = 0,
- int dont_call_handle_close = 1) = 0;
-
- /**
- * Run the <functor> for all timers whose values are <= @a current_time.
- * This does not account for <timer_skew>. Returns the number of
- * timers canceled.
+ * Implement ACE_Abstract_Timer_Queue<TYPE>::expire () with the right
+ * locking strategy.
*/
virtual int expire (const ACE_Time_Value &current_time);
+ virtual int expire (void);
+ virtual int expire_single(ACE_Command_Base & pre_dispatch_command);
+ //@}
/**
* Get the dispatch information for a timer whose value is <= @a current_time.
@@ -300,73 +86,25 @@ public:
virtual int dispatch_info (const ACE_Time_Value &current_time,
ACE_Timer_Node_Dispatch_Info_T<TYPE> &info);
- /**
- * Run the <functor> for all timers whose values are <=
- * <ACE_OS::gettimeofday>. Also accounts for <timer_skew>.
- *
- * Depending on the resolution of the underlying OS the system calls
- * like select()/poll() might return at time different than that is
- * specified in the timeout. Suppose the OS guarantees a resolution of t ms.
- * The timeline will look like
- *
- * A B
- * | |
- * V V
- * |-------------|-------------|-------------|-------------|
- * t t t t t
- *
- *
- * If you specify a timeout value of A, then the timeout will not occur
- * at A but at the next interval of the timer, which is later than
- * that is expected. Similarly, if your timeout value is equal to B,
- * then the timeout will occur at interval after B. Now depending upon the
- * resolution of your timeouts and the accuracy of the timeouts
- * needed for your application, you should set the value of
- * <timer_skew>. In the above case, if you want the timeout A to fire
- * no later than A, then you should specify your <timer_skew> to be
- * A % t.
- *
- * The timeout value should be specified via the macro ACE_TIMER_SKEW
- * in your config.h file. The default value is zero.
- *
- * Things get interesting if the t before the timeout value B is zero
- * i.e your timeout is less than the interval. In that case, you are
- * almost sure of not getting the desired timeout behaviour. Maybe you
- * should look for a better OS :-)
- *
- * Returns the number of timers canceled.
- */
- /* virtual */ int expire (void);
+ //@{
/**
- * Returns the current time of day. This method allows different
- * implementations of the timer queue to use special high resolution
- * timers.
+ * Implement the gettimeofday() functions
*/
- /* virtual */ ACE_Time_Value gettimeofday (void);
-
- /// Allows applications to control how the timer queue gets the time
- /// of day.
- void gettimeofday (ACE_Time_Value (*gettimeofday)(void));
-
- /// Determine the next event to timeout. Returns @a max if there are
- /// no pending timers or if all pending timers are longer than max.
- /// This method acquires a lock internally since it modifies internal state.
- virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max);
+ virtual ACE_Time_Value gettimeofday (void);
+ virtual void gettimeofday (ACE_Time_Value (*gettimeofday)(void));
+ //@}
+ //@{
/**
- * Determine the next event to timeout. Returns @a max if there are
- * no pending timers or if all pending timers are longer than max.
- * <the_timeout> should be a pointer to storage for the timeout value,
- * and this value is also returned. This method does not acquire a
- * lock internally since it doesn't modify internal state. If you
- * need to call this method when the queue is being modified
- * concurrently, however, you should make sure to acquire the <mutex()>
- * externally before making the call.
+ * Implement calculate_timeout() using the right locking policy
*/
+ virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max);
virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max,
ACE_Time_Value *the_timeout);
+ virtual ACE_Time_Value current_time();
+ //@}
/// Set the timer skew for the Timer_Queue.
void timer_skew (const ACE_Time_Value &skew);
@@ -380,15 +118,12 @@ public:
/// Accessor to the upcall functor
FUNCTOR &upcall_functor (void);
- /// Returns a pointer to this ACE_Timer_Queue's iterator.
- virtual ITERATOR &iter (void) = 0;
+ /// Dump the state of a object.
+ virtual void dump (void) const;
/// Removes the earliest node from the queue and returns it
virtual ACE_Timer_Node_T<TYPE> *remove_first (void) = 0;
- /// Dump the state of a object.
- virtual void dump (void) const;
-
/// Reads the earliest node from the queue and returns it.
virtual ACE_Timer_Node_T<TYPE> *get_first (void) = 0;
@@ -457,10 +192,6 @@ private:
/// Adjusts for timer skew in various clocks.
ACE_Time_Value timer_skew_;
-
- // = Don't allow these operations for now.
- ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Queue_T (const ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> &))
- ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> &))
};
/**
@@ -473,6 +204,7 @@ private:
*/
template <class ACE_LOCK>
class ACE_Event_Handler_Handle_Timeout_Upcall
+ : private ACE_Copy_Disabled
{
public:
typedef ACE_Timer_Queue_T<ACE_Event_Handler *,
@@ -538,10 +270,6 @@ private:
/// Flag indicating that reference counting is required for this
/// event handler upcall.
int requires_reference_counting_;
-
- // = Don't allow these operations for now.
- ACE_UNIMPLEMENTED_FUNC (ACE_Event_Handler_Handle_Timeout_Upcall (const ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK> &))
- ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK> &))
};
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Queue_T.inl b/ACE/ace/Timer_Queue_T.inl
index 7275119e2e1..b282af01b7e 100644
--- a/ACE/ace/Timer_Queue_T.inl
+++ b/ACE/ace/Timer_Queue_T.inl
@@ -4,134 +4,6 @@
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set (const TYPE &type,
- const void *a,
- const ACE_Time_Value &t,
- const ACE_Time_Value &i,
- ACE_Timer_Node_T<TYPE> *n,
- long timer_id)
-{
- this->type_ = type;
- this->act_ = a;
- this->timer_value_ = t;
- this->interval_ = i;
- this->next_ = n;
- this->timer_id_ = timer_id;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set (const TYPE &type,
- const void *a,
- const ACE_Time_Value &t,
- const ACE_Time_Value &i,
- ACE_Timer_Node_T<TYPE> *p,
- ACE_Timer_Node_T<TYPE> *n,
- long timer_id)
-{
- this->type_ = type;
- this->act_ = a;
- this->timer_value_ = t;
- this->interval_ = i;
- this->prev_ = p;
- this->next_ = n;
- this->timer_id_ = timer_id;
-}
-
-template <class TYPE> ACE_INLINE TYPE &
-ACE_Timer_Node_T<TYPE>::get_type (void)
-{
- return this->type_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_type (TYPE &type)
-{
- this->type_ = type;
-}
-
-template <class TYPE> ACE_INLINE const void *
-ACE_Timer_Node_T<TYPE>::get_act (void)
-{
- return this->act_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_act (void *act)
-{
- this->act_ = act;
-}
-
-template <class TYPE> ACE_INLINE const ACE_Time_Value &
-ACE_Timer_Node_T<TYPE>::get_timer_value (void) const
-{
- return this->timer_value_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_timer_value (const ACE_Time_Value &timer_value)
-{
- this->timer_value_ = timer_value;
-}
-
-template <class TYPE> ACE_INLINE const ACE_Time_Value &
-ACE_Timer_Node_T<TYPE>::get_interval (void) const
-{
- return this->interval_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_interval (const ACE_Time_Value &interval)
-{
- this->interval_ = interval;
-}
-
-template <class TYPE> ACE_INLINE ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Node_T<TYPE>::get_prev (void)
-{
- return this->prev_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_prev (ACE_Timer_Node_T<TYPE> *prev)
-{
- this->prev_ = prev;
-}
-
-template <class TYPE> ACE_INLINE ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Node_T<TYPE>::get_next (void)
-{
- return this->next_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_next (ACE_Timer_Node_T<TYPE> *next)
-{
- this->next_ = next;
-}
-
-template <class TYPE> ACE_INLINE long
-ACE_Timer_Node_T<TYPE>::get_timer_id (void) const
-{
- return this->timer_id_;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::set_timer_id (long timer_id)
-{
- this->timer_id_ = timer_id;
-}
-
-template <class TYPE> ACE_INLINE void
-ACE_Timer_Node_T<TYPE>::get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
-{
- // Yes, do a copy
- info.type_ = this->type_;
- info.act_ = this->act_;
- info.recurring_timer_ =
- this->interval_ > ACE_Time_Value::zero;
-}
-
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE void
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::timer_skew (const ACE_Time_Value &skew)
{
diff --git a/ACE/ace/Timer_Queuefwd.h b/ACE/ace/Timer_Queuefwd.h
index 6e03204bdde..af1b844d84d 100644
--- a/ACE/ace/Timer_Queuefwd.h
+++ b/ACE/ace/Timer_Queuefwd.h
@@ -17,19 +17,13 @@
#include /**/ "ace/pre.h"
-#include "ace/Synch_Traits.h"
+#include "ace/config-all.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-template <class TYPE, class FUNCTOR, class ACE_LOCK> class ACE_Timer_Queue_T;
-template <class ACE_LOCK> class ACE_Event_Handler_Handle_Timeout_Upcall;
-
class ACE_Event_Handler;
-
-typedef ACE_Timer_Queue_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
- ACE_SYNCH_RECURSIVE_MUTEX>
- ACE_Timer_Queue;
+template <class TYPE> class ACE_Abstract_Timer_Queue;
+typedef ACE_Abstract_Timer_Queue<ACE_Event_Handler*> ACE_Timer_Queue;
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Wheel_T.cpp b/ACE/ace/Timer_Wheel_T.cpp
index b860c1604dd..1392c63a5a7 100644
--- a/ACE/ace/Timer_Wheel_T.cpp
+++ b/ACE/ace/Timer_Wheel_T.cpp
@@ -783,7 +783,7 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
* @return The iterator
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>&
+ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
{
this->iterator_->first ();
diff --git a/ACE/ace/Timer_Wheel_T.h b/ACE/ace/Timer_Wheel_T.h
index 40179f7a734..431944bb024 100644
--- a/ACE/ace/Timer_Wheel_T.h
+++ b/ACE/ace/Timer_Wheel_T.h
@@ -37,7 +37,7 @@ class ACE_Timer_Wheel_T;
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
class ACE_Timer_Wheel_Iterator_T
- : public ACE_Timer_Queue_Iterator_T <TYPE, FUNCTOR, ACE_LOCK>
+ : public ACE_Timer_Queue_Iterator_T <TYPE>
{
public:
typedef ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK> Wheel;
@@ -150,7 +150,7 @@ public:
int expire (const ACE_Time_Value& current_time);
/// Returns a pointer to this <ACE_Timer_Queue_T>'s iterator.
- virtual ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>& iter (void);
+ virtual ACE_Timer_Queue_Iterator_T<TYPE> & iter (void);
/// Removes the earliest node from the queue and returns it
virtual ACE_Timer_Node_T<TYPE>* remove_first (void);
diff --git a/ACE/ace/ace.mpc b/ACE/ace/ace.mpc
index fbc2424a2ed..859668c158d 100644
--- a/ACE/ace/ace.mpc
+++ b/ACE/ace/ace.mpc
@@ -282,6 +282,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
}
Template_Files {
+ Abstract_Timer_Queue.cpp
Acceptor.cpp
Active_Map_Manager_T.cpp
ARGV.cpp
@@ -358,6 +359,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Timer_Heap_T.cpp
Timer_List_T.cpp
Timer_Queue_Adapters.cpp
+ Timer_Queue_Iterator.cpp
Timer_Queue_T.cpp
Timer_Wheel_T.cpp
Tokenizer_T.cpp
diff --git a/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp b/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
index d0dcafff858..17abcf0827c 100644
--- a/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
+++ b/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
@@ -266,38 +266,8 @@ invoke_expire (ACE_Timer_Queue &timer_queue)
int
invoke_one_upcall (ACE_Timer_Queue &timer_queue)
{
- // Get the current time
- ACE_Time_Value current_time (timer_queue.gettimeofday () +
- timer_queue.timer_skew ());
-
- // Look for a node in the timer queue whose timer <= the present
- // time.
- ACE_Timer_Node_Dispatch_Info dispatch_info;
-
- if (timer_queue.dispatch_info (current_time,
- dispatch_info))
- {
- const void *upcall_act = 0;
-
- // Preinvoke.
- timer_queue.preinvoke (dispatch_info,
- current_time,
- upcall_act);
-
- // Call the functor
- timer_queue.upcall (dispatch_info,
- current_time);
-
- // Postinvoke
- timer_queue.postinvoke (dispatch_info,
- current_time,
- upcall_act);
-
- // We have dispatched a timer
- return 1;
- }
-
- return 0;
+ ACE_Noop_Command command;
+ return timer_queue.expire_single(command);
}
void