summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-07-01 02:47:57 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-07-01 02:47:57 +0000
commit8632f81b2f8f469d49c38503d06bd8b54988812b (patch)
tree113516effff8968ec4bfa84951f88497d5f7a12b
parentaa1eef1fa01b1db730140bf91cb9439594ce49de (diff)
downloadATCD-8632f81b2f8f469d49c38503d06bd8b54988812b.tar.gz
Wed Jul 1 02:09:44 UTC 2009 Carlos O'Ryan <coryan@glamdring>
* ace/ace.mpc: * ace/Makefile.am: * ace/Event_Handler_Handle_Timeout_Upcall.h: * ace/Event_Handler_Handle_Timeout_Upcall.inl: * ace/Event_Handler_Handle_Timeout_Upcall.cpp: First I noticed that this class did not depend on the lock type at all, this was fortunate because I wanted to use it in a generic way. So, change the class from a template class to a regular class. That required moving the class to its own file too. * 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: Fixed several inconsistencies across these classes, for example, most of them had typedef as a shorthand for the base class, but the name of this typedef was not consistent. Likewise, not all of the classes made the TIME_POLICY parameter a default template parameter. * ace/Timer_Queue_T.h: * ace/Timer_Queue_T.inl: * ace/Timer_Queue_T.cpp: Introduced an intermediate class between Abstract_Timer_Queue<> and Timer_Queue_T<>. This is ugly, but the Proactor "needs" to set a back-pointer from the FUNCTOR to the Proacter instance whenever a timer queue is assigned to the Proactor. This code smells funny. Either the API is wrong (the Proactor should always create the functor with the backpointer,) or the need for the back pointer is suspicious (I think there is a thread in the Proactor that signals timers, but maybe it should be contained in the Upcall object itself?) The more I look here, the uglier the smell. * ace/Select_Reactor_T.cpp: * ace/Timer_Queue_Adapters.cpp: * tests/Timer_Queue_Reference_Counting_Test.cpp: * tests/Timer_Queue_Test.cpp: As a temporary measure, I appended "_abstract" to the gettimeofday() function name in Abstract_Timer_Queue<>. Shortly, I will change the Timer_Queue_T<> class to use gettimeofday_non_virtual() or _static() or something similar. Had to make the change in two steps to find all the uses of the original function. There was probably an easier/cleaner way to do this. * tests/Timer_Queue_Test.cpp: Take advantage of the new ACE_Abstract_Timer_Queue<> to make the different types of queues more compatible in ths test, including queues with different time source policies. * ace/Proactor.h: As with the Reactive version, I noticed that ACE_Proactor_Handle_Timeout_Upcall did not depend on its template parameter, so I changed the class to a non-template version. * ace/Proactor.cpp: Instead of making the Proactor a friend of the Timer_Handler task, expose a safe interface to do what the proactor wants to do. The proactor needed access to timer queue internal details to implement schedule(), but the reactor did not... hmmm... well, turns out the Reactor had nicely refactor that work to the upcall functor. So I did the same in the Proactor case. * ace/Timer_List.h: * ace/Timer_Wheel.h: * ace/Timer_Hash.h: * ace/Timer_Heap.h: Use Event_Handler_Handle_Timeout_Upcall without the template parameter. * ace/Abstract_Timer_Queue.h: Remove the setter for getimeofday(), this is implemented by the TIME_POLICY template parameter in Timer_Queue_T<> * tests/Reactor_Timer_Test.cpp: * tests/Network_Adapters_Test.cpp: * tests/Proactor_Timer_Test.cpp: Use a different idiom to set the time policy for this test. * examples/Timer_Queue/Thread_Timer_Queue_Test.h: * examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h: * examples/APG/Timers/Timers.cpp: * examples/APG/Timers/TimerDispatcher.cpp: * examples/Reactor/Misc/test_timer_queue.cpp: * examples/C++NPv2/Logging_Event_Handler_Ex.cpp: Need an additional #include for ACE_Event_Handler_Handle_Timeout Said class class is no longer a template class, so use it correctly. Changed name of gettimeofday() in timer queue to gettimeofday_abstract() This is a temporary change to find all the uses, will revert again soon. * Merged in changes from bug-3607 branch. * 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/ChangeLog163
-rw-r--r--ACE/ace/Abstract_Timer_Queue.cpp24
-rw-r--r--ACE/ace/Abstract_Timer_Queue.h212
-rw-r--r--ACE/ace/Dev_Poll_Reactor.cpp36
-rw-r--r--ACE/ace/Event_Handler_Handle_Timeout_Upcall.cpp98
-rw-r--r--ACE/ace/Event_Handler_Handle_Timeout_Upcall.h99
-rw-r--r--ACE/ace/Event_Handler_Handle_Timeout_Upcall.inl71
-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/Makefile.am8
-rw-r--r--ACE/ace/Proactor.cpp98
-rw-r--r--ACE/ace/Proactor.h46
-rw-r--r--ACE/ace/Select_Reactor_T.cpp2
-rw-r--r--ACE/ace/TP_Reactor.cpp37
-rw-r--r--ACE/ace/Timer_Hash.h11
-rw-r--r--ACE/ace/Timer_Hash_T.cpp32
-rw-r--r--ACE/ace/Timer_Hash_T.h15
-rw-r--r--ACE/ace/Timer_Heap.h14
-rw-r--r--ACE/ace/Timer_Heap_T.cpp14
-rw-r--r--ACE/ace/Timer_Heap_T.h6
-rw-r--r--ACE/ace/Timer_List.h5
-rw-r--r--ACE/ace/Timer_List_T.cpp8
-rw-r--r--ACE/ace/Timer_List_T.h11
-rw-r--r--ACE/ace/Timer_Queue.h4
-rw-r--r--ACE/ace/Timer_Queue_Adapters.cpp2
-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.cpp256
-rw-r--r--ACE/ace/Timer_Queue_T.h416
-rw-r--r--ACE/ace/Timer_Queue_T.inl134
-rw-r--r--ACE/ace/Timer_Queuefwd.h14
-rw-r--r--ACE/ace/Timer_Wheel.h5
-rw-r--r--ACE/ace/Timer_Wheel_T.cpp6
-rw-r--r--ACE/ace/Timer_Wheel_T.h8
-rw-r--r--ACE/ace/ace.mpc3
-rw-r--r--ACE/examples/APG/Timers/TimerDispatcher.cpp4
-rw-r--r--ACE/examples/APG/Timers/Timers.cpp2
-rw-r--r--ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h3
-rw-r--r--ACE/examples/C++NPv2/Logging_Event_Handler_Ex.cpp2
-rw-r--r--ACE/examples/Reactor/Misc/test_timer_queue.cpp1
-rw-r--r--ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h3
-rw-r--r--ACE/tests/Network_Adapters_Test.cpp25
-rw-r--r--ACE/tests/Proactor_Timer_Test.cpp29
-rw-r--r--ACE/tests/Reactor_Timer_Test.cpp27
-rw-r--r--ACE/tests/Timer_Queue_Reference_Counting_Test.cpp50
-rw-r--r--ACE/tests/Timer_Queue_Test.cpp40
49 files changed, 1534 insertions, 977 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index 6c915c76e95..9e4b74041f5 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,166 @@
+Wed Jul 1 02:09:44 UTC 2009 Carlos O'Ryan <coryan@glamdring>
+
+ * ace/ace.mpc:
+ * ace/Makefile.am:
+ * ace/Event_Handler_Handle_Timeout_Upcall.h:
+ * ace/Event_Handler_Handle_Timeout_Upcall.inl:
+ * ace/Event_Handler_Handle_Timeout_Upcall.cpp:
+ First I noticed that this class did not depend on the lock type
+ at all, this was fortunate because I wanted to use it in a
+ generic way. So, change the class from a template class to a
+ regular class. That required moving the class to its own file too.
+
+ * 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:
+ Fixed several inconsistencies across these classes, for example,
+ most of them had typedef as a shorthand for the base class, but
+ the name of this typedef was not consistent.
+ Likewise, not all of the classes made the TIME_POLICY parameter
+ a default template parameter.
+
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+ * ace/Timer_Queue_T.cpp:
+ Introduced an intermediate class between Abstract_Timer_Queue<>
+ and Timer_Queue_T<>. This is ugly, but the Proactor "needs" to
+ set a back-pointer from the FUNCTOR to the Proacter instance
+ whenever a timer queue is assigned to the Proactor.
+ This code smells funny. Either the API is wrong (the Proactor
+ should always create the functor with the backpointer,) or the
+ need for the back pointer is suspicious (I think there is a
+ thread in the Proactor that signals timers, but maybe it should
+ be contained in the Upcall object itself?)
+ The more I look here, the uglier the smell.
+
+ * ace/Select_Reactor_T.cpp:
+ * ace/Timer_Queue_Adapters.cpp:
+ * tests/Timer_Queue_Reference_Counting_Test.cpp:
+ * tests/Timer_Queue_Test.cpp:
+ As a temporary measure, I appended "_abstract" to the
+ gettimeofday() function name in Abstract_Timer_Queue<>.
+ Shortly, I will change the Timer_Queue_T<> class to use
+ gettimeofday_non_virtual() or _static() or something similar.
+ Had to make the change in two steps to find all the uses of the
+ original function.
+ There was probably an easier/cleaner way to do this.
+
+ * tests/Timer_Queue_Test.cpp:
+ Take advantage of the new ACE_Abstract_Timer_Queue<> to make the
+ different types of queues more compatible in ths test, including
+ queues with different time source policies.
+
+ * ace/Proactor.h:
+ As with the Reactive version, I noticed that
+ ACE_Proactor_Handle_Timeout_Upcall did not depend on its
+ template parameter, so I changed the class to a non-template
+ version.
+
+ * ace/Proactor.cpp:
+ Instead of making the Proactor a friend of the Timer_Handler
+ task, expose a safe interface to do what the proactor wants to
+ do.
+ The proactor needed access to timer queue internal details to
+ implement schedule(), but the reactor did not... hmmm... well,
+ turns out the Reactor had nicely refactor that work to the
+ upcall functor. So I did the same in the Proactor case.
+
+
+ * ace/Timer_List.h:
+ * ace/Timer_Wheel.h:
+ * ace/Timer_Hash.h:
+ * ace/Timer_Heap.h:
+ Use Event_Handler_Handle_Timeout_Upcall without the template
+ parameter.
+
+ * ace/Abstract_Timer_Queue.h:
+ Remove the setter for getimeofday(), this is implemented by the
+ TIME_POLICY template parameter in Timer_Queue_T<>
+
+ * tests/Reactor_Timer_Test.cpp:
+ * tests/Network_Adapters_Test.cpp:
+ * tests/Proactor_Timer_Test.cpp:
+ Use a different idiom to set the time policy for this test.
+
+ * examples/Timer_Queue/Thread_Timer_Queue_Test.h:
+ * examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h:
+ * examples/APG/Timers/Timers.cpp:
+ * examples/APG/Timers/TimerDispatcher.cpp:
+ * examples/Reactor/Misc/test_timer_queue.cpp:
+ * examples/C++NPv2/Logging_Event_Handler_Ex.cpp:
+ Need an additional #include for ACE_Event_Handler_Handle_Timeout
+ Said class class is no longer a template class, so use it
+ correctly.
+ Changed name of gettimeofday() in timer queue to
+ gettimeofday_abstract() This is a temporary change to find all
+ the uses, will revert again soon.
+
+ * Merged in changes from bug-3607 branch.
+
+ * 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()
+
Tue Jun 30 01:10:04 UTC 2009 Carlos O'Ryan <coryan@glamdring>
* This is a temporary commit into the 3707 branch. I realized too
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..4e9fc299c71
--- /dev/null
+++ b/ACE/ace/Abstract_Timer_Queue.h
@@ -0,0 +1,212 @@
+#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;
+template<typename TYPE> class ACE_Timer_Node_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_abstract (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;
+
+ /// Removes the earliest node from the queue and returns it
+ virtual ACE_Timer_Node_T<TYPE> *remove_first (void) = 0;
+
+ /// Reads the earliest node from the queue and returns it.
+ virtual ACE_Timer_Node_T<TYPE> *get_first (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..3437398e124 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
@@ -1924,7 +1898,7 @@ ACE_Dev_Poll_Reactor::schedule_timer (ACE_Event_Handler *event_handler,
return this->timer_queue_->schedule
(event_handler,
arg,
- this->timer_queue_->gettimeofday () + delay,
+ this->timer_queue_->gettimeofday_abstract () + delay,
interval);
errno = ESHUTDOWN;
diff --git a/ACE/ace/Event_Handler_Handle_Timeout_Upcall.cpp b/ACE/ace/Event_Handler_Handle_Timeout_Upcall.cpp
new file mode 100644
index 00000000000..17ab1e04da2
--- /dev/null
+++ b/ACE/ace/Event_Handler_Handle_Timeout_Upcall.cpp
@@ -0,0 +1,98 @@
+// $Id$
+
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
+#include "ace/Reactor_Timer_Interface.h"
+#include "ace/Abstract_Timer_Queue.h"
+
+#if !defined(__ACE_INLINE__)
+# include "ace/Event_Handler_Handle_Timeout_Upcall.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_Event_Handler_Handle_Timeout_Upcall::
+ACE_Event_Handler_Handle_Timeout_Upcall (void)
+{
+}
+
+ACE_Event_Handler_Handle_Timeout_Upcall::
+~ACE_Event_Handler_Handle_Timeout_Upcall (void)
+{
+}
+
+int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+timeout (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *event_handler,
+ const void *act,
+ int recurring_timer,
+ const ACE_Time_Value &cur_time)
+{
+ int requires_reference_counting = 0;
+
+ if (!recurring_timer)
+ {
+ requires_reference_counting =
+ event_handler->reference_counting_policy ().value () ==
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
+ }
+
+ // Upcall to the <handler>s handle_timeout method.
+ if (event_handler->handle_timeout (cur_time, act) == -1)
+ {
+ if (event_handler->reactor_timer_interface ())
+ event_handler->reactor_timer_interface ()->cancel_timer (event_handler, 0);
+ else
+ timer_queue.cancel (event_handler, 0); // 0 means "call handle_close()".
+ }
+
+ if (!recurring_timer &&
+ requires_reference_counting)
+ {
+ event_handler->remove_reference ();
+ }
+
+ return 0;
+}
+
+int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+cancel_type (ACE_Timer_Queue &,
+ ACE_Event_Handler *event_handler,
+ int dont_call,
+ int &requires_reference_counting)
+{
+ requires_reference_counting =
+ event_handler->reference_counting_policy ().value () ==
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
+
+ // Upcall to the <handler>s handle_close method
+ if (dont_call == 0)
+ event_handler->handle_close (ACE_INVALID_HANDLE,
+ ACE_Event_Handler::TIMER_MASK);
+
+ return 0;
+}
+
+int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+deletion (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *event_handler,
+ const void *)
+{
+ int requires_reference_counting = 0;
+
+ this->cancel_type (timer_queue,
+ event_handler,
+ 0,
+ requires_reference_counting);
+
+ this->cancel_timer (timer_queue,
+ event_handler,
+ 0,
+ requires_reference_counting);
+
+ return 0;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Event_Handler_Handle_Timeout_Upcall.h b/ACE/ace/Event_Handler_Handle_Timeout_Upcall.h
new file mode 100644
index 00000000000..55c1bb347a9
--- /dev/null
+++ b/ACE/ace/Event_Handler_Handle_Timeout_Upcall.h
@@ -0,0 +1,99 @@
+#ifndef ACE_EVENT_HANDLER_HANDLE_TIMEOUT_UPCALL_H
+#define ACE_EVENT_HANDLER_HANDLE_TIMEOUT_UPCALL_H
+#include /**/ "ace/pre.h"
+/**
+ * @file Event_Handler_Handle_Timeout_Upcall.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.
+ */
+
+#include "ace/Timer_Queuefwd.h"
+#include "ace/Copy_Disabled.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class ACE_Time_Value;
+
+/**
+ * @class ACE_Event_Handler_Handle_Timeout_Upcall
+ *
+ * @brief Functor for Timer_Queues.
+ *
+ * This class implements the functor required by the Timer
+ * Queue to call <handle_timeout> on ACE_Event_Handlers.
+ */
+class ACE_Export ACE_Event_Handler_Handle_Timeout_Upcall
+ : private ACE_Copy_Disabled
+{
+public:
+ // = Initialization and termination methods.
+ /// Constructor.
+ ACE_Event_Handler_Handle_Timeout_Upcall (void);
+
+ /// Destructor.
+ ~ACE_Event_Handler_Handle_Timeout_Upcall (void);
+
+ /// This method is called when a timer is registered.
+ int registration (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ const void *arg);
+
+ /// This method is called before the timer expires.
+ int preinvoke (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ const void *arg,
+ int recurring_timer,
+ const ACE_Time_Value &cur_time,
+ const void *&upcall_act);
+
+ /// This method is called when the timer expires.
+ int timeout (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ const void *arg,
+ int recurring_timer,
+ const ACE_Time_Value &cur_time);
+
+ /// This method is called after the timer expires.
+ int postinvoke (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ const void *arg,
+ int recurring_timer,
+ const ACE_Time_Value &cur_time,
+ const void *upcall_act);
+
+ /// This method is called when a handler is cancelled
+ int cancel_type (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ int dont_call,
+ int &requires_reference_counting);
+
+ /// This method is called when a timer is cancelled
+ int cancel_timer (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ int dont_call,
+ int requires_reference_counting);
+
+ /// This method is called when the timer queue is destroyed and
+ /// the timer is still contained in it
+ int deletion (ACE_Timer_Queue &timer_queue,
+ ACE_Event_Handler *handler,
+ const void *arg);
+
+private:
+
+ /// Flag indicating that reference counting is required for this
+ /// event handler upcall.
+ int requires_reference_counting_;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined(__ACE_INLINE__)
+# include "ace/Event_Handler_Handle_Timeout_Upcall.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_EVENT_HANDLER_HANDLE_TIMEOUT_UPCALL_H */
diff --git a/ACE/ace/Event_Handler_Handle_Timeout_Upcall.inl b/ACE/ace/Event_Handler_Handle_Timeout_Upcall.inl
new file mode 100644
index 00000000000..a2dc51cc453
--- /dev/null
+++ b/ACE/ace/Event_Handler_Handle_Timeout_Upcall.inl
@@ -0,0 +1,71 @@
+// $Id$
+
+#include "ace/Event_Handler.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+registration (ACE_Timer_Queue &,
+ ACE_Event_Handler *event_handler,
+ const void *)
+{
+ event_handler->add_reference ();
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+preinvoke (ACE_Timer_Queue &,
+ ACE_Event_Handler *event_handler,
+ const void *,
+ int,
+ const ACE_Time_Value &,
+ const void * & upcall_act)
+{
+ bool const requires_reference_counting =
+ event_handler->reference_counting_policy ().value () ==
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
+
+ if (requires_reference_counting)
+ {
+ event_handler->add_reference ();
+
+ upcall_act = &this->requires_reference_counting_;
+ }
+
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+postinvoke (ACE_Timer_Queue & /* timer_queue */,
+ ACE_Event_Handler *event_handler,
+ const void * /* timer_act */,
+ int /* recurring_timer */,
+ const ACE_Time_Value & /* cur_time */,
+ const void *upcall_act)
+{
+ if (upcall_act == &this->requires_reference_counting_)
+ {
+ event_handler->remove_reference ();
+ }
+
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Event_Handler_Handle_Timeout_Upcall::
+cancel_timer (ACE_Timer_Queue &,
+ ACE_Event_Handler *event_handler,
+ int,
+ int requires_reference_counting)
+{
+ if (requires_reference_counting)
+ event_handler->remove_reference ();
+
+ return 0;
+}
+
+
+ACE_END_VERSIONED_NAMESPACE_DECL
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/Makefile.am b/ACE/ace/Makefile.am
index 8a21c9da631..3c6a12258ea 100644
--- a/ACE/ace/Makefile.am
+++ b/ACE/ace/Makefile.am
@@ -98,6 +98,7 @@ libACE_la_SOURCES = \
Encoding_Converter_Factory.cpp \
Event.cpp \
Event_Handler.cpp \
+ Event_Handler_Handle_Timeout_Upcall.cpp \
FIFO.cpp \
FIFO_Recv.cpp \
FIFO_Recv_Msg.cpp \
@@ -367,6 +368,8 @@ nobase_include_HEADERS += \
ATM_QoS.inl \
ATM_Stream.h \
ATM_Stream.inl \
+ Abstract_Timer_Queue.h \
+ Abstract_Timer_Queue.cpp \
Acceptor.cpp \
Acceptor.h \
Activation_Queue.h \
@@ -516,6 +519,8 @@ nobase_include_HEADERS += \
Event.inl \
Event_Handler.h \
Event_Handler.inl \
+ Event_Handler_Handle_Timeout_Upcall.h \
+ Event_Handler_Handle_Timeout_Upcall.inl \
Event_Handler_T.cpp \
Event_Handler_T.h \
Event_Handler_T.inl \
@@ -1069,6 +1074,9 @@ nobase_include_HEADERS += \
Timer_Queue_Adapters.cpp \
Timer_Queue_Adapters.h \
Timer_Queue_Adapters.inl \
+ Timer_Queue_Iterator.h \
+ Timer_Queue_Iterator.inl \
+ Timer_Queue_Iterator.cpp \
Timer_Queue_T.cpp \
Timer_Queue_T.h \
Timer_Queue_T.inl \
diff --git a/ACE/ace/Proactor.cpp b/ACE/ace/Proactor.cpp
index 883a567c1fb..b844dd1fe41 100644
--- a/ACE/ace/Proactor.cpp
+++ b/ACE/ace/Proactor.cpp
@@ -63,11 +63,6 @@ bool ACE_Proactor::delete_proactor_ = false;
*/
class ACE_Proactor_Timer_Handler : public ACE_Task<ACE_NULL_SYNCH>
{
-
- /// Proactor has special privileges
- /// Access needed to: timer_event_
- friend class ACE_Proactor;
-
public:
/// Constructor.
ACE_Proactor_Timer_Handler (ACE_Proactor &proactor);
@@ -80,6 +75,11 @@ public:
/// <destroy> does. <destroy> make sure the thread exits properly.
int destroy (void);
+ /// Proactor calls this to refresh the timer event thread, to wake
+ /// up the thread from a sleep. This is needed to make the thread
+ /// recompute its sleep time after changes to the timer queue.
+ int signal (void);
+
protected:
/// Run by a daemon thread to handle deferred processing. In other
/// words, this method will do the waiting on the earliest timer and
@@ -105,6 +105,12 @@ ACE_Proactor_Timer_Handler::ACE_Proactor_Timer_Handler (ACE_Proactor &proactor)
ACE_Proactor_Timer_Handler::~ACE_Proactor_Timer_Handler (void)
{
+ this->destroy();
+}
+
+int
+ACE_Proactor_Timer_Handler::destroy (void)
+{
// Mark for closing down.
this->shutting_down_ = 1;
@@ -113,6 +119,13 @@ ACE_Proactor_Timer_Handler::~ACE_Proactor_Timer_Handler (void)
// Wait for the Timer Handler thread to exit.
this->wait ();
+ return 0;
+}
+
+int
+ACE_Proactor_Timer_Handler::signal (void)
+{
+ return this->timer_event_.signal ();
}
int
@@ -132,7 +145,7 @@ ACE_Proactor_Timer_Handler::svc (void)
// Get current time from timer queue since we don't know
// which <gettimeofday> was used.
- ACE_Time_Value cur_time = this->proactor_.timer_queue ()->gettimeofday ();
+ ACE_Time_Value cur_time = this->proactor_.timer_queue ()->gettimeofday_abstract ();
// Compare absolute time with curent time received from the
// timer queue.
@@ -177,15 +190,16 @@ ACE_Proactor_Handle_Timeout_Upcall::ACE_Proactor_Handle_Timeout_Upcall (void)
}
int
-ACE_Proactor_Handle_Timeout_Upcall::registration (TIMER_QUEUE &,
- ACE_Handler *,
+ACE_Proactor_Handle_Timeout_Upcall::registration (ACE_Proactor_Timer_Queue &,
+ ACE_Handler * handler,
const void *)
{
+ handler->proactor(proactor_);
return 0;
}
int
-ACE_Proactor_Handle_Timeout_Upcall::preinvoke (TIMER_QUEUE &,
+ACE_Proactor_Handle_Timeout_Upcall::preinvoke (ACE_Proactor_Timer_Queue &,
ACE_Handler *,
const void *,
int,
@@ -196,7 +210,7 @@ ACE_Proactor_Handle_Timeout_Upcall::preinvoke (TIMER_QUEUE &,
}
int
-ACE_Proactor_Handle_Timeout_Upcall::postinvoke (TIMER_QUEUE &,
+ACE_Proactor_Handle_Timeout_Upcall::postinvoke (ACE_Proactor_Timer_Queue &,
ACE_Handler *,
const void *,
int,
@@ -207,7 +221,7 @@ ACE_Proactor_Handle_Timeout_Upcall::postinvoke (TIMER_QUEUE &,
}
int
-ACE_Proactor_Handle_Timeout_Upcall::timeout (TIMER_QUEUE &,
+ACE_Proactor_Handle_Timeout_Upcall::timeout (ACE_Proactor_Timer_Queue &,
ACE_Handler *handler,
const void *act,
int,
@@ -253,7 +267,7 @@ ACE_Proactor_Handle_Timeout_Upcall::timeout (TIMER_QUEUE &,
}
int
-ACE_Proactor_Handle_Timeout_Upcall::cancel_type (TIMER_QUEUE &,
+ACE_Proactor_Handle_Timeout_Upcall::cancel_type (ACE_Proactor_Timer_Queue &,
ACE_Handler *,
int,
int &)
@@ -263,7 +277,7 @@ ACE_Proactor_Handle_Timeout_Upcall::cancel_type (TIMER_QUEUE &,
}
int
-ACE_Proactor_Handle_Timeout_Upcall::cancel_timer (TIMER_QUEUE &,
+ACE_Proactor_Handle_Timeout_Upcall::cancel_timer (ACE_Proactor_Timer_Queue &,
ACE_Handler *,
int,
int)
@@ -273,7 +287,7 @@ ACE_Proactor_Handle_Timeout_Upcall::cancel_timer (TIMER_QUEUE &,
}
int
-ACE_Proactor_Handle_Timeout_Upcall::deletion (TIMER_QUEUE &,
+ACE_Proactor_Handle_Timeout_Upcall::deletion (ACE_Proactor_Timer_Queue &,
ACE_Handler *,
const void *)
{
@@ -300,7 +314,7 @@ ACE_Proactor_Handle_Timeout_Upcall::proactor (ACE_Proactor &proactor)
ACE_Proactor::ACE_Proactor (ACE_Proactor_Impl *implementation,
bool delete_implementation,
- TIMER_QUEUE *tq)
+ ACE_Proactor_Timer_Queue *tq)
: implementation_ (0),
delete_implementation_ (delete_implementation),
timer_handler_ (0),
@@ -670,43 +684,14 @@ ACE_Proactor::schedule_timer (ACE_Handler &handler,
{
// absolute time.
ACE_Time_Value absolute_time =
- this->timer_queue_->gettimeofday () + time;
-
- // Only one guy goes in here at a time
- ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
- ace_mon,
- this->timer_queue_->mutex (),
- -1));
-
- // Remember the old proactor.
- ACE_Proactor *old_proactor = handler.proactor ();
-
- // Assign *this* Proactor to the handler.
- handler.proactor (this);
-
- // Schedule the timer
- long result = this->timer_queue_->schedule (&handler,
- act,
- absolute_time,
- interval);
+ this->timer_queue_->gettimeofday_abstract () + time;
+ long result = this->timer_queue_->schedule(&handler, act,
+ absolute_time, interval);
if (result != -1)
{
- // no failures: check to see if we are the earliest time
- if (this->timer_queue_->earliest_time () == absolute_time)
-
- // wake up the timer thread
- if (this->timer_handler_->timer_event_.signal () == -1)
- {
- // Cancel timer
- this->timer_queue_->cancel (result);
- result = -1;
- }
- }
-
- if (result == -1)
- {
- // Reset the old proactor in case of failures.
- handler.proactor (old_proactor);
+ // Signal the timer thread to make sure that new events are
+ // dispatched and the sleep time is updated.
+ (void) this->timer_handler_->signal ();
}
return result;
@@ -770,14 +755,14 @@ ACE_Proactor::number_of_threads (size_t threads)
this->implementation ()->number_of_threads (threads);
}
-ACE_Proactor::TIMER_QUEUE *
+ACE_Proactor_Timer_Queue *
ACE_Proactor::timer_queue (void) const
{
return this->timer_queue_;
}
void
-ACE_Proactor::timer_queue (TIMER_QUEUE *tq)
+ACE_Proactor::timer_queue (ACE_Proactor_Timer_Queue *tq)
{
// Cleanup old timer queue.
if (this->delete_timer_queue_)
@@ -800,7 +785,14 @@ ACE_Proactor::timer_queue (TIMER_QUEUE *tq)
}
// Set the proactor in the timer queue's functor
- this->timer_queue_->upcall_functor ().proactor (*this);
+ typedef ACE_Timer_Queue_Upcall_Base<ACE_Handler*,ACE_Proactor_Handle_Timeout_Upcall> TQ_Base;
+
+ TQ_Base * tqb = ACE_dynamic_cast(TQ_Base*, this->timer_queue_);
+
+ if (tqb != 0)
+ {
+ tqb->upcall_functor ().proactor (*this);
+ }
}
ACE_HANDLE
diff --git a/ACE/ace/Proactor.h b/ACE/ace/Proactor.h
index 704eef416ff..60c5a4d3d3b 100644
--- a/ACE/ace/Proactor.h
+++ b/ACE/ace/Proactor.h
@@ -43,6 +43,9 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Proactor_Impl;
class ACE_Proactor_Timer_Handler;
+/// Type def for the timer queue.
+typedef ACE_Abstract_Timer_Queue<ACE_Handler *> ACE_Proactor_Timer_Queue;
+
/**
* @class ACE_Proactor_Handle_Timeout_Upcall
*
@@ -51,15 +54,8 @@ class ACE_Proactor_Timer_Handler;
* This class implements the functor required by the Timer
* Queue to call <handle_timeout> on ACE_Handlers.
*/
-class ACE_Proactor_Handle_Timeout_Upcall
+class ACE_Export ACE_Proactor_Handle_Timeout_Upcall
{
-
- /// Type def for the timer queue.
- typedef ACE_Timer_Queue_T<ACE_Handler *,
- ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX>
- TIMER_QUEUE;
-
/// The main Proactor class has special permissions.
friend class ACE_Proactor;
@@ -68,12 +64,12 @@ public:
ACE_Proactor_Handle_Timeout_Upcall (void);
/// This method is called when a timer is registered.
- int registration (TIMER_QUEUE &timer_queue,
+ int registration (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
const void *arg);
/// This method is called before the timer expires.
- int preinvoke (TIMER_QUEUE &timer_queue,
+ int preinvoke (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
const void *arg,
int recurring_timer,
@@ -81,14 +77,14 @@ public:
const void *&upcall_act);
/// This method is called when the timer expires.
- int timeout (TIMER_QUEUE &timer_queue,
+ int timeout (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
const void *arg,
int recurring_timer,
const ACE_Time_Value &cur_time);
/// This method is called after the timer expires.
- int postinvoke (TIMER_QUEUE &timer_queue,
+ int postinvoke (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
const void *arg,
int recurring_timer,
@@ -96,20 +92,20 @@ public:
const void *upcall_act);
/// This method is called when a handler is canceled.
- int cancel_type (TIMER_QUEUE &timer_queue,
+ int cancel_type (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
int dont_call_handle_close,
int &requires_reference_counting);
/// This method is called when a timer is canceled.
- int cancel_timer (TIMER_QUEUE &timer_queue,
+ int cancel_timer (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
int dont_call_handle_close,
int requires_reference_counting);
/// This method is called when the timer queue is destroyed and the
/// timer is still contained in it.
- int deletion (TIMER_QUEUE &timer_queue,
+ int deletion (ACE_Proactor_Timer_Queue &timer_queue,
ACE_Handler *handler,
const void *arg);
@@ -135,10 +131,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>
@@ -171,12 +165,6 @@ class ACE_Export ACE_Proactor
friend class ACE_Proactor_Timer_Handler;
public:
- /// Public type.
- typedef ACE_Timer_Queue_T<ACE_Handler *,
- ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX>
- TIMER_QUEUE;
-
/**
* Constructor. If @a implementation is 0, the correct implementation
* object will be created. @a delete_implementation flag determines
@@ -185,7 +173,7 @@ public:
*/
ACE_Proactor (ACE_Proactor_Impl *implementation = 0,
bool delete_implementation = false,
- TIMER_QUEUE *tq = 0);
+ ACE_Proactor_Timer_Queue *tq = 0);
/// Destruction.
~ACE_Proactor (void);
@@ -383,10 +371,10 @@ public:
void number_of_threads (size_t threads);
/// Get timer queue.
- TIMER_QUEUE *timer_queue (void) const;
+ ACE_Proactor_Timer_Queue *timer_queue (void) const;
/// Set timer queue.
- void timer_queue (TIMER_QUEUE *timer_queue);
+ void timer_queue (ACE_Proactor_Timer_Queue *timer_queue);
/**
* Get the event handle.
@@ -614,7 +602,7 @@ protected:
ACE_Thread_Manager thr_mgr_;
/// Timer Queue.
- TIMER_QUEUE *timer_queue_;
+ ACE_Proactor_Timer_Queue *timer_queue_;
/// Flag on whether to delete the timer queue.
int delete_timer_queue_;
diff --git a/ACE/ace/Select_Reactor_T.cpp b/ACE/ace/Select_Reactor_T.cpp
index 30666cbf11f..aeac6d33cb1 100644
--- a/ACE/ace/Select_Reactor_T.cpp
+++ b/ACE/ace/Select_Reactor_T.cpp
@@ -728,7 +728,7 @@ ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::schedule_timer
return this->timer_queue_->schedule
(handler,
arg,
- timer_queue_->gettimeofday () + delay_time,
+ timer_queue_->gettimeofday_abstract () + delay_time,
interval);
errno = ESHUTDOWN;
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.h b/ACE/ace/Timer_Hash.h
index 2c41f30af6f..5a2bb32e421 100644
--- a/ACE/ace/Timer_Hash.h
+++ b/ACE/ace/Timer_Hash.h
@@ -16,6 +16,7 @@
#include /**/ "ace/pre.h"
#include "ace/Timer_Hash_T.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -29,7 +30,7 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// The following typedef are here for ease of use
typedef ACE_Timer_Hash_Upcall <ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX>
ACE_Hash_Upcall;
@@ -45,27 +46,27 @@ typedef ACE_Timer_Heap_T <ACE_Event_Handler *,
typedef ACE_Timer_Hash_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX,
ACE_Hash_Timer_List>
ACE_Timer_Hash;
typedef ACE_Timer_Hash_Iterator_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX,
ACE_Hash_Timer_List,
ACE_Default_Time_Policy>
ACE_Timer_Hash_Iterator;
typedef ACE_Timer_Hash_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX,
ACE_Hash_Timer_Heap>
ACE_Timer_Hash_Heap;
typedef ACE_Timer_Hash_Iterator_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX,
ACE_Hash_Timer_Heap>
ACE_Timer_Hash_Heap_Iterator;
diff --git a/ACE/ace/Timer_Hash_T.cpp b/ACE/ace/Timer_Hash_T.cpp
index ade274ea14a..334c93abbf6 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, TIME_POLICY>::item (v
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
+ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
@@ -271,8 +271,9 @@ template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME
ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::ACE_Timer_Hash_T (
size_t table_size,
FUNCTOR *upcall_functor,
- ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
- : ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> (upcall_functor, freelist),
+ ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist,
+ TIME_POLICY const & time_policy)
+ : Base_Timer_Queue (upcall_functor, freelist, time_policy),
size_ (0),
table_size_ (table_size),
table_functor_ (this),
@@ -295,8 +296,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::ACE_Timer_Hash_T
{
ACE_NEW (this->table_[i],
BUCKET (&this->table_functor_,
- this->free_list_));
- this->table_[i]->gettimeofday (ACE_OS::gettimeofday);
+ this->free_list_,
+ time_policy));
}
ACE_NEW (iterator_,
@@ -307,8 +308,9 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::ACE_Timer_Hash_T
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::ACE_Timer_Hash_T (
FUNCTOR *upcall_functor,
- ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
- : ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> (upcall_functor, freelist),
+ ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist,
+ TIME_POLICY const & time_policy)
+ : Base_Timer_Queue (upcall_functor, freelist, time_policy),
size_ (0),
table_size_ (ACE_DEFAULT_TIMER_HASH_TABLE_SIZE),
table_functor_ (this),
@@ -329,7 +331,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::ACE_Timer_Hash_T
{
ACE_NEW (this->table_[i],
BUCKET (&this->table_functor_,
- this->free_list_));
+ this->free_list_,
+ time_policy));
}
ACE_NEW (iterator_,
@@ -431,7 +434,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::reschedule (
// then here schedule <expired> for deletion. Don't call
// this->free_node() because that will invalidate <h>
// and that's what user have as timer_id.
- ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::free_node (expired);
+ Base_Timer_Queue::free_node (expired);
if (this->table_[this->earliest_position_]->is_empty ()
|| this->table_[h->pos_]->earliest_time ()
@@ -634,9 +637,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::cancel (const TY
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 ();
@@ -741,7 +742,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::get_first (void)
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> void
ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::free_node (ACE_Timer_Node_T<TYPE> *node)
{
- ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::free_node (node);
+ Base_Timer_Queue::free_node (node);
Hash_Token<TYPE> *h =
reinterpret_cast<Hash_Token<TYPE> *> (const_cast<void *> (node->get_act ()));
@@ -753,8 +754,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::dispatch_info_i
ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
{
int const result =
- ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::dispatch_info_i (cur_time,
- info);
+ Base_Timer_Queue::dispatch_info_i (cur_time, info);
if (result == 1)
{
@@ -772,7 +772,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::dispatch_info_i
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>::expire ()
{
- return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire();
+ return Base_Timer_Queue::expire();
}
// Specialized expire for Timer Hash
diff --git a/ACE/ace/Timer_Hash_T.h b/ACE/ace/Timer_Hash_T.h
index b644c551dfc..e2413a7f547 100644
--- a/ACE/ace/Timer_Hash_T.h
+++ b/ACE/ace/Timer_Hash_T.h
@@ -116,7 +116,7 @@ private:
* in the order of timeout values.
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY = ACE_Default_Time_Policy>
-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.
@@ -143,7 +143,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_;
};
/**
@@ -170,7 +170,7 @@ public:
friend class ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>;
/// Type inherited from
- typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> INHERITED;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Timer_Queue;
// = Initialization and termination methods.
/**
@@ -181,7 +181,8 @@ public:
*/
ACE_Timer_Hash_T (size_t table_size,
FUNCTOR *upcall_functor = 0,
- ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist = 0);
+ ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist = 0,
+ TIME_POLICY const & time_policy = TIME_POLICY());
/**
* Default constructor. @a upcall_functor is the instance of the
@@ -190,7 +191,9 @@ public:
* timer nodes. If 0, then a default freelist will be created. The default
* size will be ACE_DEFAULT_TIMERS and there will be no preallocation.
*/
- ACE_Timer_Hash_T (FUNCTOR *upcall_functor = 0, ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist = 0);
+ ACE_Timer_Hash_T (FUNCTOR *upcall_functor = 0,
+ ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist = 0,
+ TIME_POLICY const & time_policy = TIME_POLICY());
/// Destructor
virtual ~ACE_Timer_Hash_T (void);
@@ -252,7 +255,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.h b/ACE/ace/Timer_Heap.h
index 7949fbcfc90..6ac385c4f11 100644
--- a/ACE/ace/Timer_Heap.h
+++ b/ACE/ace/Timer_Heap.h
@@ -15,6 +15,7 @@
#include /**/ "ace/pre.h"
#include "ace/Timer_Heap_T.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -26,16 +27,21 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// compatibility.
typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX>
ACE_Timer_Heap;
typedef ACE_Timer_Heap_Iterator_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
- ACE_SYNCH_RECURSIVE_MUTEX,
- ACE_Default_Time_Policy>
+ ACE_Event_Handler_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>
ACE_Timer_Heap_Iterator;
+typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX,
+ ACE_FPointer_Time_Policy>
+ ACE_Timer_Heap_Variable_Time_Source;
+
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
diff --git a/ACE/ace/Timer_Heap_T.cpp b/ACE/ace/Timer_Heap_T.cpp
index 607e8e9348e..37ea1ed02df 100644
--- a/ACE/ace/Timer_Heap_T.cpp
+++ b/ACE/ace/Timer_Heap_T.cpp
@@ -102,9 +102,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Heap_T (
FUNCTOR *upcall_functor,
ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist,
TIME_POLICY const & time_policy)
- : ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK> (upcall_functor,
- freelist,
- time_policy),
+ : Base_Time_Policy (upcall_functor,
+ freelist,
+ time_policy),
max_size_ (size),
cur_size_ (0),
cur_limbo_ (0),
@@ -170,9 +170,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Heap_T (
FUNCTOR *upcall_functor,
ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist,
TIME_POLICY const & time_policy)
- : ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK> (upcall_functor,
- freelist,
- time_policy),
+ : Base_Time_Policy (upcall_functor,
+ freelist,
+ time_policy),
max_size_ (ACE_DEFAULT_TIMERS),
cur_size_ (0),
cur_limbo_ (0),
@@ -323,7 +323,7 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::is_empty (void) const
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
+ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
diff --git a/ACE/ace/Timer_Heap_T.h b/ACE/ace/Timer_Heap_T.h
index 35766f6acaa..0cba7681719 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, typename TIME_POLICY = ACE_Default_Time_Policy>
-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:
typedef ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Heap;
@@ -90,7 +90,7 @@ public:
typedef ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> HEAP_ITERATOR;
friend class ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>;
- typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> INHERITED;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Time_Policy;
// = Initialization and termination methods.
/**
@@ -166,7 +166,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.h b/ACE/ace/Timer_List.h
index 3d900d5582e..e6d0d3129cc 100644
--- a/ACE/ace/Timer_List.h
+++ b/ACE/ace/Timer_List.h
@@ -16,6 +16,7 @@
#include /**/ "ace/pre.h"
#include "ace/Timer_List_T.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -27,12 +28,12 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// compatibility.
typedef ACE_Timer_List_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX>
ACE_Timer_List;
typedef ACE_Timer_List_Iterator_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX,
ACE_Default_Time_Policy>
ACE_Timer_List_Iterator;
diff --git a/ACE/ace/Timer_List_T.cpp b/ACE/ace/Timer_List_T.cpp
index bf95530fa35..9059e10018e 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, TIME_POLICY>::item (void)
// Return our instance of the iterator
-template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
@@ -80,8 +80,10 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter (void)
// Create an empty list.
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_List_T (FUNCTOR* uf, FreeList* fl)
- : Base(uf, fl)
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_List_T (FUNCTOR* uf,
+ FreeList* fl,
+ TIME_POLICY const & time_policy)
+ : Base_Timer_Queue (uf, fl, time_policy)
, head_ (new ACE_Timer_Node_T<TYPE>)
, id_counter_ (0)
{
diff --git a/ACE/ace/Timer_List_T.h b/ACE/ace/Timer_List_T.h
index 09439c37994..8b387c04725 100644
--- a/ACE/ace/Timer_List_T.h
+++ b/ACE/ace/Timer_List_T.h
@@ -32,9 +32,9 @@ class ACE_Timer_List_T;
* This is a generic iterator that can be used to visit every
* node of a timer queue.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
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, TIME_POLICY> List;
@@ -93,7 +93,7 @@ public:
typedef ACE_Timer_Node_T<TYPE> Node;
/// Type inherited from
- typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Timer_Queue;
typedef ACE_Free_List<Node> FreeList;
// = Initialization and termination methods.
@@ -103,7 +103,8 @@ public:
* default FUNCTOR will be created. @a freelist is the freelist of
* timer nodes. If 0, then a default freelist will be created.
*/
- ACE_Timer_List_T (FUNCTOR* upcall_functor = 0, FreeList* freelist = 0);
+ ACE_Timer_List_T (FUNCTOR* upcall_functor = 0, FreeList* freelist = 0,
+ TIME_POLICY const & time_policy = TIME_POLICY());
/// Destructor
virtual ~ACE_Timer_List_T (void);
@@ -147,7 +148,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_Adapters.cpp b/ACE/ace/Timer_Queue_Adapters.cpp
index 0c4fc51b573..634276961a8 100644
--- a/ACE/ace/Timer_Queue_Adapters.cpp
+++ b/ACE/ace/Timer_Queue_Adapters.cpp
@@ -263,7 +263,7 @@ ACE_Thread_Timer_Queue_Adapter<TQ>::svc (void)
{
// Compute the remaining time, being careful not to sleep
// for "negative" amounts of time.
- ACE_Time_Value const tv_curr = this->timer_queue_->gettimeofday ();
+ ACE_Time_Value const tv_curr = this->timer_queue_->gettimeofday_abstract ();
ACE_Time_Value const tv_earl = this->timer_queue_->earliest_time ();
if (tv_earl > tv_curr)
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 18d1d004695..d4501dc1521 100644
--- a/ACE/ace/Timer_Queue_T.cpp
+++ b/ACE/ace/Timer_Queue_T.cpp
@@ -17,9 +17,9 @@
#include "ace/Timer_Queue_T.h"
#include "ace/Guard_T.h"
#include "ace/Log_Msg.h"
-#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,42 +34,37 @@ 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
+template <class TYPE, class FUNCTOR> ACE_INLINE
+ACE_Timer_Queue_Upcall_Base<TYPE, FUNCTOR>::ACE_Timer_Queue_Upcall_Base (FUNCTOR * upcall_functor)
+ : ACE_Abstract_Timer_Queue<TYPE>()
+ , ACE_Copy_Disabled()
+ , upcall_functor_(upcall_functor)
+ , delete_upcall_functor_ (upcall_functor == 0)
{
-#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 */
-}
+ ACE_TRACE ("ACE_Timer_Queue_Upcall_Base::ACE_Timer_Queue_Upcall_Base");
-template <class TYPE>
-ACE_Timer_Node_T<TYPE>::ACE_Timer_Node_T (void)
-{
- ACE_TRACE ("ACE_Timer_Node_T::ACE_Timer_Node_T");
-}
+ if (upcall_functor != 0)
+ {
+ return;
+ }
-template <class TYPE>
-ACE_Timer_Node_T<TYPE>::~ACE_Timer_Node_T (void)
-{
- ACE_TRACE ("ACE_Timer_Node_T::~ACE_Timer_Node_T");
+ ACE_NEW (upcall_functor_, FUNCTOR);
}
-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> ACE_INLINE
+ACE_Timer_Queue_Upcall_Base<TYPE, FUNCTOR>::~ACE_Timer_Queue_Upcall_Base ()
{
+ ACE_TRACE ("ACE_Timer_Queue_Upcall_Base::~ACE_Timer_Queue_Upcall_Base");
+ if (this->delete_upcall_functor_)
+ {
+ delete this->upcall_functor_;
+ }
}
-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, typename TIME_POLICY> ACE_Time_Value
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::gettimeofday_abstract()
{
+ return this->gettimeofday();
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Time_Value *
@@ -152,6 +147,14 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::calculate_timeout (ACE_
return the_timeout;
}
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Time_Value
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::current_time()
+{
+ ACE_Time_Value tv = this->gettimeofday();
+ tv += this->timer_skew();
+ return tv;
+}
+
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dump (void) const
{
@@ -168,8 +171,8 @@ template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Queue_T (FUNCTOR *upcall_functor,
ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist,
TIME_POLICY const & time_policy)
- : time_policy_ (time_policy),
- delete_upcall_functor_ (upcall_functor == 0),
+ : ACE_Timer_Queue_Upcall_Base<TYPE,FUNCTOR>(upcall_functor),
+ time_policy_ (time_policy),
delete_free_list_ (freelist == 0),
timer_skew_ (0, ACE_TIMER_SKEW)
{
@@ -180,12 +183,6 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Queue_T (FUNC
(ACE_Locked_Free_List<ACE_Timer_Node_T<TYPE>,ACE_Null_Mutex>));
else
free_list_ = freelist;
-
- if (!upcall_functor)
- ACE_NEW (upcall_functor_,
- FUNCTOR);
- else
- upcall_functor_ = upcall_functor;
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
@@ -193,10 +190,7 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Queue_T (voi
{
ACE_TRACE ("ACE_Timer_Queue_T::~ACE_Timer_Queue_T");
- // Cleanup the functor and free_list on the way out
- if (this->delete_upcall_functor_)
- delete this->upcall_functor_;
-
+ // Cleanup the free_list on the way out
if (this->delete_free_list_)
delete this->free_list_;
}
@@ -285,6 +279,46 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::expire (const ACE_Time_
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::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, typename TIME_POLICY> int
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dispatch_info_i (const ACE_Time_Value &cur_time,
ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
{
@@ -335,148 +369,6 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::return_node (ACE_Timer_
this->free_node (node);
}
-
-template <class ACE_LOCK>
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::ACE_Event_Handler_Handle_Timeout_Upcall (void)
-{
-}
-
-template <class ACE_LOCK>
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::~ACE_Event_Handler_Handle_Timeout_Upcall (void)
-{
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::registration (TIMER_QUEUE &,
- ACE_Event_Handler *event_handler,
- const void *)
-{
- event_handler->add_reference ();
- return 0;
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::preinvoke (TIMER_QUEUE & /* timer_queue */,
- ACE_Event_Handler *event_handler,
- const void * /* timer_act */,
- int /* recurring_timer */,
- const ACE_Time_Value & /* cur_time */,
- const void *&upcall_act)
-{
- bool const requires_reference_counting =
- event_handler->reference_counting_policy ().value () ==
- ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
-
- if (requires_reference_counting)
- {
- event_handler->add_reference ();
-
- upcall_act = &this->requires_reference_counting_;
- }
-
- return 0;
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::postinvoke (TIMER_QUEUE & /* timer_queue */,
- ACE_Event_Handler *event_handler,
- const void * /* timer_act */,
- int /* recurring_timer */,
- const ACE_Time_Value & /* cur_time */,
- const void *upcall_act)
-{
- if (upcall_act == &this->requires_reference_counting_)
- {
- event_handler->remove_reference ();
- }
-
- return 0;
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::timeout (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *event_handler,
- const void *act,
- int recurring_timer,
- const ACE_Time_Value &cur_time)
-{
- int requires_reference_counting = 0;
-
- if (!recurring_timer)
- {
- requires_reference_counting =
- event_handler->reference_counting_policy ().value () ==
- ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
- }
-
- // Upcall to the <handler>s handle_timeout method.
- if (event_handler->handle_timeout (cur_time, act) == -1)
- {
- if (event_handler->reactor_timer_interface ())
- event_handler->reactor_timer_interface ()->cancel_timer (event_handler, 0);
- else
- timer_queue.cancel (event_handler, 0); // 0 means "call handle_close()".
- }
-
- if (!recurring_timer &&
- requires_reference_counting)
- {
- event_handler->remove_reference ();
- }
-
- return 0;
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::cancel_type (TIMER_QUEUE &,
- ACE_Event_Handler *event_handler,
- int dont_call,
- int &requires_reference_counting)
-{
- requires_reference_counting =
- event_handler->reference_counting_policy ().value () ==
- ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
-
- // Upcall to the <handler>s handle_close method
- if (dont_call == 0)
- event_handler->handle_close (ACE_INVALID_HANDLE,
- ACE_Event_Handler::TIMER_MASK);
-
- return 0;
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::cancel_timer (TIMER_QUEUE &,
- ACE_Event_Handler *event_handler,
- int,
- int requires_reference_counting)
-{
- if (requires_reference_counting)
- event_handler->remove_reference ();
-
- return 0;
-}
-
-template <class ACE_LOCK> int
-ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::deletion (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *event_handler,
- const void *)
-{
- int requires_reference_counting = 0;
-
- this->cancel_type (timer_queue,
- event_handler,
- 0,
- requires_reference_counting);
-
- this->cancel_timer (timer_queue,
- event_handler,
- 0,
- requires_reference_counting);
-
- return 0;
-}
-
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_TIMER_QUEUE_T_CPP */
diff --git a/ACE/ace/Timer_Queue_T.h b/ACE/ace/Timer_Queue_T.h
index 2e02021139e..489881fec79 100644
--- a/ACE/ace/Timer_Queue_T.h
+++ b/ACE/ace/Timer_Queue_T.h
@@ -16,184 +16,48 @@
#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/Event_Handler.h"
+#include "ace/Free_List.h"
#include "ace/Time_Value.h"
+#include "ace/Abstract_Timer_Queue.h"
+#include "ace/Timer_Queue_Iterator.h"
#include "ace/Time_Policy.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
+ * @class ACE_Timer_Queue_Upcall_Base
*
- * @brief Maintains the state associated with a Timer entry.
+ * Common base class for all timer queues with the same time source
+ * policy. This is really motivated by a single use-case in the code,
+ * namely the ACE_Proactor needs to set a backpointer in the upcall
+ * functor.
*/
-template <class TYPE>
-class ACE_Timer_Node_T
+template<typename TYPE, typename FUNCTOR>
+class ACE_Timer_Queue_Upcall_Base
+ : public ACE_Abstract_Timer_Queue<TYPE>
+ , private ACE_Copy_Disabled
{
public:
- /// Default constructor
- ACE_Timer_Node_T (void);
+ // Constructor
+ explicit ACE_Timer_Queue_Upcall_Base(FUNCTOR * upcall_functor = 0);
/// 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);
+ virtual ~ACE_Timer_Queue_Upcall_Base (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;
+ /// Accessor to the upcall functor
+ FUNCTOR & upcall_functor (void);
- /// Returns true when there are no more nodes in the sequence
- virtual bool isdone (void) const = 0;
+protected:
+ /// Upcall functor
+ FUNCTOR *upcall_functor_;
- /// Returns the node at the current position in the sequence
- virtual ACE_Timer_Node_T<TYPE> *item (void) = 0;
+ /// To delete or not to delete is the question?
+ bool const delete_upcall_functor_;
};
/**
@@ -207,12 +71,9 @@ public:
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
class ACE_Timer_Queue_T
- : private ACE_Copy_Disabled
+ : public ACE_Timer_Queue_Upcall_Base<TYPE,FUNCTOR>
{
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
@@ -228,72 +89,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.
@@ -304,73 +117,33 @@ 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() virtual function
*/
- ACE_Time_Value gettimeofday (void);
+ virtual ACE_Time_Value gettimeofday_abstract (void);
+ //@}
+
+ /// Implement a non-abstract version of gettimeofday(), through this
+ /// member function the internals of the class can make calls to
+ /// ACE_OS::gettimeofday() with zero overhead.
+ ACE_Time_Value gettimeofday();
/// Allows applications to control how the timer queue gets the time
/// of day.
void set_time_policy(TIME_POLICY const & time_policy);
- /// 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);
-
+ //@{
/**
- * 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);
@@ -381,21 +154,9 @@ public:
/// Synchronization variable used by the queue
ACE_LOCK &mutex (void);
- /// Accessor to the upcall functor
- FUNCTOR &upcall_functor (void);
-
- /// Returns a pointer to this ACE_Timer_Queue's iterator.
- virtual ITERATOR &iter (void) = 0;
-
- /// 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;
-
/// Method used to return a timer node to the queue's ownership
/// after it is returned by a method like <remove_first>.
virtual void return_node (ACE_Timer_Node_T<TYPE> *);
@@ -445,12 +206,6 @@ protected:
/// The policy to return the current time of day
TIME_POLICY time_policy_;
- /// Upcall functor
- FUNCTOR *upcall_functor_;
-
- /// To delete or not to delete is the question?
- bool const delete_upcall_functor_;
-
/// Flag to delete only if the class created the <free_list_>
bool const delete_free_list_;
@@ -463,87 +218,6 @@ private:
ACE_Time_Value timer_skew_;
};
-/**
- * @class ACE_Event_Handler_Handle_Timeout_Upcall
- *
- * @brief Functor for Timer_Queues.
- *
- * This class implements the functor required by the Timer
- * Queue to call <handle_timeout> on ACE_Event_Handlers.
- */
-template <class ACE_LOCK>
-class ACE_Event_Handler_Handle_Timeout_Upcall
-{
-public:
- typedef ACE_Timer_Queue_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>,
- ACE_LOCK>
- TIMER_QUEUE;
-
- // = Initialization and termination methods.
- /// Constructor.
- ACE_Event_Handler_Handle_Timeout_Upcall (void);
-
- /// Destructor.
- ~ACE_Event_Handler_Handle_Timeout_Upcall (void);
-
- /// This method is called when a timer is registered.
- int registration (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- const void *arg);
-
- /// This method is called before the timer expires.
- int preinvoke (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- const void *arg,
- int recurring_timer,
- const ACE_Time_Value &cur_time,
- const void *&upcall_act);
-
- /// This method is called when the timer expires.
- int timeout (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- const void *arg,
- int recurring_timer,
- const ACE_Time_Value &cur_time);
-
- /// This method is called after the timer expires.
- int postinvoke (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- const void *arg,
- int recurring_timer,
- const ACE_Time_Value &cur_time,
- const void *upcall_act);
-
- /// This method is called when a handler is cancelled
- int cancel_type (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- int dont_call,
- int &requires_reference_counting);
-
- /// This method is called when a timer is cancelled
- int cancel_timer (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- int dont_call,
- int requires_reference_counting);
-
- /// This method is called when the timer queue is destroyed and
- /// the timer is still contained in it
- int deletion (TIMER_QUEUE &timer_queue,
- ACE_Event_Handler *handler,
- const void *arg);
-
-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
#if defined (__ACE_INLINE__)
diff --git a/ACE/ace/Timer_Queue_T.inl b/ACE/ace/Timer_Queue_T.inl
index ce957fd29ce..eb3abe53f29 100644
--- a/ACE/ace/Timer_Queue_T.inl
+++ b/ACE/ace/Timer_Queue_T.inl
@@ -4,132 +4,10 @@
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)
+template <class TYPE, class FUNCTOR> ACE_INLINE FUNCTOR &
+ACE_Timer_Queue_Upcall_Base<TYPE, FUNCTOR>::upcall_functor (void)
{
- 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;
+ return *this->upcall_functor_;
}
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
@@ -213,10 +91,4 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::set_time_policy (TIME_P
this->time_policy_ = rhs;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE FUNCTOR &
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::upcall_functor (void)
-{
- return *this->upcall_functor_;
-}
-
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Queuefwd.h b/ACE/ace/Timer_Queuefwd.h
index 076bd761c2c..af1b844d84d 100644
--- a/ACE/ace/Timer_Queuefwd.h
+++ b/ACE/ace/Timer_Queuefwd.h
@@ -17,21 +17,13 @@
#include /**/ "ace/pre.h"
-#include "ace/Synch_Traits.h"
-#include "ace/Time_Policy.h"
+#include "ace/config-all.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-template <class TYPE, class FUNCTOR, class ACE_LOCK, typename ACE_TIME_POLICY> 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_Default_Time_Policy>
- 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.h b/ACE/ace/Timer_Wheel.h
index 0045e58dc6a..02ca7b020ba 100644
--- a/ACE/ace/Timer_Wheel.h
+++ b/ACE/ace/Timer_Wheel.h
@@ -16,6 +16,7 @@
#include /**/ "ace/pre.h"
#include "ace/Timer_Wheel_T.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -27,12 +28,12 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// compatibility.
typedef ACE_Timer_Wheel_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX>
ACE_Timer_Wheel;
typedef ACE_Timer_Wheel_Iterator_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX,
ACE_Default_Time_Policy>
ACE_Timer_Wheel_Iterator;
diff --git a/ACE/ace/Timer_Wheel_T.cpp b/ACE/ace/Timer_Wheel_T.cpp
index 8ef6e654664..f6e3fd1acaf 100644
--- a/ACE/ace/Timer_Wheel_T.cpp
+++ b/ACE/ace/Timer_Wheel_T.cpp
@@ -47,7 +47,7 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Wheel_T
, FreeList* freelist
, TIME_POLICY const & time_policy
)
- : Base (upcall_functor, freelist, time_policy)
+ : Base_Timer_Queue (upcall_functor, freelist, time_policy)
, spokes_(0)
, spoke_count_(0) // calculated in open_i
, spoke_bits_(0)
@@ -80,7 +80,7 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Wheel_T
FUNCTOR* upcall_functor,
FreeList* freelist,
TIME_POLICY const & time_policy)
-: Base (upcall_functor, freelist, time_policy)
+: Base_Timer_Queue (upcall_functor, freelist, time_policy)
, spokes_ (0)
, spoke_count_ (0) // calculated in open_i
, spoke_bits_ (0)
@@ -783,7 +783,7 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first_i (void) cons
* @return The iterator
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>&
+ACE_Timer_Queue_Iterator_T<TYPE> &
ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
diff --git a/ACE/ace/Timer_Wheel_T.h b/ACE/ace/Timer_Wheel_T.h
index d879cacb9eb..332d8200a4c 100644
--- a/ACE/ace/Timer_Wheel_T.h
+++ b/ACE/ace/Timer_Wheel_T.h
@@ -36,9 +36,9 @@ class ACE_Timer_Wheel_T;
* node of a timer queue. Be aware that it doesn't traverse
* in the order of timeout values.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
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, TIME_POLICY> Wheel;
@@ -100,7 +100,7 @@ public:
friend class ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>;
typedef ACE_Timer_Node_T<TYPE> Node;
/// Type inherited from
- typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Timer_Queue;
typedef ACE_Free_List<Node> FreeList;
/// Default constructor
@@ -154,7 +154,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 06c49df8fa3..5c47dcce422 100644
--- a/ACE/ace/ace.mpc
+++ b/ACE/ace/ace.mpc
@@ -63,6 +63,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Dynamic_Message_Strategy.cpp
Event.cpp
Event_Handler.cpp
+ Event_Handler_Handle_Timeout_Upcall.cpp
FIFO.cpp
FIFO_Recv.cpp
FIFO_Recv_Msg.cpp
@@ -283,6 +284,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
@@ -359,6 +361,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/examples/APG/Timers/TimerDispatcher.cpp b/ACE/examples/APG/Timers/TimerDispatcher.cpp
index 818d762b738..8f8043fbeef 100644
--- a/ACE/examples/APG/Timers/TimerDispatcher.cpp
+++ b/ACE/examples/APG/Timers/TimerDispatcher.cpp
@@ -8,7 +8,7 @@ void Timer_Dispatcher::wait_for_event (void)
while (1)
{
- ACE_Time_Value max_tv = timer_queue_->gettimeofday ();
+ ACE_Time_Value max_tv = timer_queue_->gettimeofday_abstract ();
ACE_Time_Value *this_timeout =
this->timer_queue_->calculate_timeout (&max_tv);
@@ -19,7 +19,7 @@ void Timer_Dispatcher::wait_for_event (void)
{
// Convert to absolute time.
ACE_Time_Value next_timeout =
- timer_queue_->gettimeofday ();
+ timer_queue_->gettimeofday_abstract ();
next_timeout += *this_timeout;
if (this->timer_.wait (&next_timeout) == -1 )
this->timer_queue_->expire ();
diff --git a/ACE/examples/APG/Timers/Timers.cpp b/ACE/examples/APG/Timers/Timers.cpp
index 761f03a650c..fda76c6afcd 100644
--- a/ACE/examples/APG/Timers/Timers.cpp
+++ b/ACE/examples/APG/Timers/Timers.cpp
@@ -40,7 +40,7 @@ int ACE_TMAIN (int, ACE_TCHAR *[])
Timer::instance ()->schedule
(&cb[i],
&args[i],
- timer_queue->gettimeofday () + (ACE_Time_Value)5,
+ timer_queue->gettimeofday_abstract () + ACE_Time_Value(5),
timeout);
// Set the timerID state variable of the handler.
diff --git a/ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h b/ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h
index ccd5782b487..4838905085c 100644
--- a/ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h
+++ b/ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h
@@ -37,11 +37,12 @@
#include "ace/Task.h"
#include "ace/Timer_Heap_T.h"
#include "ace/Timer_Queue_Adapters.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
#include "BPR_Drivers.h"
// These typedefs ensure that we use the minimal amount of locking
// necessary.
-typedef ACE_Event_Handler_Handle_Timeout_Upcall<ACE_Null_Mutex>
+typedef ACE_Event_Handler_Handle_Timeout_Upcall
Upcall;
typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
Upcall,
diff --git a/ACE/examples/C++NPv2/Logging_Event_Handler_Ex.cpp b/ACE/examples/C++NPv2/Logging_Event_Handler_Ex.cpp
index 858e615e9d9..f27900d955f 100644
--- a/ACE/examples/C++NPv2/Logging_Event_Handler_Ex.cpp
+++ b/ACE/examples/C++NPv2/Logging_Event_Handler_Ex.cpp
@@ -9,7 +9,7 @@
int Logging_Event_Handler_Ex::handle_input (ACE_HANDLE h) {
time_of_last_log_record_ =
- reactor ()->timer_queue ()->gettimeofday ();
+ reactor ()->timer_queue ()->gettimeofday_abstract ();
return PARENT::handle_input (h);
}
diff --git a/ACE/examples/Reactor/Misc/test_timer_queue.cpp b/ACE/examples/Reactor/Misc/test_timer_queue.cpp
index 64138e13daf..72e514d48bf 100644
--- a/ACE/examples/Reactor/Misc/test_timer_queue.cpp
+++ b/ACE/examples/Reactor/Misc/test_timer_queue.cpp
@@ -7,6 +7,7 @@
#include "ace/Log_Msg.h"
#include "ace/Recursive_Thread_Mutex.h"
#include "ace/Null_Mutex.h"
+#include "ace/Event_Handler.h"
ACE_RCSID(Misc, test_timer_queue, "$Id$")
diff --git a/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h b/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h
index 573df6121f8..3298cf7d499 100644
--- a/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h
+++ b/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h
@@ -34,11 +34,12 @@
#include "ace/Timer_Queue_Adapters.h"
#include "ace/svc_export.h"
#include "ace/Condition_Recursive_Thread_Mutex.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
#include "Driver.h"
// These typedefs ensure that we use the minimal amount of locking
// necessary.
-typedef ACE_Event_Handler_Handle_Timeout_Upcall<ACE_Null_Mutex>
+typedef ACE_Event_Handler_Handle_Timeout_Upcall
Upcall;
typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
Upcall,
diff --git a/ACE/tests/Network_Adapters_Test.cpp b/ACE/tests/Network_Adapters_Test.cpp
index d58f93b9abe..a8e46456bb5 100644
--- a/ACE/tests/Network_Adapters_Test.cpp
+++ b/ACE/tests/Network_Adapters_Test.cpp
@@ -33,6 +33,8 @@
#include "ace/Timer_Queue.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_signal.h"
+#include "ace/Timer_Heap.h"
+#include "ace/Auto_Ptr.h"
#include "Network_Adapters_Test.h"
@@ -1044,8 +1046,27 @@ run_main (int argc, ACE_TCHAR *argv[])
ACE_NEW_RETURN (main_reactor, ACE_Reactor, -1);
(void) ACE_High_Res_Timer::global_scale_factor ();
- main_reactor->timer_queue ()->gettimeofday
- (&ACE_High_Res_Timer::gettimeofday_hr);
+
+ // Change the source of time in the reactor to the high-resolution
+ // timer. Why does this test require such precision for a 1 second
+ // timer is beyond me ... I think it is a cut&paste error.
+ //
+ // The use of auto_ptr<> is optional, ACE uses dangerous memory
+ // management idioms everywhere, I thought I could demonstrate how
+ // to do it right in at least one test. Notice the lack of
+ // ACE_NEW_RETURN, that monstrosity has no business in proper C++
+ // code ...
+ auto_ptr<ACE_Timer_Heap_Variable_Time_Source> tq(
+ new ACE_Timer_Heap_Variable_Time_Source);
+ // ... notice how the policy is in the derived timer queue type.
+ // The abstract timer queue does not have a time policy ...
+ tq->set_time_policy(&ACE_High_Res_Timer::gettimeofday_hr);
+ // ... and then the timer queue is replaced. Strangely, the reactor
+ // does *not* copy the timers, it just deletes the existing timer
+ // queue ....
+ main_reactor->timer_queue(tq.get());
+ // ... the reactor has assumed ownership, release the auto_ptr<> ...
+ tq.release();
/**
* Stop_Handler's is supposed to stop the activity of all
diff --git a/ACE/tests/Proactor_Timer_Test.cpp b/ACE/tests/Proactor_Timer_Test.cpp
index 7d81bcb5ef1..031f8639236 100644
--- a/ACE/tests/Proactor_Timer_Test.cpp
+++ b/ACE/tests/Proactor_Timer_Test.cpp
@@ -32,10 +32,11 @@ ACE_RCSID (tests,
// supporting POSIX aio calls.
#include "ace/OS_NS_unistd.h"
-#include "ace/Timer_Queue.h"
#include "ace/Proactor.h"
#include "ace/High_Res_Timer.h"
#include "ace/Asynch_IO.h"
+#include "ace/Timer_Heap.h"
+#include "ace/Auto_Ptr.h"
static int done = 0;
static size_t counter = 0;
@@ -304,8 +305,32 @@ run_main (int argc, ACE_TCHAR *[])
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("Running with high-res timer queue\n")));
ACE_Proactor *r = ACE_Proactor::instance ();
+
(void) ACE_High_Res_Timer::global_scale_factor ();
- r->timer_queue ()->gettimeofday (&ACE_High_Res_Timer::gettimeofday_hr);
+
+ // Change the source of time in the Proactor to the
+ // high-resolution timer. Why does this test require such
+ // precision for a 1 second timer is beyond me ... I think it
+ // is a cut&paste error.
+ //
+ // The use of auto_ptr<> is optional, ACE uses dangerous memory
+ // management idioms everywhere, I thought I could demonstrate how
+ // to do it right in at least one test. Notice the lack of
+ // ACE_NEW_RETURN, that monstrosity has no business in proper C++
+ // code ...
+ typedef ACE_Timer_Heap_T<ACE_Handler*,ACE_Proactor_Handle_Timeout_Upcall,ACE_SYNCH_RECURSIVE_MUTEX,ACE_FPointer_Time_Policy> Timer_Queue;
+
+ auto_ptr<Timer_Queue> tq(new Timer_Queue);
+ // ... notice how the policy is in the derived timer queue type.
+ // The abstract timer queue does not have a time policy ...
+ tq->set_time_policy(&ACE_High_Res_Timer::gettimeofday_hr);
+ // ... and then the timer queue is replaced. Strangely, the
+ // Proactor does *not* copy the timers, it just deletes the
+ // existing timer queue ....
+ r->timer_queue(tq.get());
+ // ... the Proactor has assumed ownership, release the
+ // auto_ptr<> ...
+ tq.release();
}
// Register all different handlers, i.e., one per timer.
diff --git a/ACE/tests/Reactor_Timer_Test.cpp b/ACE/tests/Reactor_Timer_Test.cpp
index cc34c5b1b70..952db15cccf 100644
--- a/ACE/tests/Reactor_Timer_Test.cpp
+++ b/ACE/tests/Reactor_Timer_Test.cpp
@@ -27,6 +27,8 @@
#include "ace/Trace.h"
#include "ace/Recursive_Thread_Mutex.h"
#include "ace/Log_Msg.h"
+#include "ace/Timer_Heap.h"
+#include "ace/Auto_Ptr.h"
ACE_RCSID(tests, Reactor_Timer_Test, "$Id$")
@@ -250,8 +252,31 @@ run_main (int argc, ACE_TCHAR *[])
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("Running with high-res timer queue\n")));
ACE_Reactor *r = ACE_Reactor::instance ();
+
(void) ACE_High_Res_Timer::global_scale_factor ();
- r->timer_queue ()->gettimeofday (&ACE_High_Res_Timer::gettimeofday_hr);
+
+ // Change the source of time in the Reactor to the
+ // high-resolution timer. Why does this test require such
+ // precision for a 1 second timer is beyond me ... I think it
+ // is a cut&paste error.
+ //
+ // The use of auto_ptr<> is optional, ACE uses dangerous memory
+ // management idioms everywhere, I thought I could demonstrate how
+ // to do it right in at least one test. Notice the lack of
+ // ACE_NEW_RETURN, that monstrosity has no business in proper C++
+ // code ...
+ auto_ptr<ACE_Timer_Heap_Variable_Time_Source> tq(
+ new ACE_Timer_Heap_Variable_Time_Source);
+ // ... notice how the policy is in the derived timer queue type.
+ // The abstract timer queue does not have a time policy ...
+ tq->set_time_policy(&ACE_High_Res_Timer::gettimeofday_hr);
+ // ... and then the timer queue is replaced. Strangely, the
+ // Reactor does *not* copy the timers, it just deletes the
+ // existing timer queue ....
+ r->timer_queue(tq.get());
+ // ... the Reactor has assumed ownership, release the
+ // auto_ptr<> ...
+ tq.release();
}
// Register all different handlers, i.e., one per timer.
diff --git a/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp b/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
index d0dcafff858..daabfe2aec5 100644
--- a/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
+++ b/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
@@ -40,7 +40,7 @@ namespace
inline void WAIT_FOR_NEXT_EVENT (ACE_Timer_Queue &timer_queue)
{
ACE_Time_Value const earliest_time = timer_queue.earliest_time ();
- ACE_Time_Value const time_of_day = timer_queue.gettimeofday ();
+ ACE_Time_Value const time_of_day = timer_queue.gettimeofday_abstract ();
if (earliest_time > time_of_day)
{
ACE_OS::sleep (earliest_time - time_of_day);
@@ -155,7 +155,7 @@ cancellation (ACE_Timer_Queue &timer_queue,
first_timer_id =
timer_queue.schedule (handler,
one_second_timeout,
- ACE_Time_Value (1) + timer_queue.gettimeofday (),
+ ACE_Time_Value (1) + timer_queue.gettimeofday_abstract (),
ACE_Time_Value (1));
ACE_ASSERT (first_timer_id != -1);
}
@@ -164,7 +164,7 @@ cancellation (ACE_Timer_Queue &timer_queue,
first_timer_id =
timer_queue.schedule (handler,
one_second_timeout,
- ACE_Time_Value (1) + timer_queue.gettimeofday ());
+ ACE_Time_Value (1) + timer_queue.gettimeofday_abstract ());
ACE_ASSERT (first_timer_id != -1);
}
@@ -173,7 +173,7 @@ cancellation (ACE_Timer_Queue &timer_queue,
second_timer_id =
timer_queue.schedule (handler,
two_second_timeout,
- ACE_Time_Value (2) + timer_queue.gettimeofday (),
+ ACE_Time_Value (2) + timer_queue.gettimeofday_abstract (),
ACE_Time_Value (2));
ACE_ASSERT (second_timer_id != -1);
}
@@ -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
@@ -315,14 +285,14 @@ expire (ACE_Timer_Queue &timer_queue,
long timer_id =
timer_queue.schedule (handler,
one_second_timeout,
- ACE_Time_Value (1) + timer_queue.gettimeofday (),
+ ACE_Time_Value (1) + timer_queue.gettimeofday_abstract (),
ACE_Time_Value (1));
ACE_ASSERT (timer_id != -1);
result =
timer_queue.schedule (handler,
two_second_timeout,
- ACE_Time_Value (2) + timer_queue.gettimeofday ());
+ ACE_Time_Value (2) + timer_queue.gettimeofday_abstract ());
ACE_ASSERT (result != -1);
events += 4;
@@ -451,7 +421,7 @@ simple (ACE_Timer_Queue &timer_queue)
timer_id =
timer_queue.schedule (handler,
one_second_timeout,
- ACE_Time_Value (1) + timer_queue.gettimeofday (),
+ ACE_Time_Value (1) + timer_queue.gettimeofday_abstract (),
ACE_Time_Value (1));
ACE_ASSERT (timer_id != -1);
@@ -469,7 +439,7 @@ simple (ACE_Timer_Queue &timer_queue)
timer_id =
timer_queue.schedule (handler,
one_second_timeout,
- ACE_Time_Value (1) + timer_queue.gettimeofday (),
+ ACE_Time_Value (1) + timer_queue.gettimeofday_abstract (),
ACE_Time_Value (1));
ACE_ASSERT (timer_id != -1);
diff --git a/ACE/tests/Timer_Queue_Test.cpp b/ACE/tests/Timer_Queue_Test.cpp
index b267237018d..44cf2b81274 100644
--- a/ACE/tests/Timer_Queue_Test.cpp
+++ b/ACE/tests/Timer_Queue_Test.cpp
@@ -37,6 +37,7 @@
#include "ace/Null_Mutex.h"
#include "ace/OS_NS_unistd.h"
#include "ace/Containers_T.h"
+#include "ace/Event_Handler.h"
ACE_RCSID(tests, Timer_Queue_Test, "$Id$")
@@ -99,7 +100,7 @@ test_functionality (ACE_Timer_Queue *tq)
long timer_id2;
// Do a test on earliest_time.
- ACE_Time_Value earliest_time = tq->gettimeofday ();
+ ACE_Time_Value earliest_time = tq->gettimeofday_abstract ();
const void *timer_act = 0;
ACE_NEW (timer_act, int (1));
@@ -108,7 +109,7 @@ test_functionality (ACE_Timer_Queue *tq)
ACE_OS::sleep (ACE_Time_Value (0, 10));
ACE_NEW (timer_act, int (1));
- timer_id2 = tq->schedule (&eh, timer_act, tq->gettimeofday ());
+ timer_id2 = tq->schedule (&eh, timer_act, tq->gettimeofday_abstract ());
long result = tq->earliest_time () == earliest_time;
ACE_ASSERT (result != 0);
@@ -124,21 +125,21 @@ test_functionality (ACE_Timer_Queue *tq)
ACE_NEW (timer_act, int (1));
timer_id = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (timer_id != -1);
ACE_ASSERT (tq->is_empty () == 0); //==
ACE_NEW (timer_act, int (42));
result = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (result != -1);
ACE_ASSERT (tq->is_empty () == 0); //==
ACE_NEW (timer_act, int (42));
result = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (result != -1);
ACE_ASSERT (tq->is_empty () == 0); //==
@@ -157,21 +158,21 @@ test_functionality (ACE_Timer_Queue *tq)
ACE_NEW (timer_act, int (007));
result = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (result != -1);
const void *timer_act1 = 0;
ACE_NEW (timer_act1, int (42));
result = tq->schedule (&eh,
timer_act1,
- tq->gettimeofday () + ACE_Time_Value (100));
+ tq->gettimeofday_abstract () + ACE_Time_Value (100));
ACE_ASSERT (result != -1);
const void *timer_act2 = 0;
ACE_NEW (timer_act2, int (42));
result = tq->schedule (&eh,
timer_act2,
- tq->gettimeofday () + ACE_Time_Value (100));
+ tq->gettimeofday_abstract () + ACE_Time_Value (100));
ACE_ASSERT (result != -1);
// The following will trigger a call to <handle_close> when it
@@ -193,13 +194,13 @@ test_functionality (ACE_Timer_Queue *tq)
ACE_NEW (timer_act, int (4));
timer_id = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (timer_id != -1);
ACE_NEW (timer_act, int (4));
timer_id2 = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (timer_id2 != -1);
// The following method will trigger a call to <handle_close>.
@@ -225,7 +226,7 @@ test_functionality (ACE_Timer_Queue *tq)
ACE_NEW (timer_act, int (007));
result = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (result != -1);
result = tq->expire ();
@@ -235,13 +236,13 @@ test_functionality (ACE_Timer_Queue *tq)
ACE_NEW (timer_act, int (6));
timer_id = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (timer_id != -1);
ACE_NEW (timer_act, int (7));
timer_id2 = tq->schedule (&eh,
timer_act,
- tq->gettimeofday ());
+ tq->gettimeofday_abstract ());
ACE_ASSERT (timer_id2 != -1);
ACE_ASSERT (eh.close_count_ == 3);
@@ -280,7 +281,10 @@ test_performance (ACE_Timer_Queue *tq,
// Set up a bunch of times TIMER_DISTANCE ms apart.
for (i = 0; i < max_iterations; ++i)
- times[i] = tq->gettimeofday() + ACE_Time_Value(0, i * TIMER_DISTANCE * 1000);
+ {
+ times[i] = (tq->gettimeofday_abstract()
+ + ACE_Time_Value(0, i * TIMER_DISTANCE * 1000));
+ }
ACE_Time_Value last_time = times[max_iterations-1];
@@ -627,13 +631,9 @@ run_main (int argc, ACE_TCHAR *argv[])
// Timer_Heap without preallocated memory, using high-res time.
(void) ACE_High_Res_Timer::global_scale_factor ();
- typedef ACE_Timer_Heap_T<
- ACE_Event_Handler*,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
- ACE_SYNCH_RECURSIVE_MUTEX,
- ACE_FPointer_Time_Policy > Timer_Heap;
- Timer_Heap *tq_heap = new Timer_Heap;
+ ACE_Timer_Heap_Variable_Time_Source *tq_heap =
+ new ACE_Timer_Heap_Variable_Time_Source;
tq_heap->set_time_policy(&ACE_High_Res_Timer::gettimeofday_hr);
ACE_NEW_RETURN (tq_stack,
Timer_Queue_Stack (tq_heap,