summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcorino <mcorino@users.noreply.github.com>2011-12-08 18:35:38 +0000
committermcorino <mcorino@users.noreply.github.com>2011-12-08 18:35:38 +0000
commit01eb039cbc2232bb44b589635d11952e656902fa (patch)
tree1a632c5f5641b72fbdc137866384f49fa5c6442d
parentbc9acf7697ed3ebf81153735dd29a3bb5a41fc4a (diff)
downloadATCD-01eb039cbc2232bb44b589635d11952e656902fa.tar.gz
merged time policy changes from local branch
-rw-r--r--ACE/ChangeLog.BRANCH380
-rw-r--r--ACE/ace/Abstract_Timer_Queue.cpp24
-rw-r--r--ACE/ace/Abstract_Timer_Queue.h212
-rw-r--r--ACE/ace/Countdown_Time.cpp57
-rw-r--r--ACE/ace/Countdown_Time.h57
-rw-r--r--ACE/ace/Countdown_Time.inl20
-rw-r--r--ACE/ace/Countdown_Time_T.cpp65
-rw-r--r--ACE/ace/Countdown_Time_T.h100
-rw-r--r--ACE/ace/Countdown_Time_T.inl26
-rw-r--r--ACE/ace/Dev_Poll_Reactor.cpp34
-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/Proactor.cpp97
-rw-r--r--ACE/ace/Proactor.h46
-rw-r--r--ACE/ace/TP_Reactor.cpp37
-rw-r--r--ACE/ace/Time_Policy.cpp23
-rw-r--r--ACE/ace/Time_Policy.h156
-rw-r--r--ACE/ace/Time_Policy.inl75
-rw-r--r--ACE/ace/Time_Policy_T.cpp27
-rw-r--r--ACE/ace/Time_Policy_T.h75
-rw-r--r--ACE/ace/Time_Policy_T.inl25
-rw-r--r--ACE/ace/Timer_Hash.h14
-rw-r--r--ACE/ace/Timer_Hash_T.cpp140
-rw-r--r--ACE/ace/Timer_Hash_T.h45
-rw-r--r--ACE/ace/Timer_Heap.h11
-rw-r--r--ACE/ace/Timer_Heap_T.cpp142
-rw-r--r--ACE/ace/Timer_Heap_T.h35
-rw-r--r--ACE/ace/Timer_List.h8
-rw-r--r--ACE/ace/Timer_List_T.cpp100
-rw-r--r--ACE/ace/Timer_List_T.h23
-rw-r--r--ACE/ace/Timer_Queue.h4
-rw-r--r--ACE/ace/Timer_Queue_Adapters.cpp6
-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.cpp321
-rw-r--r--ACE/ace/Timer_Queue_T.h429
-rw-r--r--ACE/ace/Timer_Queue_T.inl178
-rw-r--r--ACE/ace/Timer_Queuefwd.h12
-rw-r--r--ACE/ace/Timer_Wheel.h8
-rw-r--r--ACE/ace/Timer_Wheel_T.cpp154
-rw-r--r--ACE/ace/Timer_Wheel_T.h35
-rw-r--r--ACE/ace/ace.mpc8
-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/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.cpp34
-rw-r--r--ACE/tests/Timer_Queue_Test.cpp13
-rw-r--r--TAO/ChangeLog.BRANCH130
-rw-r--r--TAO/bin/tao_orb_tests.lst4
-rw-r--r--TAO/tao/Block_Flushing_Strategy.cpp4
-rw-r--r--TAO/tao/HR_Time_Policy_Strategy.cpp55
-rw-r--r--TAO/tao/HR_Time_Policy_Strategy.h66
-rw-r--r--TAO/tao/Leader_Follower.cpp6
-rw-r--r--TAO/tao/LocateRequest_Invocation.cpp4
-rw-r--r--TAO/tao/ORB_Time_Policy.cpp32
-rw-r--r--TAO/tao/ORB_Time_Policy.h68
-rw-r--r--TAO/tao/ORB_Time_Policy.inl18
-rw-r--r--TAO/tao/Profile_Transport_Resolver.cpp4
-rw-r--r--TAO/tao/Strategies/advanced_resource.cpp18
-rw-r--r--TAO/tao/Synch_Invocation.cpp6
-rw-r--r--TAO/tao/TAO_Internal.cpp6
-rw-r--r--TAO/tao/Time_Policy_Manager.cpp164
-rw-r--r--TAO/tao/Time_Policy_Manager.h87
-rw-r--r--TAO/tao/Time_Policy_Strategy.h61
-rw-r--r--TAO/tao/Transport.cpp4
-rw-r--r--TAO/tao/Wait_On_Reactor.cpp4
-rw-r--r--TAO/tao/Wait_On_Read.cpp4
-rw-r--r--TAO/tao/default_resource.cpp72
-rw-r--r--TAO/tao/default_resource.h39
-rw-r--r--TAO/tao/default_resource.inl32
-rw-r--r--TAO/tao/orbconf.h8
-rw-r--r--TAO/tao/tao.mpc7
-rw-r--r--TAO/tests/Time_Policy/Time_Policy.mpc12
-rw-r--r--TAO/tests/Time_Policy/hr_time.conf3
-rw-r--r--TAO/tests/Time_Policy/hr_time.conf.xml6
-rw-r--r--TAO/tests/Time_Policy/main.cpp194
-rwxr-xr-xTAO/tests/Time_Policy/run_test.pl38
-rwxr-xr-xTAO/tests/Time_Policy/run_test_hr.pl44
-rw-r--r--TAO/tests/Time_Policy_Custom/Custom_Time_Policy.mpc21
-rw-r--r--TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.cpp63
-rw-r--r--TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.h53
-rw-r--r--TAO/tests/Time_Policy_Custom/TPTest_Export.h58
-rw-r--r--TAO/tests/Time_Policy_Custom/custom_time.conf7
-rw-r--r--TAO/tests/Time_Policy_Custom/custom_time.conf.xml9
-rw-r--r--TAO/tests/Time_Policy_Custom/main.cpp163
-rwxr-xr-xTAO/tests/Time_Policy_Custom/run_test.pl38
-rwxr-xr-xTAO/tests/Time_Policy_Custom/run_test_dyn.pl44
97 files changed, 4293 insertions, 1444 deletions
diff --git a/ACE/ChangeLog.BRANCH b/ACE/ChangeLog.BRANCH
new file mode 100644
index 00000000000..2581e844275
--- /dev/null
+++ b/ACE/ChangeLog.BRANCH
@@ -0,0 +1,380 @@
+ Mon Dec 05 10:26:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Time_Policy.inl
+
+ Prevent setting delegate to null pointer.
+
+ Sun Dec 04 15:40:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Countdown_Time.cpp:
+ * ace/Countdown_Time.inl:
+
+ Renamed to *_T.*
+
+ * ace/Countdown_Time.h
+ * ace/Countdown_Time_T.cpp
+ * ace/Countdown_Time_T.h
+ * ace/Countdown_Time_T.inl
+
+ Changed ACE_Countdown_Time to TIME_POLICY based
+ template class ACE_Countdown_Time_T,
+ Created typedef for default template instantiation
+ as ACE_Countdown_Time.
+
+ * ace/Time_Policy.cpp
+ * ace/Time_Policy.h
+ * ace/Time_Policy.inl
+ * ace/Time_Policy_T.cpp
+ * ace/Time_Policy_T.h
+ * ace/Time_Policy_T.inl
+
+ Added support for dynamically loadable/shared time
+ policies.
+
+ * ace/ace.mpc
+
+ Updated for file changes.
+
+ Fri Dec 02 11:48:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+
+ Reverting set_time_policy() change. Interpretation error.
+
+ Thu Dec 01 17:52:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Time_Policy.h:
+ * ace/Time_Policy.inl:
+
+ Added ACE_HR_Time_Policy.
+
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+
+ Replaced set_time_policy() by get_time_policy() since setting
+ the policy is not possible but configuring might be.
+
+ Thu Dec 01 14:05:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Proactor.cpp:
+ * ace/Timer_Queue_T.cpp:
+ * ace/Timer_Queue_T.h:
+
+ Fixed compile errors.
+
+ Thu Dec 01 13:34:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * ace/Timer_Hash_T.cpp:
+ * ace/Timer_Hash_T.h:
+ * ace/Timer_Heap_T.h:
+ * ace/Timer_Wheel_T.h:
+
+ Small cleanup to prevent potential compiler warnings.
+
+ Mon Aug 24 02:27:36 UTC 2009 Carlos O'Ryan <coryan@glamdring>
+
+ * ace/Timer_Queue_T.cpp:
+ Need to release the internal timer queue lock before dispatching
+ calls in expire_single(), otherwise we get nasty deadlocks in
+ the TP_Reactor implementation.
+
+ Thu Jul 2 02:55:09 UTC 2009 Carlos O'Ryan <coryan@glamdring>
+
+ * ace/Abstract_Timer_Queue.h:
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+ * ace/Timer_Queue_T.cpp:
+ I wanted to use gettimeofday() for the pure virtual function and
+ some other name for the inline function used in the timer queue
+ internals.
+ This is the second and final pass to get that change in. This
+ time, I renamed the internal function to gettimeofday_static(),
+ used the compiler (and grep) to find all uses. Once that
+ compiled I renamed the virtual function from
+ gettimeofday_abstract() to the gettimeofday() function.
+ I know it is convoluted, but it gets the job done without me
+ having to think too much.
+
+ * ace/Timer_Hash_T.h:
+ * ace/Timer_Hash_T.cpp:
+ * ace/Select_Reactor_T.cpp:
+ * ace/Dev_Poll_Reactor.cpp:
+ * ace/Proactor.cpp:
+ * ace/Timer_Queue_Adapters.cpp:
+ * tests/Timer_Queue_Reference_Counting_Test.cpp:
+ * tests/Timer_Queue_Test.cpp:
+ * examples/APG/Timers/Timers.cpp:
+ * examples/APG/Timers/TimerDispatcher.cpp:
+ * examples/C++NPv2/Logging_Event_Handler_Ex.cpp:
+ Fixed users and tests to use the real name for gettimeofday() in
+ ACE_Abstract_Timer_Queue<>
+
+ 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
+ late that the changes from 3706 will be needed to make this work.
+
+ * ace/ace.mpc:
+ * ace/Time_Policy.h:
+ * ace/Time_Policy.inl:
+ * ace/Time_Policy.cpp:
+ New classes to encapsulate how "now" is computed in the Timer
+ Queues. This will be an additional template parameter, so the
+ default configuration has zero overhead.
+
+ * ace/Timer_Queuefwd.h:
+ * ace/Timer_List.h:
+ * ace/Timer_List_T.h:
+ * ace/Timer_List_T.cpp:
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+ * ace/Timer_Queue_T.cpp:
+ * ace/Timer_Wheel.h:
+ * ace/Timer_Wheel_T.h:
+ * ace/Timer_Wheel_T.cpp:
+ * ace/Timer_Hash.h:
+ * ace/Timer_Hash_T.h:
+ * ace/Timer_Hash_T.cpp:
+ * ace/Timer_Heap.h:
+ * ace/Timer_Heap_T.h:
+ * ace/Timer_Heap_T.cpp:
+ Re-factor timer queue classes to use new TIMER_POLICY
+ parameter.
+
+ * tests/Timer_Queue_Test.cpp:
+ Modify test to use TIMER_POLICY. But here is the rub, the test
+ does not compile because all timer queue types are "different"
+ to each other. I need to introduce the base class from the
+ bug-3706 branch to make things work.
+
+ Sun Jun 28 22:15:47 UTC 2009 Carlos O'Ryan <coryan@glamdring>
+
+ * ace/ace.mpc:
+ * ace/Abstract_Timer_Queue.h:
+ * ace/Abstract_Timer_Queue.cpp:
+ * ace/Timer_Queue_Iterator.h:
+ * ace/Timer_Queue_Iterator.inl:
+ * ace/Timer_Queue_Iterator.cpp:
+ * ace/Timer_Queuefwd.h:
+ * ace/Timer_Queue.h:
+ * ace/Timer_Queue_T.h:
+ * ace/Timer_Queue_T.inl:
+ * ace/Timer_Queue_T.cpp:
+ * ace/Timer_List_T.h:
+ * ace/Timer_List_T.cpp:
+ * ace/Timer_Wheel_T.h:
+ * ace/Timer_Wheel_T.cpp:
+ * ace/Timer_Hash_T.h:
+ * ace/Timer_Hash_T.cpp:
+ * ace/Timer_Heap_T.h:
+ * ace/Timer_Heap_T.cpp:
+ Heavy refactoring in ACE_Timer_Queue_T class and friends.
+ First, created a template base class (ACE_Abstract_Timer_Queue) that:
+ 1) Only depends on the type held by the timer queue, not to lock
+ or upcall strategy.
+ 2) It is a pure abstract class, i.e., none of its member
+ functions have any implementation.
+ 3) Provides new pure virtual functions to encapsulates some
+ logic that was spread between tests, TP_Reactor and
+ Dev_Poll_Reactor.
+ Then I re-wrote all the standard timer queue objects in terms of
+ this class. In particular, the reactors use only the abstract
+ interface.
+ I also re-factored the Timer_Queue_Iterator to only depend on
+ the type of objects held by the timer queue. The rest of the
+ parameters where not used either.
+ Implement functionality that was spread in Dev_Poll_Reactor,
+ TP_Reactor and a test into expire_single.
+
+ * ace/Proactor.h:
+ * ace/TP_Reactor.cpp:
+ * ace/Dev_Poll_Reactor.cpp:
+ Both classes implemented the logic to dispatch a single timer
+ but release a mutex before the upcall. This was confusing as
+ well as required exposing too much detail about the Timer_Queue
+ classes.
+ The new mechanism is a single function in (expire_single)
+ ACE_Abstract_Timer_Queue<> (implemented in ACE_Timer_Queue_T<>)
+ which receives a command object to encapsulate the mutex release.
+
+ * ace/Functor.h:
+ * ace/Functor.cpp:
+ * ace/Functor_T.h:
+ * ace/Functor_T.inl:
+ Add helper ACE_Command_* objects. One is a no-op, for the test
+ below. The other is a callback that ignores the silly void*
+ argument in the ACE_Command_Base::execute() member function.
+
+ * tests/Timer_Queue_Reference_Counting_Test.cpp:
+ Re-factored test in terms of expire_single()
+
+
+Local Variables:
+mode: change-log
+add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time))
+indent-tabs-mode: nil
+End:
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..f01817ccc7f
--- /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 (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/Countdown_Time.cpp b/ACE/ace/Countdown_Time.cpp
deleted file mode 100644
index 335931514e4..00000000000
--- a/ACE/ace/Countdown_Time.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// $Id$
-
-#include "ace/Countdown_Time.h"
-#include "ace/OS_NS_sys_time.h"
-
-#if !defined (__ACE_INLINE__)
-#include "ace/Countdown_Time.inl"
-#endif /* __ACE_INLINE__ */
-
-ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-
-ACE_Countdown_Time::ACE_Countdown_Time (ACE_Time_Value *max_wait_time)
- : max_wait_time_ (max_wait_time),
- stopped_ (false)
-{
- this->start ();
-}
-
-ACE_Countdown_Time::~ACE_Countdown_Time (void)
-{
- this->stop ();
-}
-
-void
-ACE_Countdown_Time::start (void)
-{
- if (this->max_wait_time_ != 0)
- {
- this->start_time_ = ACE_OS::gettimeofday ();
- this->stopped_ = false;
- }
-}
-
-void
-ACE_Countdown_Time::stop (void)
-{
- if (this->max_wait_time_ != 0 && !this->stopped_)
- {
- ACE_Time_Value const elapsed_time =
- ACE_OS::gettimeofday () - this->start_time_;
-
- if (elapsed_time >= ACE_Time_Value::zero &&
- *this->max_wait_time_ > elapsed_time)
- {
- *this->max_wait_time_ -= elapsed_time;
- }
- else
- {
- // Used all of timeout.
- *this->max_wait_time_ = ACE_Time_Value::zero;
- // errno = ETIME;
- }
- this->stopped_ = true;
- }
-}
-
-ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Countdown_Time.h b/ACE/ace/Countdown_Time.h
index 1d17c3aead7..30ed1c9d99e 100644
--- a/ACE/ace/Countdown_Time.h
+++ b/ACE/ace/Countdown_Time.h
@@ -7,6 +7,7 @@
* $Id$
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Irfan Pyarali <irfan@cs.wustl.edu>
*/
//=============================================================================
@@ -15,67 +16,21 @@
#include /**/ "ace/pre.h"
-#include /**/ "ace/ACE_export.h"
-
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "ace/Time_Value.h"
-#include "ace/Copy_Disabled.h"
+#include "ace/Countdown_Time_T.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-/**
- * @class ACE_Countdown_Time
- *
- * @brief Keeps track of the amount of elapsed time.
- *
- * This class has a side-effect on the @c max_wait_time -- every
- * time the stop() method is called the @c max_wait_time is
- * updated.
- */
-class ACE_Export ACE_Countdown_Time : private ACE_Copy_Disabled
-{
-public:
- /// Cache the @a max_wait_time and call @c start().
- ACE_Countdown_Time (ACE_Time_Value *max_wait_time);
-
- /// Destructor, makes sure the max_wait_time that got passed as pointer
- /// to the constructor is updated with the time elapsed.
- ~ACE_Countdown_Time (void);
-
- /// Cache the current time and enter a start state.
- void start (void);
-
- /// Subtract the elapsed time from max_wait_time_ and enter a stopped
- /// state.
- void stop (void);
-
- /// Calls stop and then start. max_wait_time_ is modified by the
- /// call to stop.
- void update (void);
-
- /// Returns true if we've already been stopped, else false.
- bool stopped (void) const;
-
-private:
- /// Maximum time we were willing to wait.
- ACE_Time_Value *max_wait_time_;
-
- /// Beginning of the start time.
- ACE_Time_Value start_time_;
-
- /// Keeps track of whether we've already been stopped.
- bool stopped_;
-};
+// The following typedef is here for ease of use and backward
+// compatibility.
+typedef ACE_Countdown_Time_T<ACE_Default_Time_Policy>
+ ACE_Countdown_Time;
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
-#if defined (__ACE_INLINE__)
-#include "ace/Countdown_Time.inl"
-#endif /* __ACE_INLINE__ */
-
#endif /* ACE_COUNTDOWN_TIME_H */
diff --git a/ACE/ace/Countdown_Time.inl b/ACE/ace/Countdown_Time.inl
deleted file mode 100644
index 3911ca85bda..00000000000
--- a/ACE/ace/Countdown_Time.inl
+++ /dev/null
@@ -1,20 +0,0 @@
-// -*- C++ -*-
-//
-// $Id$
-
-ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-
-ACE_INLINE bool
-ACE_Countdown_Time::stopped (void) const
-{
- return stopped_;
-}
-
-ACE_INLINE void
-ACE_Countdown_Time::update (void)
-{
- this->stop ();
- this->start ();
-}
-
-ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Countdown_Time_T.cpp b/ACE/ace/Countdown_Time_T.cpp
new file mode 100644
index 00000000000..c59784207e5
--- /dev/null
+++ b/ACE/ace/Countdown_Time_T.cpp
@@ -0,0 +1,65 @@
+// $Id$
+
+#ifndef ACE_COUNTDOWN_TIME_T_CPP
+#define ACE_COUNTDOWN_TIME_T_CPP
+
+#include "ace/Countdown_Time_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Countdown_Time_T.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <typename TIME_POLICY> ACE_INLINE
+ACE_Countdown_Time_T<TIME_POLICY>::ACE_Countdown_Time_T (ACE_Time_Value *max_wait_time,
+ TIME_POLICY const & time_policy)
+ : time_policy_ (time_policy),
+ max_wait_time_ (max_wait_time),
+ stopped_ (false)
+{
+ this->start ();
+}
+
+template <typename TIME_POLICY> ACE_INLINE
+ACE_Countdown_Time_T<TIME_POLICY>::~ACE_Countdown_Time_T (void)
+{
+ this->stop ();
+}
+
+template <typename TIME_POLICY> ACE_INLINE void
+ACE_Countdown_Time_T<TIME_POLICY>::start (void)
+{
+ if (this->max_wait_time_ != 0)
+ {
+ this->start_time_ = this->time_policy_ ();
+ this->stopped_ = false;
+ }
+}
+
+template <typename TIME_POLICY> ACE_INLINE void
+ACE_Countdown_Time_T<TIME_POLICY>::stop (void)
+{
+ if (this->max_wait_time_ != 0 && !this->stopped_)
+ {
+ ACE_Time_Value const elapsed_time =
+ this->time_policy_ () - this->start_time_;
+
+ if (elapsed_time >= ACE_Time_Value::zero &&
+ *this->max_wait_time_ > elapsed_time)
+ {
+ *this->max_wait_time_ -= elapsed_time;
+ }
+ else
+ {
+ // Used all of timeout.
+ *this->max_wait_time_ = ACE_Time_Value::zero;
+ // errno = ETIME;
+ }
+ this->stopped_ = true;
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_COUNTDOWN_TIME_T_CPP */
diff --git a/ACE/ace/Countdown_Time_T.h b/ACE/ace/Countdown_Time_T.h
new file mode 100644
index 00000000000..faca33de28e
--- /dev/null
+++ b/ACE/ace/Countdown_Time_T.h
@@ -0,0 +1,100 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Countdown_Time_T.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_COUNTDOWN_TIME_T_H
+#define ACE_COUNTDOWN_TIME_T_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/ACE_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Time_Value.h"
+#include "ace/Time_Policy.h"
+#include "ace/Copy_Disabled.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Countdown_Time
+ *
+ * @brief Keeps track of the amount of elapsed time.
+ *
+ * This class has a side-effect on the @c max_wait_time -- every
+ * time the stop() method is called the @c max_wait_time is
+ * updated.
+ */
+template <typename TIME_POLICY = ACE_Default_Time_Policy>
+class ACE_Export ACE_Countdown_Time_T : private ACE_Copy_Disabled
+{
+public:
+ /// Cache the @a max_wait_time and call @c start().
+ ACE_Countdown_Time_T (ACE_Time_Value *max_wait_time,
+ TIME_POLICY const & time_policy = TIME_POLICY());
+
+ /// Destructor, makes sure the max_wait_time that got passed as pointer
+ /// to the constructor is updated with the time elapsed.
+ ~ACE_Countdown_Time_T (void);
+
+ /// Cache the current time and enter a start state.
+ void start (void);
+
+ /// Subtract the elapsed time from max_wait_time_ and enter a stopped
+ /// state.
+ void stop (void);
+
+ /// Calls stop and then start. max_wait_time_ is modified by the
+ /// call to stop.
+ void update (void);
+
+ /// Returns true if we've already been stopped, else false.
+ bool stopped (void) const;
+
+ /// Allows applications to control how the timer queue gets the time
+ /// of day.
+ void set_time_policy(TIME_POLICY const & time_policy);
+
+private:
+ /// The policy to return the current time of day
+ TIME_POLICY time_policy_;
+
+ /// Maximum time we were willing to wait.
+ ACE_Time_Value *max_wait_time_;
+
+ /// Beginning of the start time.
+ ACE_Time_Value start_time_;
+
+ /// Keeps track of whether we've already been stopped.
+ bool stopped_;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#if defined (__ACE_INLINE__)
+#include "ace/Countdown_Time_T.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Countdown_Time_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Countdown_Time_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+
+#endif /* ACE_COUNTDOWN_TIME_T_H */
diff --git a/ACE/ace/Countdown_Time_T.inl b/ACE/ace/Countdown_Time_T.inl
new file mode 100644
index 00000000000..79abe9670d7
--- /dev/null
+++ b/ACE/ace/Countdown_Time_T.inl
@@ -0,0 +1,26 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <typename TIME_POLICY> ACE_INLINE bool
+ACE_Countdown_Time_T<TIME_POLICY>::stopped (void) const
+{
+ return stopped_;
+}
+
+template <typename TIME_POLICY> ACE_INLINE void
+ACE_Countdown_Time_T<TIME_POLICY>::update (void)
+{
+ this->stop ();
+ this->start ();
+}
+
+template <typename TIME_POLICY> ACE_INLINE void
+ACE_Countdown_Time_T<TIME_POLICY>::set_time_policy(TIME_POLICY const & time_policy)
+{
+ this->time_policy_ = time_policy;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Dev_Poll_Reactor.cpp b/ACE/ace/Dev_Poll_Reactor.cpp
index 318c1c62579..6da3c4b5bb3 100644
--- a/ACE/ace/Dev_Poll_Reactor.cpp
+++ b/ACE/ace/Dev_Poll_Reactor.cpp
@@ -39,6 +39,7 @@
#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
@@ -1090,37 +1091,10 @@ ACE_Dev_Poll_Reactor::dispatch (Token_Guard &guard)
int
ACE_Dev_Poll_Reactor::dispatch_timer_handler (Token_Guard &guard)
{
- if (this->timer_queue_->is_empty ())
- return 0; // Empty timer queue so cannot have any expired timers.
+ typedef ACE_Member_Function_Command<Token_Guard> Guard_Release;
- // Get the current time
- ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () +
- this->timer_queue_->timer_skew ());
-
- // Look for a node in the timer queue whose timer <= the present
- // time.
- ACE_Timer_Node_Dispatch_Info info;
- if (this->timer_queue_->dispatch_info (cur_time, info))
- {
- const void *upcall_act = 0;
-
- // Preinvoke (handles refcount if needed, etc.)
- this->timer_queue_->preinvoke (info, cur_time, upcall_act);
-
- // Release the token before expiration upcall.
- guard.release_token ();
-
- // call the functor
- this->timer_queue_->upcall (info, cur_time);
-
- // Postinvoke (undo refcount if needed, etc.)
- this->timer_queue_->postinvoke (info, cur_time, upcall_act);
-
- // We have dispatched a timer
- return 1;
- }
-
- return 0;
+ Guard_Release release(guard, &Token_Guard::release_token);
+ return this->timer_queue_->expire_single(release);
}
#if 0
diff --git a/ACE/ace/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 f6bd6e0d1a4..f60488e3509 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 dda37360a9f..cf8b4512c49 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 53c06261acd..f8a215c078e 100644
--- a/ACE/ace/Functor_T.h
+++ b/ACE/ace/Functor_T.h
@@ -79,6 +79,38 @@ private:
ACTION action_;
};
+/**
+ * @class ACE_Member_Function_Command
+ *
+ * @brief Defines a class template that allows us to invoke a member
+ * function using the GoF command style callback.
+ *
+ */
+template <class RECEIVER>
+class ACE_Member_Function_Command : public ACE_Command_Base
+{
+public:
+ typedef void (RECEIVER::*PTMF)(void);
+
+ /// Con Constructor: sets the <receiver_> of the Command to recvr, and the
+ /// <action_> of the Command to <action>.
+ ACE_Member_Function_Command (RECEIVER &recvr, PTMF ptmf);
+
+ /// Virtual destructor.
+ virtual ~ACE_Member_Function_Command (void);
+
+ /// Invokes the method <action_> from the object <receiver_>. The
+ /// parameter is ignored
+ virtual int execute (void *);
+
+private:
+ /// Object where the method resides.
+ RECEIVER &receiver_;
+
+ /// Method that is going to be invoked.
+ PTMF ptmf_;
+};
+
/////////////////////////////////
// STL-style Functor Templates //
/////////////////////////////////
diff --git a/ACE/ace/Functor_T.inl b/ACE/ace/Functor_T.inl
index 6441c091b76..d6cefade1bd 100644
--- a/ACE/ace/Functor_T.inl
+++ b/ACE/ace/Functor_T.inl
@@ -4,6 +4,27 @@
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+template<class RECEIVER> ACE_INLINE
+ACE_Member_Function_Command<RECEIVER>::
+ACE_Member_Function_Command (RECEIVER &recvr, PTMF ptmf)
+ : receiver_(recvr)
+ , ptmf_(ptmf)
+{
+}
+
+template<class RECEIVER> ACE_INLINE
+ACE_Member_Function_Command<RECEIVER>::
+~ACE_Member_Function_Command (void)
+{
+}
+
+template<class RECEIVER> ACE_INLINE int
+ACE_Member_Function_Command<RECEIVER>::execute (void *)
+{
+ (this->receiver_.*ptmf_)();
+ return 0;
+}
+
template <class TYPE> ACE_INLINE unsigned long
ACE_Hash<TYPE>::operator () (const TYPE &t) const
{
diff --git a/ACE/ace/Proactor.cpp b/ACE/ace/Proactor.cpp
index d88f4117ea8..aa10f34c669 100644
--- a/ACE/ace/Proactor.cpp
+++ b/ACE/ace/Proactor.cpp
@@ -58,11 +58,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);
@@ -75,6 +70,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
@@ -100,6 +100,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;
@@ -108,6 +114,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
@@ -127,7 +140,8 @@ 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 ();
// Compare absolute time with curent time received from the
// timer queue.
@@ -172,15 +186,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,
@@ -191,7 +206,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,
@@ -202,7 +217,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,
@@ -248,7 +263,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 &)
@@ -258,7 +273,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)
@@ -268,7 +283,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 *)
{
@@ -295,7 +310,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),
@@ -666,42 +681,13 @@ 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);
+ 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;
@@ -765,14 +751,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_)
@@ -795,7 +781,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 = 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 18f2c2c0e27..13a90203f0c 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/TP_Reactor.cpp b/ACE/ace/TP_Reactor.cpp
index bd0a7c12884..2c7c4d0b13e 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__)
@@ -306,40 +307,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/Time_Policy.cpp b/ACE/ace/Time_Policy.cpp
new file mode 100644
index 00000000000..4e36ffe6734
--- /dev/null
+++ b/ACE/ace/Time_Policy.cpp
@@ -0,0 +1,23 @@
+// $Id$
+
+#include "ace/Time_Policy.h"
+
+#if !defined(__ACE_INLINE__)
+# include "ace/Time_Policy.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_Dynamic_Time_Policy_Base::~ACE_Dynamic_Time_Policy_Base ()
+{
+}
+
+ACE_Time_Value ACE_Delegating_Time_Policy::NULL_Time_Policy::gettimeofday () const
+{
+ return ACE_Time_Value::zero;
+}
+
+ACE_Delegating_Time_Policy::NULL_Time_Policy ACE_Delegating_Time_Policy::null_policy_;
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
diff --git a/ACE/ace/Time_Policy.h b/ACE/ace/Time_Policy.h
new file mode 100644
index 00000000000..0d8858f4009
--- /dev/null
+++ b/ACE/ace/Time_Policy.h
@@ -0,0 +1,156 @@
+#ifndef ACE_TIME_POLICY_H
+#define ACE_TIME_POLICY_H
+// -*- C++ -*-
+/**
+ * @file Time_Policy.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan <coryan@atdesk.com>
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/config-all.h"
+
+#include /**/ "ace/Time_Value.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Default_Time_Policy
+ *
+ * @brief Implement the default time policy for ACE.
+ *
+ * The most common time policy is to simply use
+ * ACE_OS::gettimeofday(), this class implements that policy, i.e., it
+ * simply calls that function.
+ */
+class ACE_Export ACE_Default_Time_Policy
+{
+public:
+ /// Return the current time according to this policy
+ ACE_Time_Value operator() () const;
+};
+
+/**
+ * @class ACE_HR_Time_Policy
+ *
+ * @brief Implement a time policy based on the ACE Highres timer.
+ *
+ */
+class ACE_Export ACE_HR_Time_Policy
+{
+public:
+ /// Return the current time according to this policy
+ ACE_Time_Value operator() () const;
+};
+
+/**
+ * @class ACE_FPointer_Timer_Policy
+ *
+ * @brief Implement a time policy based on a function pointer.
+ *
+ * This time policy allows dynamic changes to the source of time by
+ * using a function pointer.
+ */
+class ACE_Export ACE_FPointer_Time_Policy
+{
+public:
+ /**
+ * @brief Default constructor uses ACE_OS::gettimeofday()
+ *
+ * ACE_T requires a default constructor that leaves the
+ * policy in a functional state. Therefore, a null pointer would
+ * not be desirable, in other words, we need a non-trivial default
+ * constructor.
+ */
+ ACE_FPointer_Time_Policy();
+
+ /**
+ * @typedef FPtr
+ *
+ * Short-hand for the right type of pointer to function.
+ */
+ typedef ACE_Time_Value (*FPtr)();
+
+ /**
+ * @brief Constructor from a pointer to function.
+ *
+ * Construct from a pointer to function.
+ */
+ ACE_FPointer_Time_Policy(FPtr f);
+
+ /// Return the current time according to this policy
+ ACE_Time_Value operator()() const;
+
+
+private:
+ FPtr function_;
+};
+
+/**
+ * @class ACE_Dynamic_Time_Policy_base
+ *
+ * @brief Abstract base class for dynamically loaded and/or shared
+ * time policies.
+ *
+ */
+class ACE_Export ACE_Dynamic_Time_Policy_Base
+{
+public:
+ virtual ~ACE_Dynamic_Time_Policy_Base ();
+
+ /// Return the current time according to this policy
+ ACE_Time_Value operator()() const;
+
+protected:
+ /// Return the current time according to policy implementation.
+ virtual ACE_Time_Value gettimeofday () const = 0;
+};
+
+/**
+ * @class ACE_Delegating_Time_Policy
+ *
+ * @brief Implement a time policy that delegates to a dynamic
+ * time policy.
+ *
+ */
+class ACE_Export ACE_Delegating_Time_Policy
+{
+public:
+ ACE_Delegating_Time_Policy (ACE_Dynamic_Time_Policy_Base const * delegate = 0);
+
+ /// Return the current time according to this policy
+ ACE_Time_Value operator()() const;
+
+ /// Set delegate
+ void set_delegate (ACE_Dynamic_Time_Policy_Base const * delegate);
+
+ /// Copy policy
+ ACE_Delegating_Time_Policy& operator =(ACE_Delegating_Time_Policy const & pol);
+
+private:
+ ACE_Dynamic_Time_Policy_Base const * delegate_;
+
+ class NULL_Time_Policy : public ACE_Dynamic_Time_Policy_Base
+ {
+ protected:
+ virtual ACE_Time_Value gettimeofday () const;
+ };
+
+ static NULL_Time_Policy null_policy_;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/Time_Policy.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_TIME_POLICY_H */
diff --git a/ACE/ace/Time_Policy.inl b/ACE/ace/Time_Policy.inl
new file mode 100644
index 00000000000..10d28730a29
--- /dev/null
+++ b/ACE/ace/Time_Policy.inl
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#include "ace/OS_NS_sys_time.h"
+#include "ace/High_Res_Timer.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE ACE_Time_Value
+ACE_Default_Time_Policy::operator()() const
+{
+ return ACE_OS::gettimeofday();
+}
+
+ACE_INLINE ACE_Time_Value
+ACE_HR_Time_Policy::operator()() const
+{
+ return ACE_High_Res_Timer::gettimeofday_hr ();
+}
+
+ACE_INLINE
+ACE_FPointer_Time_Policy::ACE_FPointer_Time_Policy()
+ : function_(ACE_OS::gettimeofday)
+{
+}
+
+ACE_INLINE
+ACE_FPointer_Time_Policy::
+ACE_FPointer_Time_Policy(ACE_FPointer_Time_Policy::FPtr f)
+ : function_(f)
+{
+}
+
+ACE_INLINE ACE_Time_Value
+ACE_FPointer_Time_Policy::operator()() const
+{
+ return (*this->function_)();
+}
+
+ACE_INLINE ACE_Time_Value
+ACE_Dynamic_Time_Policy_Base::operator()() const
+{
+ return this->gettimeofday ();
+}
+
+ACE_INLINE
+ACE_Delegating_Time_Policy::ACE_Delegating_Time_Policy (ACE_Dynamic_Time_Policy_Base const * delegate)
+ : delegate_ (delegate != 0 ? delegate : &null_policy_)
+{
+}
+
+ACE_INLINE ACE_Time_Value
+ACE_Delegating_Time_Policy::operator()() const
+{
+ return (*this->delegate_) ();
+}
+
+ACE_INLINE void
+ACE_Delegating_Time_Policy::set_delegate (ACE_Dynamic_Time_Policy_Base const * delegate)
+{
+ if (delegate != 0)
+ {
+ this->delegate_ = delegate;
+ }
+}
+
+ACE_INLINE ACE_Delegating_Time_Policy&
+ACE_Delegating_Time_Policy::operator =(ACE_Delegating_Time_Policy const & pol)
+{
+ this->delegate_ = pol.delegate_;
+ return *this;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Time_Policy_T.cpp b/ACE/ace/Time_Policy_T.cpp
new file mode 100644
index 00000000000..f2a75aea684
--- /dev/null
+++ b/ACE/ace/Time_Policy_T.cpp
@@ -0,0 +1,27 @@
+// $Id$
+
+#ifndef ACE_TIME_POLICY_T_CPP
+#define ACE_TIME_POLICY_T_CPP
+
+#include "ace/Time_Policy_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Time_Policy_T.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <typename TIME_POLICY> ACE_INLINE
+ACE_Time_Policy_T<TIME_POLICY>::~ACE_Time_Policy_T ()
+{
+}
+
+template <typename TIME_POLICY> ACE_INLINE ACE_Time_Value
+ACE_Time_Policy_T<TIME_POLICY>::gettimeofday () const
+{
+ return this->time_policy_ ();
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_TIME_POLICY_T_CPP */
diff --git a/ACE/ace/Time_Policy_T.h b/ACE/ace/Time_Policy_T.h
new file mode 100644
index 00000000000..fce00b36a13
--- /dev/null
+++ b/ACE/ace/Time_Policy_T.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Time_Policy_T.h
+ *
+ * $Id$
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+//=============================================================================
+
+#ifndef ACE_TIME_POLICY_T_H
+#define ACE_TIME_POLICY_T_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/ACE_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Time_Policy.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Time_Policy_T
+ *
+ * @brief Template class implementing a dynamic time policy based on
+ * another time policy
+ *
+ */
+template <typename TIME_POLICY>
+class ACE_Export ACE_Time_Policy_T : public ACE_Dynamic_Time_Policy_Base
+{
+public:
+ ACE_Time_Policy_T (TIME_POLICY const & time_policy = TIME_POLICY());
+ virtual ~ACE_Time_Policy_T ();
+
+ /// Return the current time according to this policy
+ ACE_Time_Value operator()() const;
+
+ /// Allows applications to control how the timer queue gets the time
+ /// of day.
+ void set_time_policy(TIME_POLICY const & time_policy);
+
+protected:
+ /// Return the current time according to policy implementation.
+ virtual ACE_Time_Value gettimeofday () const;
+
+private:
+ /// The policy to return the current time of day
+ TIME_POLICY time_policy_;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#if defined (__ACE_INLINE__)
+#include "ace/Time_Policy_T.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Time_Policy_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Time_Policy_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+
+#endif /* ACE_TIME_POLICY_T_H */
diff --git a/ACE/ace/Time_Policy_T.inl b/ACE/ace/Time_Policy_T.inl
new file mode 100644
index 00000000000..a110ee7057b
--- /dev/null
+++ b/ACE/ace/Time_Policy_T.inl
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <typename TIME_POLICY> ACE_INLINE
+ACE_Time_Policy_T<TIME_POLICY>::ACE_Time_Policy_T (TIME_POLICY const & time_policy)
+ : time_policy_ (time_policy)
+{
+}
+
+template <typename TIME_POLICY> ACE_INLINE ACE_Time_Value
+ACE_Time_Policy_T<TIME_POLICY>::operator() () const
+{
+ return this->gettimeofday ();
+}
+
+template <typename TIME_POLICY> ACE_INLINE void
+ACE_Time_Policy_T<TIME_POLICY>::set_time_policy(TIME_POLICY const & time_policy)
+{
+ this->time_policy_ = time_policy;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Hash.h b/ACE/ace/Timer_Hash.h
index 2d959be39c5..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,26 +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_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 c3e452301f0..44f658979d5 100644
--- a/ACE/ace/Timer_Hash_T.cpp
+++ b/ACE/ace/Timer_Hash_T.cpp
@@ -171,18 +171,24 @@ ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::deletion (
return result;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_Iterator_T (ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET> &hash)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
+ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::ACE_Timer_Hash_Iterator_T (Hash & hash)
: timer_hash_ (hash)
{
this->first ();
// Nothing
}
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
+ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::~ACE_Timer_Hash_Iterator_T ()
+{
+ // Nothing
+}
+
// Positions the iterator at the first node in the timing hash table
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
-ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> void
+ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::first (void)
{
for (this->position_ = 0;
this->position_ < this->timer_hash_.table_size_;
@@ -204,8 +210,8 @@ ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::first (void)
// Positions the iterator at the next node in the bucket or goes to the next
// bucket
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
-ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::next (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> void
+ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::next (void)
{
if (this->isdone ())
return;
@@ -235,17 +241,17 @@ ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::next (void)
// Returns true when we are at the end (when bucket_item_ == 0)
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> bool
-ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::isdone (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> bool
+ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::isdone (void) const
{
return this->iter_ == 0;
}
// Returns the node at the current position in the sequence
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::item (void)
+ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::item (void)
{
if (this->isdone ())
return 0;
@@ -253,9 +259,9 @@ ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::item (void)
return this->iter_->item ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::iter (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
+ACE_Timer_Queue_Iterator_T<TYPE> &
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
return *this->iterator_;
@@ -263,12 +269,13 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::iter (void)
// Create an empty queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::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 (
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),
@@ -283,16 +290,14 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_T (
ACE_NEW (table_,
BUCKET *[table_size]);
- this->gettimeofday (ACE_OS::gettimeofday);
-
for (size_t i = 0;
i < table_size;
++i)
{
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_,
@@ -300,11 +305,12 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_T (
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::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),
@@ -319,17 +325,14 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_T (
ACE_NEW (table_,
BUCKET *[ACE_DEFAULT_TIMER_HASH_TABLE_SIZE]);
-
- this->gettimeofday (ACE_OS::gettimeofday);
-
for (size_t i = 0;
i < this->table_size_;
++i)
{
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_,
@@ -338,8 +341,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_T (
// Remove all remaining items in the Queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::~ACE_Timer_Hash_T (void)
+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 (void)
{
ACE_TRACE ("ACE_Timer_Hash_T::~ACE_Timer_Hash_T");
ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
@@ -356,8 +359,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::~ACE_Timer_Hash_T (void)
// Checks if queue is empty.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> bool
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::is_empty (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> bool
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::is_empty (void) const
{
ACE_TRACE ("ACE_Timer_Hash_T::is_empty");
return this->table_[this->earliest_position_]->is_empty ();
@@ -365,16 +368,16 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::is_empty (void) const
// Returns earliest time in a non-empty bucket
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
const ACE_Time_Value &
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::earliest_time (void) const
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::earliest_time (void) const
{
ACE_TRACE ("ACE_Timer_Hash_T::earliest_time");
return this->table_[this->earliest_position_]->earliest_time ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::dump (void) const
+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>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Timer_Hash_T::dump");
@@ -394,9 +397,9 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::dump (void) const
// Reschedule a periodic timer. This function must be called with the
// mutex lock held.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
void
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::reschedule (
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::reschedule (
ACE_Timer_Node_T<TYPE> *expired)
{
ACE_TRACE ("ACE_Timer_Hash_T::reschedule");
@@ -423,7 +426,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::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 ()
@@ -434,9 +437,9 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::reschedule (
// Insert a new handler that expires at time future_time; if interval
// is > 0, the handler will be reinvoked periodically.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
long
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::schedule_i (
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::schedule_i (
const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
@@ -489,9 +492,9 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::schedule_i (
// Locate and update the inteval on the timer_id
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
int
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::reset_interval (
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::reset_interval (
long timer_id,
const ACE_Time_Value & interval)
{
@@ -526,9 +529,9 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::reset_interval (
// Locate and remove the single <ACE_Event_Handler> with a value of
// @a timer_id from the correct table timer queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
int
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (long timer_id,
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::cancel (long timer_id,
const void **act,
int dont_call)
{
@@ -596,9 +599,9 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (long timer_id,
// Locate and remove all values of <type> from the timer queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
int
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (const TYPE &type,
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::cancel (const TYPE &type,
int dont_call)
{
ACE_TRACE ("ACE_Timer_Hash_T::cancel");
@@ -618,9 +621,7 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (const TYPE &type,
i < this->table_size_;
++i)
{
- ACE_Timer_Queue_Iterator_T<TYPE,
- ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>,
- ACE_Null_Mutex> &iter =
+ ACE_Timer_Queue_Iterator_T<TYPE> & iter =
this->table_[i]->iter ();
for (iter.first ();
@@ -680,8 +681,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (const TYPE &type,
// Removes the earliest node and finds the new earliest position
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::remove_first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::remove_first (void)
{
if (this->is_empty ())
return 0;
@@ -698,8 +699,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::remove_first (void)
// Finds a new earliest position
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::find_new_earliest (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>::find_new_earliest (void)
{
for (size_t i = 0; i < this->table_size_; ++i)
if (!this->table_[i]->is_empty ())
@@ -711,8 +712,8 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::find_new_earliest (void)
// Returns the earliest node without removing it
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::get_first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>::get_first (void)
{
ACE_TRACE ("ACE_Timer_Hash_T::get_first");
@@ -722,23 +723,22 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::get_first (void)
return this->table_[this->earliest_position_]->get_first ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::free_node (ACE_Timer_Node_T<TYPE> *node)
+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 ()));
this->token_list_.add (h);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::dispatch_info_i (const ACE_Time_Value &cur_time,
+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>::dispatch_info_i (const ACE_Time_Value &cur_time,
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)
{
@@ -753,16 +753,16 @@ ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::dispatch_info_i (const ACE_Ti
// Dummy version of expire to get rid of warnings in Sun CC 4.2
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::expire ()
+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
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
-ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::expire (const ACE_Time_Value &cur_time)
+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 (const ACE_Time_Value &cur_time)
{
ACE_TRACE ("ACE_Timer_Hash_T::expire");
diff --git a/ACE/ace/Timer_Hash_T.h b/ACE/ace/Timer_Hash_T.h
index 53072ebd51c..8d9dbae6784 100644
--- a/ACE/ace/Timer_Hash_T.h
+++ b/ACE/ace/Timer_Hash_T.h
@@ -25,7 +25,7 @@
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declaration.
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY>
class ACE_Timer_Hash_T;
template <typename TYPE>
class Hash_Token;
@@ -40,6 +40,7 @@ class Hash_Token;
*/
template <class TYPE, class FUNCTOR, class ACE_LOCK>
class ACE_Timer_Hash_Upcall
+ : private ACE_Copy_Disabled
{
public:
typedef ACE_Timer_Queue_T<ACE_Event_Handler *,
@@ -103,10 +104,6 @@ public:
private:
/// Timer Queue to do the calling up to
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> *timer_hash_;
-
- // = Don't allow these operations for now.
- ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Hash_Upcall (const ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK> &))
- ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK> &))
};
/**
@@ -118,12 +115,15 @@ private:
* node of a timer queue. Be aware that it doesn't transverse
* in the order of timeout values.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-class ACE_Timer_Hash_Iterator_T : public ACE_Timer_Queue_Iterator_T <TYPE, FUNCTOR, ACE_LOCK>
+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>
{
public:
/// Constructor.
- ACE_Timer_Hash_Iterator_T (ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET> &);
+ typedef ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY> Hash;
+ ACE_Timer_Hash_Iterator_T (Hash &);
+
+ virtual ~ACE_Timer_Hash_Iterator_T ();
/// Positions the iterator at the earliest node in the Timer Queue
virtual void first (void);
@@ -139,13 +139,13 @@ public:
protected:
/// Pointer to the ACE_Timer_Hash that we are iterating over.
- ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET> &timer_hash_;
+ Hash & timer_hash_;
/// Current position in <timer_hash_>'s table
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_;
};
/**
@@ -156,21 +156,23 @@ protected:
*
* This implementation uses a hash table of BUCKETs. The hash
* is based on the time_value of the event. Unlike other Timer
- * Queues, ACE_Timer_Hash does not expire events in order.
+ * Queues, ACE_Timer_Hash does not expire events in strict order,
+ * i.e., all events are expired after their deadline. But two events
+ * may expired out of order as defined by their deadlines.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
-class ACE_Timer_Hash_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET, typename TIME_POLICY = ACE_Default_Time_Policy>
+class ACE_Timer_Hash_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>
{
public:
/// Type of iterator
- typedef ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>
+ typedef ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET, TIME_POLICY>
HASH_ITERATOR;
/// Iterator is a friend
- friend class ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>;
+ 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> INHERITED;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Timer_Queue;
// = Initialization and termination methods.
/**
@@ -181,7 +183,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 +193,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);
@@ -239,7 +244,7 @@ public:
/**
* Run the <functor> for all timers whose values are <=
- * <ACE_OS::gettimeofday>. Also accounts for <timer_skew>. Returns
+ * gettimeofday. Also accounts for <timer_skew>. Returns
* the number of timers canceled.
*/
virtual int expire (void);
@@ -252,7 +257,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 a0c9301ebc8..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,15 +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_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 47f4f501da3..c4395294b6d 100644
--- a/ACE/ace/Timer_Heap_T.cpp
+++ b/ACE/ace/Timer_Heap_T.cpp
@@ -39,34 +39,34 @@ ACE_HEAP_LCHILD (size_t X)
// Constructor that takes in an <ACE_Timer_Heap_T> to iterate over.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_Iterator_T (
- ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK> &heap)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Heap_Iterator_T (
+ Heap & heap)
: timer_heap_ (heap)
{
ACE_TRACE ("ACE_Timer_Heap_Iterator_T::ACE_Timer_Heap_Iterator");
this->first ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Heap_Iterator_T (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Heap_Iterator_T (void)
{
}
// Positions the iterator at the first node in the heap array
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
+ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::first (void)
{
this->position_ = 0;
}
// Positions the iterator at the next node in the heap array
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
+ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::next (void)
{
if (this->position_ != this->timer_heap_.cur_size_)
++this->position_;
@@ -74,16 +74,16 @@ ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
// Returns true the <position_> is at the end of the heap array
-template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
-ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
+ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::isdone (void) const
{
return this->position_ == this->timer_heap_.cur_size_;
}
// Returns the node at the current position in the heap or 0 if at the end
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::item (void)
{
if (this->position_ != this->timer_heap_.cur_size_)
return this->timer_heap_.heap_[this->position_];
@@ -95,13 +95,16 @@ ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
// Since timer IDs are assigned by first incrementing the timer_ids_curr_
// value, the first ID assigned will be 1 (just as in the previous design).
// When it's time to wrap, the next ID given out will be 0.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Heap_T (
size_t size,
bool preallocated,
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_Time_Policy (upcall_functor,
+ freelist,
+ time_policy),
max_size_ (size),
cur_size_ (0),
cur_limbo_ (0),
@@ -162,11 +165,14 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (
// Since timer IDs are assigned by first incrementing the timer_ids_curr_
// value, the first ID assigned will be 1 (just as in the previous design).
// When it's time to wrap, the next ID given out will be 0.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+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)
- : 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_Time_Policy (upcall_functor,
+ freelist,
+ time_policy),
max_size_ (ACE_DEFAULT_TIMERS),
cur_size_ (0),
cur_limbo_ (0),
@@ -199,8 +205,8 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (
HEAP_ITERATOR (*this));
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Heap_T (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Heap_T (void)
{
ACE_TRACE ("ACE_Timer_Heap_T::~ACE_Timer_Heap_T");
@@ -238,9 +244,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Heap_T (void)
}
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
long
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::pop_freelist (void)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::pop_freelist (void)
{
ACE_TRACE ("ACE_Timer_Heap_T::pop_freelist");
@@ -271,9 +277,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::pop_freelist (void)
return static_cast<long> (this->timer_ids_curr_);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::push_freelist (long old_id)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::push_freelist (long old_id)
{
ACE_TRACE ("ACE_Timer_Heap_T::push_freelist");
@@ -296,9 +302,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::push_freelist (long old_id)
return;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
long
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::timer_id (void)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::timer_id (void)
{
ACE_TRACE ("ACE_Timer_Heap_T::timer_id");
@@ -308,17 +314,17 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::timer_id (void)
// Checks if queue is empty.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
bool
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::is_empty (void) const
{
ACE_TRACE ("ACE_Timer_Heap_T::is_empty");
return this->cur_size_ == 0;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Queue_Iterator_T<TYPE> &
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
return *this->iterator_;
@@ -326,16 +332,16 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
// Returns earliest time in a non-empty queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> const ACE_Time_Value &
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::earliest_time (void) const
{
ACE_TRACE ("ACE_Timer_Heap_T::earliest_time");
return this->heap_[0]->get_timer_value ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Timer_Heap_T::dump");
@@ -371,9 +377,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
#endif /* ACE_HAS_DUMP */
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::copy (
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::copy (
size_t slot,
ACE_Timer_Node_T<TYPE> *moved_node)
{
@@ -392,9 +398,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::copy (
// this function must call either free_node (to reclaim the timer ID
// and the timer node memory, as well as decrement the size of the queue)
// or reschedule (to reinsert the node in the heap at a new time).
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::remove (size_t slot)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::remove (size_t slot)
{
ACE_Timer_Node_T<TYPE> *removed_node =
this->heap_[slot];
@@ -437,8 +443,8 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::remove (size_t slot)
return removed_node;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reheap_down (
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reheap_down (
ACE_Timer_Node_T<TYPE> *moved_node,
size_t slot,
size_t child)
@@ -471,9 +477,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reheap_down (
this->copy (slot, moved_node);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reheap_up (
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reheap_up (
ACE_Timer_Node_T<TYPE> *moved_node,
size_t slot,
size_t parent)
@@ -501,9 +507,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reheap_up (
moved_node);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::insert (
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::insert (
ACE_Timer_Node_T<TYPE> *new_node)
{
if (this->cur_size_ + this->cur_limbo_ + 2 >= this->max_size_)
@@ -515,9 +521,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::insert (
this->cur_size_++;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::grow_heap (void)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::grow_heap (void)
{
// All the containers will double in size from max_size_.
size_t new_size = this->max_size_ * 2;
@@ -597,9 +603,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::grow_heap (void)
// Reschedule a periodic timer. This function must be called with the
// mutex lock held.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reschedule (
ACE_Timer_Node_T<TYPE> *expired)
{
ACE_TRACE ("ACE_Timer_Heap_T::reschedule");
@@ -614,9 +620,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (
this->insert (expired);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::alloc_node (void)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::alloc_node (void)
{
ACE_Timer_Node_T<TYPE> *temp = 0;
@@ -640,9 +646,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::alloc_node (void)
return temp;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
void
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::free_node (
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::free_node (
ACE_Timer_Node_T<TYPE> *node)
{
// Return this timer id to the freelist.
@@ -661,9 +667,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::free_node (
// Insert a new timer that expires at time future_time; if interval is
// > 0, the handler will be reinvoked periodically.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
long
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (
const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
@@ -699,9 +705,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (
// Locate and remove the single timer with a value of @a timer_id from
// the timer queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
int
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (long timer_id,
const void **act,
int dont_call)
{
@@ -756,9 +762,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
// Locate and update the inteval on the timer_id
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
int
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reset_interval (long timer_id,
const ACE_Time_Value &interval)
{
ACE_TRACE ("ACE_Timer_Heap_T::reset_interval");
@@ -792,9 +798,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
// Locate and remove all values of @a type from the timer queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
int
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE &type,
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (const TYPE &type,
int dont_call)
{
ACE_TRACE ("ACE_Timer_Heap_T::cancel");
@@ -849,9 +855,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE &type,
// Returns the earliest node or returns 0 if the heap is empty.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T <TYPE> *
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::remove_first (void)
{
ACE_TRACE ("ACE_Timer_Heap_T::remove_first");
@@ -861,9 +867,9 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
return this->remove (0);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T <TYPE> *
-ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
+ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first (void)
{
ACE_TRACE ("ACE_Timer_Heap_T::get_first");
diff --git a/ACE/ace/Timer_Heap_T.h b/ACE/ace/Timer_Heap_T.h
index 00c128b1aa9..c1e4e83d368 100644
--- a/ACE/ace/Timer_Heap_T.h
+++ b/ACE/ace/Timer_Heap_T.h
@@ -26,7 +26,7 @@
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declaration
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
class ACE_Timer_Heap_T;
/**
@@ -38,15 +38,16 @@ class ACE_Timer_Heap_T;
* node of a timer queue. Be aware that it doesn't transverse
* in the order of timeout values.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-class ACE_Timer_Heap_Iterator_T : public ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>
+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>
{
public:
+ typedef ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Heap;
/// Constructor.
- ACE_Timer_Heap_Iterator_T (ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK> &);
+ ACE_Timer_Heap_Iterator_T (Heap &);
/// Destructor.
- ~ACE_Timer_Heap_Iterator_T (void);
+ virtual ~ACE_Timer_Heap_Iterator_T (void);
/// Positions the iterator at the earliest node in the Timer Queue
virtual void first (void);
@@ -62,7 +63,7 @@ public:
protected:
/// Pointer to the ACE_Timer_Heap that we are iterating over.
- ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK> &timer_heap_;
+ Heap & timer_heap_;
/// Position in the array where the iterator is at
size_t position_;
@@ -82,14 +83,14 @@ protected:
* dynamic memory allocation, which is important for real-time
* systems.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-class ACE_Timer_Heap_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
+class ACE_Timer_Heap_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>
{
public:
- typedef ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> HEAP_ITERATOR;
- friend class ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>;
+ 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> INHERITED;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Time_Policy;
// = Initialization and termination methods.
/**
@@ -109,7 +110,8 @@ public:
ACE_Timer_Heap_T (size_t size,
bool preallocated = false,
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. @c upcall_functor is the instance of the
@@ -119,7 +121,8 @@ public:
* size will be ACE_DEFAULT_TIMERS and there will be no preallocation.
*/
ACE_Timer_Heap_T (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());
/// Destructor.
virtual ~ACE_Timer_Heap_T (void);
@@ -163,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
@@ -318,10 +321,6 @@ private:
/// Set of pointers to the arrays of preallocated timer nodes.
/// Used to delete the allocated memory when required.
ACE_Unbounded_Set<ACE_Timer_Node_T<TYPE> *> preallocated_node_set_;
-
- // = Don't allow these operations for now.
- ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Heap_T (const ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK> &))
- ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK> &))
};
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_List.h b/ACE/ace/Timer_List.h
index 686aa63804b..0173b2ed2f8 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
@@ -26,13 +27,14 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// The following typedefs are here for ease of use and backward
// 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_SYNCH_RECURSIVE_MUTEX>
+ ACE_Event_Handler_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX,
+ ACE_Default_Time_Policy>
ACE_Timer_List_Iterator;
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_List_T.cpp b/ACE/ace/Timer_List_T.cpp
index 519a2080cd8..a6fa64601c7 100644
--- a/ACE/ace/Timer_List_T.cpp
+++ b/ACE/ace/Timer_List_T.cpp
@@ -15,30 +15,30 @@
// Default Constructor
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_List_Iterator_T (List& lst)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_List_Iterator_T (List& lst)
: list_ (lst)
{
this->first();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_List_Iterator_T (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_List_Iterator_T (void)
{
}
// Positions the iterator at the node right after the dummy node
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::first (void)
{
this->current_node_ = this->list_.get_first();
}
// Positions the iterator at the next node in the Timer Queue
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::next (void)
{
// Make sure that if we are at the end, we don't wrap around
if (! this->isdone())
@@ -49,16 +49,16 @@ ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
// Returns true when we are at <head_>
-template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
-ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
+ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::isdone (void) const
{
return this->current_node_ == 0;
}
// Returns the node at <position_> or 0 if we are at the end
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::item (void)
{
if (! this->isdone())
return this->current_node_;
@@ -70,8 +70,8 @@ ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
// Return our instance of the iterator
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
+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 ();
return *this->iterator_;
@@ -79,9 +79,11 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
// Create an empty list.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_List_T (FUNCTOR* uf, FreeList* fl)
- : Base(uf, fl)
+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,
+ TIME_POLICY const & time_policy)
+ : Base_Timer_Queue (uf, fl, time_policy)
, head_ (new ACE_Timer_Node_T<TYPE>)
, id_counter_ (0)
{
@@ -96,8 +98,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_List_T (FUNCTOR* uf, FreeLi
// Checks if list is empty.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::is_empty (void) const
{
ACE_TRACE ("ACE_Timer_List_T::is_empty");
return this->get_first_i() == 0;
@@ -106,8 +108,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
// Returns earliest time in a non-empty list.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> const ACE_Time_Value &
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::earliest_time (void) const
{
ACE_TRACE ("ACE_Timer_List_T::earliest_time");
ACE_Timer_Node_T<TYPE>* first = this->get_first_i();
@@ -119,8 +121,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
// Remove all remaining items in the list.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_List_T (void)
+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 (void)
{
ACE_TRACE ("ACE_Timer_List_T::~ACE_Timer_List_T");
ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
@@ -150,8 +152,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_List_T (void)
delete this->head_;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Timer_List_T::dump");
@@ -175,8 +177,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
// Reschedule a periodic timer. This function must be called with the
// lock held.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>* n)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reschedule (ACE_Timer_Node_T<TYPE>* n)
{
ACE_TRACE ("ACE_Timer_List_T::reschedule");
this->schedule_i(n, n->get_timer_value());
@@ -186,8 +188,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>* n
// Insert a new handler that expires at time future_time; if interval
// is > 0, the handler will be reinvoked periodically.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> long
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE &type,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> long
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
const ACE_Time_Value &interval)
@@ -213,8 +215,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE &type,
}
/// The shared scheduling functionality between schedule() and reschedule()
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (ACE_Timer_Node_T<TYPE>* n,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (ACE_Timer_Node_T<TYPE>* n,
const ACE_Time_Value& expire)
{
if (this->is_empty()) {
@@ -240,9 +242,9 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (ACE_Timer_Node_T<TYPE>* n
p->set_next(n);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE>*
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::find_node (long timer_id) const
{
ACE_Timer_Node_T<TYPE>* n = this->get_first_i();
if (n == 0)
@@ -257,8 +259,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
}
// Locate and update the inteval on the timer_id
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reset_interval (long timer_id,
const ACE_Time_Value &interval)
{
ACE_TRACE ("ACE_Timer_List_T::reset_interval");
@@ -273,8 +275,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
// Locate and remove the single <ACE_Event_Handler> with a value of
// @a timer_id from the timer queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (long timer_id,
const void **act,
int skip_close)
{
@@ -310,8 +312,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
}
// Locate and remove all values of <handler> from the timer queue.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE &type, int skip_close)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (const TYPE &type, int skip_close)
{
ACE_TRACE ("ACE_Timer_List_T::cancel");
@@ -365,8 +367,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE &type, int skip_cl
return num_canceled;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::unlink (ACE_Timer_Node_T<TYPE>* n)
{
n->get_prev()->set_next(n->get_next());
n->get_next()->set_prev(n->get_prev());
@@ -375,23 +377,23 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
}
/// Shared subset of the two cancel() methods.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
{
this->unlink (n);
this->free_node (n);
}
// Reads the first node on the list and returns it.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first (void)
{
ACE_TRACE ("ACE_Timer_List_T::get_first");
return this->get_first_i();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first_i (void) const
{
ACE_TRACE ("ACE_Timer_List_T::get_first_i");
ACE_Timer_Node_T<TYPE>* first = this->head_->get_next();
@@ -403,8 +405,8 @@ ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
// Removes the first node on the list and returns it.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::remove_first (void)
{
ACE_TRACE ("ACE_Timer_List_T::remove_first");
ACE_Timer_Node_T<TYPE>* first = this->get_first();
diff --git a/ACE/ace/Timer_List_T.h b/ACE/ace/Timer_List_T.h
index d4ec800340e..8b387c04725 100644
--- a/ACE/ace/Timer_List_T.h
+++ b/ACE/ace/Timer_List_T.h
@@ -21,7 +21,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
// Forward declaration.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
class ACE_Timer_List_T;
/**
@@ -32,12 +32,12 @@ 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>
+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> List;
+ typedef ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> List;
/// Constructor.
ACE_Timer_List_Iterator_T (List& lst);
@@ -81,19 +81,19 @@ protected:
* ACE_Timer_Heap will perform substantially faster than the
* ACE_Timer_List.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-class ACE_Timer_List_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
+class ACE_Timer_List_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>
{
public:
/// Type of iterator
- typedef ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> Iterator;
+ typedef ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Iterator;
/// Iterator is a friend
- friend class ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>;
+ friend class ACE_Timer_List_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> 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 fe6be3f4adc..6c887c0ed03 100644
--- a/ACE/ace/Timer_Queue_Adapters.cpp
+++ b/ACE/ace/Timer_Queue_Adapters.cpp
@@ -264,8 +264,10 @@ ACE_Thread_Timer_Queue_Adapter<TQ, TYPE>::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_earl = this->timer_queue_->earliest_time ();
+ ACE_Time_Value const tv_curr =
+ this->timer_queue_->gettimeofday ();
+ 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 f7d8f00675e..86f96bbeb95 100644
--- a/ACE/ace/Timer_Queue_T.cpp
+++ b/ACE/ace/Timer_Queue_T.cpp
@@ -16,11 +16,11 @@
#include "ace/Timer_Queue_T.h"
#include "ace/Guard_T.h"
-#include "ace/Log_Msg.h"
-#include "ace/Reactor_Timer_Interface.h"
#include "ace/Reverse_Lock_T.h"
+#include "ace/Log_Msg.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"
@@ -35,46 +35,41 @@ 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()
{
+ return this->gettimeofday_static();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Time_Value *
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::calculate_timeout (ACE_Time_Value *max_wait_time)
{
ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout");
ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, max_wait_time));
@@ -84,7 +79,7 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *m
return max_wait_time;
else
{
- ACE_Time_Value const cur_time = this->gettimeofday ();
+ ACE_Time_Value const cur_time = this->gettimeofday_static ();
if (this->earliest_time () > cur_time)
{
@@ -110,8 +105,8 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *m
}
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Time_Value *
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::calculate_timeout (ACE_Time_Value *max_wait_time,
ACE_Time_Value *the_timeout)
{
ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout");
@@ -129,7 +124,7 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *m
}
else
{
- ACE_Time_Value cur_time = this->gettimeofday ();
+ ACE_Time_Value cur_time = this->gettimeofday_static ();
if (this->earliest_time () > cur_time)
{
@@ -153,8 +148,16 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *m
return the_timeout;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
+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_static ();
+ 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
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Timer_Queue_T::dump");
@@ -165,11 +168,12 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
#endif /* ACE_HAS_DUMP */
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_T (FUNCTOR *upcall_functor,
- ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
- : gettimeofday_ (ACE_OS::gettimeofday),
- delete_upcall_functor_ (upcall_functor == 0),
+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)
+ : 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,47 +184,38 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_T (FUNCTOR *upcall_f
(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>
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Queue_T (void)
+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 (void)
{
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_;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::alloc_node (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::alloc_node (void)
{
return this->free_list_->remove ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::free_node (ACE_Timer_Node_T<TYPE> *node)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::free_node (ACE_Timer_Node_T<TYPE> *node)
{
this->free_list_->add (node);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_LOCK &
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::mutex (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_LOCK &
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::mutex (void)
{
return this->mutex_;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> long
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::schedule (const TYPE &type,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> long
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule (const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
const ACE_Time_Value &interval)
@@ -249,8 +244,8 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::schedule (const TYPE &type,
// Run the <handle_timeout> method for all Timers whose values are <=
// <cur_time>.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value &cur_time)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::expire (const ACE_Time_Value &cur_time)
{
ACE_TRACE ("ACE_Timer_Queue_T::expire");
ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
@@ -287,8 +282,8 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value &cur_ti
return number_of_timers_expired;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::recompute_next_abs_interval_time
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::recompute_next_abs_interval_time
(ACE_Timer_Node_T<TYPE> *expired,
const ACE_Time_Value &cur_time)
{
@@ -347,8 +342,52 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::recompute_next_abs_interval_time
}
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info_i (const ACE_Time_Value &cur_time,
+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_Timer_Node_Dispatch_Info_T<TYPE> info;
+ ACE_Time_Value cur_time;
+ {
+ // Create a scope for the lock ...
+ ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
+
+ if (this->is_empty ())
+ return 0;
+
+ // Get the current time
+ cur_time = this->gettimeofday_static () + this->timer_skew ();
+
+ // Look for a node in the timer queue whose timer <= the present
+ // time.
+ if (!this->dispatch_info_i (cur_time, info))
+ {
+ return 0;
+ }
+ }
+ // We do not need the lock anymore, all these operations take place
+ // with local variables.
+ 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;
+}
+
+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)
{
ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info_i");
@@ -388,155 +427,13 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info_i (const ACE_Time_Valu
return 0;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::return_node (ACE_Timer_Node_T<TYPE> *node)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::return_node (ACE_Timer_Node_T<TYPE> *node)
{
ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
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 4ed6fd4a30f..c5d2a488329 100644
--- a/ACE/ace/Timer_Queue_T.h
+++ b/ACE/ace/Timer_Queue_T.h
@@ -16,182 +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_;
};
/**
@@ -203,13 +69,11 @@ public:
* implementing specialized policies such as ACE_Timer_List
* and ACE_Timer_Heap.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
class ACE_Timer_Queue_T
+ : 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
@@ -218,78 +82,31 @@ public:
* timer nodes. If 0, then a default freelist will be created.
*/
ACE_Timer_Queue_T (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());
/// Destructor - make virtual for proper destruction of inherited
/// classes.
virtual ~ACE_Timer_Queue_T (void);
- /// True if queue is empty, else false.
- virtual bool is_empty (void) const = 0;
-
- /// Returns the time of the earlier node in the Timer_Queue. Must
- /// be called on a non-empty queue.
- virtual const ACE_Time_Value &earliest_time (void) const = 0;
-
/**
- * Schedule @a type that will expire at @a future_time, which is
- * specified in absolute time. If it expires then @a act is passed
- * in as the value to the <functor>. If @a interval is != to
- * ACE_Time_Value::zero then it is used to reschedule the @a type
- * automatically, using relative time to the current <gettimeofday>.
- * This method returns a <timer_id> that uniquely identifies the the
- * @a type entry in an internal list. This <timer_id> can be used to
- * cancel the timer before it expires. The cancellation ensures
- * that <timer_ids> are unique up to values of greater than 2
- * billion timers. As long as timers don't stay around longer than
- * this there should be no problems with accidentally deleting the
- * wrong timer. Returns -1 on failure (which is guaranteed never to
- * be a valid <timer_id>).
+ * Implement ACE_Abstract_Timer_Queue<TYPE>::schedule () with the right
+ * locking strategy.
*/
virtual long schedule (const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
const ACE_Time_Value &interval = ACE_Time_Value::zero);
+ //@{
/**
- * Resets the interval of the timer represented by @a timer_id to
- * @a interval, which is specified in relative time to the current
- * <gettimeofday>. If @a interval is equal to
- * ACE_Time_Value::zero, the timer will become a non-rescheduling
- * timer. Returns 0 if successful, -1 if not.
- */
- virtual int reset_interval (long timer_id,
- const ACE_Time_Value &interval) = 0;
-
- /**
- * Cancel all timer associated with @a type. If
- * @a dont_call_handle_close is 0 then the <functor> will be invoked,
- * which typically invokes the <handle_close> hook. Returns number
- * of timers cancelled.
- */
- virtual int cancel (const TYPE &type,
- int dont_call_handle_close = 1) = 0;
-
- /**
- * Cancel the single timer that matches the @a timer_id value (which
- * was returned from the <schedule> method). If act is non-NULL
- * then it will be set to point to the ``magic cookie'' argument
- * passed in when the timer was registered. This makes it possible
- * to free up the memory and avoid memory leaks. If
- * @a dont_call_handle_close is 0 then the <functor> will be invoked,
- * which typically calls the <handle_close> hook. Returns 1 if
- * cancellation succeeded and 0 if the @a timer_id wasn't found.
- */
- virtual int cancel (long timer_id,
- const void **act = 0,
- int dont_call_handle_close = 1) = 0;
-
- /**
- * Run the <functor> for all timers whose values are <= @a current_time.
- * This does not account for <timer_skew>. Returns the number of
- * timers canceled.
+ * Implement ACE_Abstract_Timer_Queue<TYPE>::expire () with the right
+ * locking strategy.
*/
virtual int expire (const ACE_Time_Value &current_time);
+ virtual int expire (void);
+ virtual int expire_single(ACE_Command_Base & pre_dispatch_command);
+ //@}
/**
* Get the dispatch information for a timer whose value is <= @a current_time.
@@ -300,73 +117,36 @@ 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
*/
- /* virtual */ ACE_Time_Value gettimeofday (void);
+ virtual ACE_Time_Value gettimeofday (void);
+ //@}
+
+ /// Implement an inlined, 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_static();
/// Allows applications to control how the timer queue gets the time
/// of day.
- void gettimeofday (ACE_Time_Value (*gettimeofday)(void));
+ 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);
@@ -377,21 +157,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> *);
@@ -442,14 +210,8 @@ protected:
/// Class that implements a free list
ACE_Free_List<ACE_Timer_Node_T<TYPE> > *free_list_;
- /// Pointer to function that returns the current time of day.
- ACE_Time_Value (*gettimeofday_)(void);
-
- /// Upcall functor
- FUNCTOR *upcall_functor_;
-
- /// To delete or not to delete is the question?
- bool const delete_upcall_functor_;
+ /// The policy to return the current time of day
+ TIME_POLICY time_policy_;
/// Flag to delete only if the class created the <free_list_>
bool const delete_free_list_;
@@ -461,91 +223,6 @@ private:
/// Adjusts for timer skew in various clocks.
ACE_Time_Value timer_skew_;
-
- // = Don't allow these operations for now.
- ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Queue_T (const ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> &))
- ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> &))
-};
-
-/**
- * @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
diff --git a/ACE/ace/Timer_Queue_T.inl b/ACE/ace/Timer_Queue_T.inl
index 7275119e2e1..94fdd42d382 100644
--- a/ACE/ace/Timer_Queue_T.inl
+++ b/ACE/ace/Timer_Queue_T.inl
@@ -4,157 +4,35 @@
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> ACE_INLINE void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::timer_skew (const ACE_Time_Value &skew)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::timer_skew (const ACE_Time_Value &skew)
{
timer_skew_ = skew;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE const ACE_Time_Value &
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::timer_skew (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE const ACE_Time_Value &
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::timer_skew (void) const
{
return timer_skew_;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE int
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE int
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::expire (void)
{
if (!this->is_empty ())
- return this->expire (this->gettimeofday () + timer_skew_);
+ return this->expire (this->gettimeofday_static () + timer_skew_);
else
return 0;
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info (const ACE_Time_Value &cur_time,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dispatch_info (const ACE_Time_Value &cur_time,
ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
{
ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info");
@@ -163,8 +41,8 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info (const ACE_Time_Value
return this->dispatch_info_i (cur_time, info);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::upcall (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::upcall (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
const ACE_Time_Value &cur_time)
{
this->upcall_functor ().timeout (*this,
@@ -174,8 +52,8 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::upcall (ACE_Timer_Node_Dispatch_Info
cur_time);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::preinvoke (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::preinvoke (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
const ACE_Time_Value &cur_time,
const void *&upcall_act)
{
@@ -187,8 +65,8 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::preinvoke (ACE_Timer_Node_Dispatch_I
upcall_act);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::postinvoke (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::postinvoke (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
const ACE_Time_Value &cur_time,
const void *upcall_act)
{
@@ -200,23 +78,17 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::postinvoke (ACE_Timer_Node_Dispatch_
upcall_act);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE ACE_Time_Value
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::gettimeofday (void)
-{
- // Invoke gettimeofday via pointer to function.
- return this->gettimeofday_ ();
-}
-
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE void
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::gettimeofday (ACE_Time_Value (*gettimeofday)(void))
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE ACE_Time_Value
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::gettimeofday_static (void)
{
- this->gettimeofday_ = gettimeofday;
+ // Get the current time according to the time policy.
+ return this->time_policy_ ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_INLINE FUNCTOR &
-ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::upcall_functor (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
+ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::set_time_policy (TIME_POLICY const & rhs)
{
- return *this->upcall_functor_;
+ this->time_policy_ = rhs;
}
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Queuefwd.h b/ACE/ace/Timer_Queuefwd.h
index 6e03204bdde..af1b844d84d 100644
--- a/ACE/ace/Timer_Queuefwd.h
+++ b/ACE/ace/Timer_Queuefwd.h
@@ -17,19 +17,13 @@
#include /**/ "ace/pre.h"
-#include "ace/Synch_Traits.h"
+#include "ace/config-all.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-template <class TYPE, class FUNCTOR, class ACE_LOCK> class ACE_Timer_Queue_T;
-template <class ACE_LOCK> class ACE_Event_Handler_Handle_Timeout_Upcall;
-
class ACE_Event_Handler;
-
-typedef ACE_Timer_Queue_T<ACE_Event_Handler *,
- ACE_Event_Handler_Handle_Timeout_Upcall<ACE_SYNCH_RECURSIVE_MUTEX>,
- ACE_SYNCH_RECURSIVE_MUTEX>
- ACE_Timer_Queue;
+template <class TYPE> class ACE_Abstract_Timer_Queue;
+typedef ACE_Abstract_Timer_Queue<ACE_Event_Handler*> ACE_Timer_Queue;
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Wheel.h b/ACE/ace/Timer_Wheel.h
index 307e56b5542..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,13 +28,14 @@ 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_SYNCH_RECURSIVE_MUTEX>
+ ACE_Event_Handler_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX,
+ ACE_Default_Time_Policy>
ACE_Timer_Wheel_Iterator;
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/Timer_Wheel_T.cpp b/ACE/ace/Timer_Wheel_T.cpp
index d7734e6b120..d99cf1b8225 100644
--- a/ACE/ace/Timer_Wheel_T.cpp
+++ b/ACE/ace/Timer_Wheel_T.cpp
@@ -41,12 +41,13 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
* @param upcall_functor A pointer to a functor to use instead of the default
* @param freelist A pointer to a freelist to use instead of the default
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+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)
+ : Base_Timer_Queue (upcall_functor, freelist, time_policy)
, spokes_(0)
, spoke_count_(0) // calculated in open_i
, spoke_bits_(0)
@@ -71,14 +72,15 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
* @param upcall_functor A pointer to a functor to use instead of the default
* @param freelist A pointer to a freelist to use instead of the default
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_Wheel_T
(u_int spoke_count,
u_int resolution,
size_t prealloc,
FUNCTOR* upcall_functor,
- FreeList* freelist)
-: Base (upcall_functor, freelist)
+ FreeList* freelist,
+ TIME_POLICY const & time_policy)
+: Base_Timer_Queue (upcall_functor, freelist, time_policy)
, spokes_ (0)
, spoke_count_ (0) // calculated in open_i
, spoke_bits_ (0)
@@ -91,8 +93,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
this->open_i (prealloc, spoke_count, resolution);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::power2bits (int n,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::power2bits (int n,
int min_bits,
int max_bits)
{
@@ -127,14 +129,12 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::power2bits (int n,
* Initialize the queue. Uses the established members for all needed
* information.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::open_i
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::open_i
(size_t prealloc, u_int spokes, u_int res)
{
ACE_TRACE ("ACE_Timer_Wheel_T::open_i");
- this->gettimeofday (ACE_OS::gettimeofday);
-
// Rather than waste bits in our timer id, we might as well round up
// the spoke count to the next power of two - 1 . (i.e 1,3,7,15,...127,etc.)
const int MIN_SPOKE_BITS = 3; // Allow between 8 and 4096 spokes
@@ -164,8 +164,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::open_i
}
/// Destructor just cleans up its memory
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Wheel_T (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_Wheel_T (void)
{
ACE_TRACE ("ACE_Timer_Wheel_T::~ACE_Timer_Wheel_T");
@@ -190,9 +190,9 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Wheel_T (void)
}
/// Searches for a node by timer_id within one spoke.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE>*
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_spoke_node
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::find_spoke_node
(u_int spoke, long timer_id) const
{
ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
@@ -208,9 +208,9 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_spoke_node
/// Searches all spokes for a node matching the specified timer_id
/// Uses the spoke encoded in the timer_id as a starting place.
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE>*
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::find_node (long timer_id) const
{
if (timer_id == -1)
return 0;
@@ -244,8 +244,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
*
* @return True if empty
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::is_empty (void) const
{
ACE_TRACE ("ACE_Timer_Wheel_T::is_empty");
return timer_count_ == 0;
@@ -255,8 +255,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
/**
* @return First (earliest) node in the wheel_'s earliest_spoke_ list
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> const ACE_Time_Value &
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::earliest_time (void) const
{
ACE_TRACE ("ACE_Timer_Wheel_T::earliest_time");
ACE_Timer_Node_T<TYPE>* n = this->get_first_i ();
@@ -268,8 +268,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
/// Uses a simple hash to find which spoke to use based on when the
/// timer is due to expire. Hopefully the 64bit int operations avoid
/// any overflow problems.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> u_int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_spoke
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> u_int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::calculate_spoke
(const ACE_Time_Value& t) const
{
return static_cast<u_int> ((t.msec () >> this->res_bits_) & (this->spoke_count_ - 1));
@@ -280,8 +280,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_spoke
/// have to do exhaustive searches within the spoke to ensure that a particular
/// timer id is not already in use. Some optimizations are in place so
/// that this hopefully doesn't have to happen often.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> long
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::generate_timer_id (u_int spoke)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> long
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::generate_timer_id (u_int spoke)
{
int cnt_bits = sizeof (long) * 8 - this->spoke_bits_;
@@ -382,8 +382,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::generate_timer_id (u_int spoke)
* @return Unique identifier (can be used to cancel the timer).
* -1 on failure.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> long
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE& type,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> long
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (const TYPE& type,
const void* act,
const ACE_Time_Value& future_time,
const ACE_Time_Value& interval)
@@ -418,8 +418,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE& type,
*
* @param n The timer node to reschedule
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>* n)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reschedule (ACE_Timer_Node_T<TYPE>* n)
{
ACE_TRACE ("ACE_Timer_Wheel_T::reschedule");
const ACE_Time_Value& expire = n->get_timer_value ();
@@ -428,8 +428,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>*
}
/// The shared scheduling functionality between schedule() and reschedule()
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i
(ACE_Timer_Node_T<TYPE>* n,
u_int spoke,
const ACE_Time_Value& expire)
@@ -476,8 +476,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i
*
* @return 0 if successful, -1 if no.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reset_interval (long timer_id,
const ACE_Time_Value &interval
)
{
@@ -506,8 +506,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
*
* @return Number of timers cancelled
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE& type, int skip_close)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (const TYPE& type, int skip_close)
{
ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
@@ -589,8 +589,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE& type, int skip_c
* @return 1 for sucess and 0 if the timer_id wasn't found (or was
* found to be invalid)
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (long timer_id,
const void **act,
int skip_close)
{
@@ -631,8 +631,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
}
/// Shared subset of the two cancel() methods.
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
{
this->unlink (n);
this->free_node (n);
@@ -644,8 +644,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
/// determined from their expiration time.
/// The last time is always passed in, even though you can often calculate
/// it as get_first()->get_timer_value().
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::recalc_earliest
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::recalc_earliest
(const ACE_Time_Value& last)
{
// This is possible because we use a count for is_empty()
@@ -687,8 +687,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::recalc_earliest
* Dumps out the size of the wheel, the resolution, and the contents
* of the wheel.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Timer_Wheel_T::dump");
@@ -723,15 +723,15 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
*
* @return The earliest timer node.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::remove_first (void)
{
ACE_TRACE ("ACE_Timer_Wheel_T::remove_first");
return remove_first_expired (ACE_Time_Value::max_time);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::unlink (ACE_Timer_Node_T<TYPE>* n)
{
ACE_TRACE ("ACE_Timer_Wheel_T::unlink");
--timer_count_;
@@ -741,8 +741,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
n->set_next (0);
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first_expired (const ACE_Time_Value& now)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::remove_first_expired (const ACE_Time_Value& now)
{
ACE_Timer_Node_T<TYPE>* n = this->get_first ();
if (n != 0 && n->get_timer_value() <= now)
@@ -759,17 +759,17 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first_expired (const ACE_Time
*
* @return The earliest timer node.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE>*
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first (void)
{
ACE_TRACE ("ACE_Timer_Wheel_T::get_first");
return this->get_first_i ();
}
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
ACE_Timer_Node_T<TYPE>*
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first_i (void) const
{
ACE_Timer_Node_T<TYPE>* root = this->spokes_[this->earliest_spoke_];
ACE_Timer_Node_T<TYPE>* first = root->get_next ();
@@ -782,9 +782,9 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
/**
* @return The iterator
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>&
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Queue_Iterator_T<TYPE> &
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter (void)
{
this->iterator_->first ();
return *this->iterator_;
@@ -794,8 +794,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
* Dummy version of expire to get rid of warnings in Sun CC 4.2
* Just call the expire of the base class.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire ()
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::expire ()
{
return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire ();
}
@@ -808,8 +808,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire ()
*
* @return Number of timers expired
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> int
-ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value& cur_time)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
+ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::expire (const ACE_Time_Value& cur_time)
{
ACE_TRACE ("ACE_Timer_Wheel_T::expire");
@@ -866,8 +866,8 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value& cur_ti
*
* @param wheel A reference for a timer queue to iterate over
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Wheel_Iterator_T<TYPE,FUNCTOR,ACE_LOCK>::ACE_Timer_Wheel_Iterator_T
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Wheel_Iterator_T<TYPE,FUNCTOR,ACE_LOCK,TIME_POLICY>::ACE_Timer_Wheel_Iterator_T
(Wheel& wheel)
: timer_wheel_ (wheel)
{
@@ -878,10 +878,8 @@ ACE_Timer_Wheel_Iterator_T<TYPE,FUNCTOR,ACE_LOCK>::ACE_Timer_Wheel_Iterator_T
/**
* Destructor, at this level does nothing.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-ACE_Timer_Wheel_Iterator_T<TYPE,
-FUNCTOR,
-ACE_LOCK>::~ACE_Timer_Wheel_Iterator_T (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
+ACE_Timer_Wheel_Iterator_T<TYPE,FUNCTOR,ACE_LOCK,TIME_POLICY>::~ACE_Timer_Wheel_Iterator_T (void)
{
}
@@ -894,8 +892,8 @@ ACE_LOCK>::~ACE_Timer_Wheel_Iterator_T (void)
* If the wheel is empty, spoke_ will be equal timer_wheel_.spoke_count_ and
* current_node_ would be 0.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::first (void)
{
this->goto_next(0);
}
@@ -904,8 +902,8 @@ ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
/**
* Positions the iterator at the next node.
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::next (void)
{
if (this->isdone())
return;
@@ -919,8 +917,8 @@ ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
}
/// Helper class for common functionality of next() and first()
-template <class TYPE, class FUNCTOR, class ACE_LOCK> void
-ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::goto_next (u_int start_spoke)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
+ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::goto_next (u_int start_spoke)
{
// Find the first non-empty entry.
u_int sc = this->timer_wheel_.spoke_count_;
@@ -943,8 +941,8 @@ ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::goto_next (u_int start_spok
/**
* @return True when we there aren't any more items (when current_node_ == 0)
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
-ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
+ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::isdone (void) const
{
return this->current_node_ == 0;
}
@@ -953,8 +951,8 @@ ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
* @return The node at the current spokeition in the sequence or 0 if the wheel
* is empty
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
-ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
+ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::item (void)
{
return this->current_node_;
}
diff --git a/ACE/ace/Timer_Wheel_T.h b/ACE/ace/Timer_Wheel_T.h
index 40179f7a734..ee758daa00f 100644
--- a/ACE/ace/Timer_Wheel_T.h
+++ b/ACE/ace/Timer_Wheel_T.h
@@ -15,6 +15,7 @@
#include /**/ "ace/pre.h"
#include "ace/Timer_Queue_T.h"
+#include "ace/Copy_Disabled.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -23,7 +24,7 @@
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declaration
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
class ACE_Timer_Wheel_T;
/**
@@ -35,19 +36,19 @@ 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>
+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> Wheel;
+ typedef ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Wheel;
typedef ACE_Timer_Node_T<TYPE> Node;
/// Constructor
ACE_Timer_Wheel_Iterator_T (Wheel &);
/// Destructor
- ~ACE_Timer_Wheel_Iterator_T (void);
+ virtual ~ACE_Timer_Wheel_Iterator_T (void);
/// Positions the iterator at the earliest node in the Timer Queue
virtual void first (void);
@@ -88,28 +89,31 @@ private:
* Timer Facilities"
* (http://dworkin.wustl.edu/~varghese/PAPERS/newbsd.ps.Z)
*/
-template <class TYPE, class FUNCTOR, class ACE_LOCK>
-class ACE_Timer_Wheel_T : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>
+template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY = ACE_Default_Time_Policy>
+class ACE_Timer_Wheel_T
+ : public ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>
{
public:
/// Type of iterator
- typedef ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> Iterator;
+ typedef ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Iterator;
/// Iterator is a friend
- friend class ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>;
+ 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> Base;
+ typedef ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY> Base_Timer_Queue;
typedef ACE_Free_List<Node> FreeList;
/// Default constructor
- ACE_Timer_Wheel_T (FUNCTOR* upcall_functor = 0, FreeList* freelist = 0);
+ ACE_Timer_Wheel_T (FUNCTOR* upcall_functor = 0, FreeList* freelist = 0,
+ TIME_POLICY const & time_policy = TIME_POLICY());
/// Constructor with opportunities to set the wheelsize and resolution
ACE_Timer_Wheel_T (u_int spoke_count,
u_int resolution,
size_t prealloc = 0,
FUNCTOR* upcall_functor = 0,
- FreeList* freelist = 0);
+ FreeList* freelist = 0,
+ TIME_POLICY const & time_policy = TIME_POLICY());
/// Destructor
virtual ~ACE_Timer_Wheel_T (void);
@@ -150,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);
@@ -205,11 +209,6 @@ private:
ACE_Time_Value wheel_time_;
/// The total number of timers currently scheduled.
u_int timer_count_;
-
- // = Don't allow these operations for now, don't split into multiple lines
- // breaks sun compilers
- ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Wheel_T (const ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK> &))
- ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK> &))
};
ACE_END_VERSIONED_NAMESPACE_DECL
diff --git a/ACE/ace/ace.mpc b/ACE/ace/ace.mpc
index 9bbca7bbc5f..b6e52c57480 100644
--- a/ACE/ace/ace.mpc
+++ b/ACE/ace/ace.mpc
@@ -48,7 +48,6 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Connection_Recycling_Strategy.cpp
Containers.cpp
Copy_Disabled.cpp
- Countdown_Time.cpp
Date_Time.cpp
DEV.cpp
DEV_Addr.cpp
@@ -63,6 +62,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
@@ -259,6 +259,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Thread_Mutex.cpp
Thread_Semaphore.cpp
Throughput_Stats.cpp
+ Time_Policy.cpp
Time_Value.cpp
Timeprobe.cpp
TLI.cpp
@@ -281,6 +282,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
}
Template_Files {
+ Abstract_Timer_Queue.cpp
Acceptor.cpp
Active_Map_Manager_T.cpp
ARGV.cpp
@@ -303,6 +305,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Condition_T.cpp
Connector.cpp
Containers_T.cpp
+ Countdown_Time_T.cpp
Dump_T.cpp
Dynamic_Service.cpp
Env_Value_T.cpp
@@ -353,10 +356,12 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Task_T.cpp
Test_and_Set.cpp
Timeprobe_T.cpp
+ Time_Policy_T.cpp
Timer_Hash_T.cpp
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
@@ -393,6 +398,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
CORBA_macros.h
Codeset_Symbols.h
Condition_T.h
+ Countdown_Time.h
Default_Constants.h
Global_Macros.h
Guard_T.h
diff --git a/ACE/examples/APG/Timers/Timers.cpp b/ACE/examples/APG/Timers/Timers.cpp
index 761f03a650c..fedc8867a90 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 () + 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 5d28cf5d88b..678b7b3e487 100644
--- a/ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h
+++ b/ACE/examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.h
@@ -27,11 +27,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/Reactor/Misc/test_timer_queue.cpp b/ACE/examples/Reactor/Misc/test_timer_queue.cpp
index 87190f43c7d..245949b2ac1 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"
diff --git a/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h b/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h
index f5e9f07d4f6..1583eaa5fe2 100644
--- a/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h
+++ b/ACE/examples/Timer_Queue/Thread_Timer_Queue_Test.h
@@ -30,11 +30,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 4d5aea82d7b..e00f901078d 100644
--- a/ACE/tests/Network_Adapters_Test.cpp
+++ b/ACE/tests/Network_Adapters_Test.cpp
@@ -28,6 +28,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"
@@ -1035,8 +1037,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 d27601bb3ce..86469c4dd40 100644
--- a/ACE/tests/Proactor_Timer_Test.cpp
+++ b/ACE/tests/Proactor_Timer_Test.cpp
@@ -25,10 +25,11 @@
// 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;
@@ -297,8 +298,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 f376b51c069..22dfc273b7b 100644
--- a/ACE/tests/Reactor_Timer_Test.cpp
+++ b/ACE/tests/Reactor_Timer_Test.cpp
@@ -23,6 +23,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"
@@ -246,8 +248,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 400a8711b1c..43bd43b0c73 100644
--- a/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
+++ b/ACE/tests/Timer_Queue_Reference_Counting_Test.cpp
@@ -263,38 +263,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
diff --git a/ACE/tests/Timer_Queue_Test.cpp b/ACE/tests/Timer_Queue_Test.cpp
index 209ea014356..be9514bc424 100644
--- a/ACE/tests/Timer_Queue_Test.cpp
+++ b/ACE/tests/Timer_Queue_Test.cpp
@@ -29,10 +29,12 @@
#include "ace/Timer_Wheel.h"
#include "ace/Timer_Hash.h"
#include "ace/Timer_Queue.h"
+#include "ace/Time_Policy.h"
#include "ace/Recursive_Thread_Mutex.h"
#include "ace/Null_Mutex.h"
#include "ace/OS_NS_unistd.h"
#include "ace/Containers_T.h"
+#include "ace/Event_Handler.h"
@@ -326,7 +328,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()
+ + ACE_Time_Value(0, i * TIMER_DISTANCE * 1000));
+ }
ACE_Time_Value last_time = times[max_iterations-1];
@@ -675,8 +680,10 @@ run_main (int argc, ACE_TCHAR *argv[])
// Timer_Heap without preallocated memory, using high-res time.
(void) ACE_High_Res_Timer::global_scale_factor ();
- ACE_Timer_Heap *tq_heap = new ACE_Timer_Heap;
- tq_heap->gettimeofday (&ACE_High_Res_Timer::gettimeofday_hr);
+
+ 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,
ACE_TEXT ("ACE_Timer_Heap (high-res timer)"),
diff --git a/TAO/ChangeLog.BRANCH b/TAO/ChangeLog.BRANCH
new file mode 100644
index 00000000000..0558c828de9
--- /dev/null
+++ b/TAO/ChangeLog.BRANCH
@@ -0,0 +1,130 @@
+ Thu Dec 08 15:34:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * tao/HR_Time_Policy_Strategy.h
+
+ Fixed class comment.
+
+ * tests/Time_Policy/main.cpp
+
+ Fixed comments.
+
+ * tests/Time_Policy_Custom/Custom_Time_Policy.mpc
+ * tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.cpp
+ * tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.h
+ * tests/Time_Policy_Custom/TPTest_Export.h
+ * tests/Time_Policy_Custom/custom_time.conf
+ * tests/Time_Policy_Custom/custom_time.conf.xml
+ * tests/Time_Policy_Custom/main.cpp
+ * tests/Time_Policy_Custom/run_test.pl
+ * tests/Time_Policy_Custom/run_test_dyn.pl
+ * bin/tao_orb_tests.lst
+
+ Added new tests for custom TAO Time policy support.
+
+ Thu Dec 08 12:00:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * tao/Time_Policy_Manager.cpp
+ * tao/default_resource.cpp
+
+ Logging improvements.
+
+ * tests/Time_Policy/Time_Policy.mpc
+ * tests/Time_Policy/hr_time.conf
+ * tests/Time_Policy/hr_time.conf.xml
+ * tests/Time_Policy/main.cpp
+ * tests/Time_Policy/run_test.pl
+ * tests/Time_Policy/run_test_hr.pl
+ * bin/tao_orb_tests.lst
+
+ Added new tests for TAO Time policy support.
+
+ Wed Dec 07 12:34:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * tao/TAO_Internal.cpp:
+
+ Added loading HR_Time_Policy_Strategy static service.
+
+ * tao/Time_Policy_Manager.cpp:
+
+ Improved error reporting.
+
+ Wed Dec 07 11:20:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * tao/default_resource.cpp:
+ * tao/default_resource.h;
+ * tao/default_resource.inl:
+
+ Improved protection for dynamically allocated
+ timer queues.
+
+ * tao/Strategies/advanced_resource.cpp:
+
+ Added support for ORB time policies.
+
+ Tue Dec 06 15:45:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * tao/HR_Time_Policy_Strategy.h:
+ * tao/Time_Policy_Manager.h:
+ * tao/Time_Policy_Strategy.h:
+
+ Fixed potential compile problems because of
+ #include placements.
+
+ Tue Dec 06 15:30:00 UTC 2011 Martin Corino <mcorino@remedy.nl>
+
+ * tao/ORB_Time_Policy.cpp:
+ * tao/ORB_Time_Policy.h:
+ * tao/ORB_Time_Policy.inl:
+
+ Added dynamic time policy and a
+ countdown template instantiation based
+ on that policy.
+
+ * tao/Block_Flushing_Strategy.cpp:
+ * tao/Leader_Follower.cpp:
+ * tao/LocateRequest_Invocation.cpp:
+ * tao/Profile_Transport_Resolver.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/Transport.cpp:
+ * tao/Wait_On_Reactor.cpp:
+ * tao/Wait_On_Read.cpp:
+
+ Replaced ACE_Countdown_Time by new ORB time
+ policy based countdown class.
+
+ * tao/Time_Policy_Manager.cpp:
+ * tao/Time_Policy_Manager.h:
+
+ Added ORB time policy manager service object
+ for managing dynamically configured ORB time
+ policy.
+
+ * tao/Time_Policy_Strategy.h:
+
+ Added base for loadable ORB time policies.
+
+ * tao/HR_Time_Policy_Strategy.cpp:
+ * tao/HR_Time_Policy_Strategy.h:
+
+ Added HR ORB time policy implementation.
+
+ * tao/default_resource.cpp:
+ * tao/default_resource.h:
+ * tao/TAO_Internal.cpp:
+
+ Added support for ORB time policies.
+
+ * tao/orbconf.h:
+
+ Added ACE_HAS_TIME_POLICY compile time configuration
+ to enable/disable ORB time policy support.
+
+ * tao/tao.mpc:
+
+ Added new files.
+
+Local Variables:
+mode: change-log
+add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time))
+indent-tabs-mode: nil
+End:
diff --git a/TAO/bin/tao_orb_tests.lst b/TAO/bin/tao_orb_tests.lst
index a2c2e659dab..5204dc10f22 100644
--- a/TAO/bin/tao_orb_tests.lst
+++ b/TAO/bin/tao_orb_tests.lst
@@ -329,6 +329,10 @@ TAO/tests/Policies/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST
TAO/tests/Timeout/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO
TAO/tests/MT_Timeout/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST !OpenVMS_IA64Crash
TAO/tests/Timed_Buffered_Oneways/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO
+TAO/tests/Time_Policy/run_test.pl:
+TAO/tests/Time_Policy/run_test_hr.pl:
+TAO/tests/Time_Policy_Custom/run_test.pl: !STATIC
+TAO/tests/Time_Policy_Custom/run_test_dyn.pl: !STATIC
TAO/tests/Single_Read/run_test.pl:
TAO/tests/Connection_Timeout/run_test.pl: !VxWorks !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ACE_FOR_TAO
#TAO/tests/Connection_Failure/run_test.pl ! Timesout for good reasons
diff --git a/TAO/tao/Block_Flushing_Strategy.cpp b/TAO/tao/Block_Flushing_Strategy.cpp
index da95bb25641..d6939825ffb 100644
--- a/TAO/tao/Block_Flushing_Strategy.cpp
+++ b/TAO/tao/Block_Flushing_Strategy.cpp
@@ -4,7 +4,7 @@
#include "tao/Transport.h"
#include "tao/Queued_Message.h"
#include "tao/Connection_Handler.h"
-#include "ace/Countdown_Time.h"
+#include "tao/ORB_Time_Policy.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -31,7 +31,7 @@ TAO_Block_Flushing_Strategy::call_handle_output (TAO_Transport *transport,
case TAO_Transport::DR_OK: return 0;
case TAO_Transport::DR_WOULDBLOCK:
{
- ACE_Countdown_Time counter (dc.timeout ());
+ TAO::ORB_Countdown_Time counter (dc.timeout ());
TAO_Connection_Handler &ch = *transport->connection_handler ();
if (ch.handle_write_ready (dc.timeout ()) == -1)
{
diff --git a/TAO/tao/HR_Time_Policy_Strategy.cpp b/TAO/tao/HR_Time_Policy_Strategy.cpp
new file mode 100644
index 00000000000..09c39930da8
--- /dev/null
+++ b/TAO/tao/HR_Time_Policy_Strategy.cpp
@@ -0,0 +1,55 @@
+// $Id$
+
+#include "tao/HR_Time_Policy_Strategy.h"
+
+#include "ace/Timer_Heap_T.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_Time_Policy_T<ACE_HR_Time_Policy> TAO_HR_Time_Policy_Strategy::time_policy_;
+
+TAO_HR_Time_Policy_Strategy::~TAO_HR_Time_Policy_Strategy ()
+{
+}
+
+ACE_Timer_Queue * TAO_HR_Time_Policy_Strategy::create_timer_queue (void)
+{
+ ACE_Timer_Queue * tmq = 0;
+
+ typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX,
+ ACE_HR_Time_Policy> timer_queue_type;
+ ACE_NEW_RETURN (tmq, timer_queue_type (), 0);
+
+ return tmq;
+}
+
+void
+TAO_HR_Time_Policy_Strategy::destroy_timer_queue (ACE_Timer_Queue *tmq)
+{
+ delete tmq;
+}
+
+ACE_Dynamic_Time_Policy_Base * TAO_HR_Time_Policy_Strategy::get_time_policy (void)
+{
+ return &time_policy_;
+}
+
+
+ACE_STATIC_SVC_DEFINE (TAO_HR_Time_Policy_Strategy,
+ ACE_TEXT ("TAO_HR_TIME_POLICY"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_HR_Time_Policy_Strategy),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (TAO, TAO_HR_Time_Policy_Strategy)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_TIME_POLICY */
diff --git a/TAO/tao/HR_Time_Policy_Strategy.h b/TAO/tao/HR_Time_Policy_Strategy.h
new file mode 100644
index 00000000000..f744bb509cb
--- /dev/null
+++ b/TAO/tao/HR_Time_Policy_Strategy.h
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file HR_Time_Policy_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+//=============================================================================
+
+#ifndef HR_TIME_POLICY_STRATEGY_H
+#define HR_TIME_POLICY_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "tao/TAO_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/orbconf.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+#include "tao/Time_Policy_Strategy.h"
+
+#include "ace/Time_Policy_T.h"
+#include "ace/Service_Config.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_HR_Time_Policy_Strategy
+ *
+ * @brief Time policy strategy providing Highres time.
+ *
+ */
+class TAO_Export TAO_HR_Time_Policy_Strategy
+ : public TAO_Time_Policy_Strategy
+{
+public:
+ virtual ~TAO_HR_Time_Policy_Strategy ();
+
+ virtual ACE_Timer_Queue * create_timer_queue (void);
+
+ virtual void destroy_timer_queue (ACE_Timer_Queue *tmq);
+
+ virtual ACE_Dynamic_Time_Policy_Base * get_time_policy (void);
+
+private:
+ static ACE_Time_Policy_T<ACE_HR_Time_Policy> time_policy_;
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO, TAO_HR_Time_Policy_Strategy)
+ACE_FACTORY_DECLARE (TAO, TAO_HR_Time_Policy_Strategy)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_TIME_POLICY */
+
+#include /**/ "ace/post.h"
+
+#endif /* HR_TIME_POLICY_STRATEGY_H */
diff --git a/TAO/tao/Leader_Follower.cpp b/TAO/tao/Leader_Follower.cpp
index 427374ee726..7a5d014efc7 100644
--- a/TAO/tao/Leader_Follower.cpp
+++ b/TAO/tao/Leader_Follower.cpp
@@ -1,6 +1,5 @@
// $Id$
-#include "ace/Countdown_Time.h"
#include "ace/OS_NS_sys_time.h"
#include "ace/Reactor.h"
#include "ace/Auto_Ptr.h"
@@ -13,6 +12,7 @@
#include "tao/Transport.h"
#include "tao/GUIResource_Factory.h"
#include "tao/ORB_Core.h"
+#include "tao/ORB_Time_Policy.h"
#if !defined (__ACE_INLINE__)
# include "tao/Leader_Follower.inl"
@@ -92,7 +92,7 @@ int
TAO_Leader_Follower::wait_for_client_leader_to_complete (ACE_Time_Value *max_wait_time)
{
int result = 0;
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
// Note that we are waiting.
++this->event_loop_threads_waiting_;
@@ -253,7 +253,7 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event,
// Obtain the lock.
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock (), -1);
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
// Optimize the first iteration [no access to errno]
int result = 1;
diff --git a/TAO/tao/LocateRequest_Invocation.cpp b/TAO/tao/LocateRequest_Invocation.cpp
index db8f26c7910..9b1a9768335 100644
--- a/TAO/tao/LocateRequest_Invocation.cpp
+++ b/TAO/tao/LocateRequest_Invocation.cpp
@@ -14,7 +14,7 @@
#include "tao/SystemException.h"
#include "ace/Intrusive_Auto_Ptr.h"
-#include "ace/Countdown_Time.h"
+#include "tao/ORB_Time_Policy.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -71,7 +71,7 @@ namespace TAO
Invocation_Status
LocateRequest_Invocation::invoke (ACE_Time_Value *max_wait_time)
{
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
TAO_Synch_Reply_Dispatcher *rd_p = 0;
ACE_NEW_NORETURN (rd_p, TAO_Synch_Reply_Dispatcher (this->resolver_.stub ()->orb_core (),
diff --git a/TAO/tao/ORB_Time_Policy.cpp b/TAO/tao/ORB_Time_Policy.cpp
new file mode 100644
index 00000000000..c73e15def94
--- /dev/null
+++ b/TAO/tao/ORB_Time_Policy.cpp
@@ -0,0 +1,32 @@
+// $Id$
+
+#include "tao/ORB_Time_Policy.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/ORB_Time_Policy.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ ACE_Time_Policy_T<ACE_Default_Time_Policy> ORB_Time_Policy::default_policy_;
+ ACE_Dynamic_Time_Policy_Base const * ORB_Time_Policy::active_policy_ = &ORB_Time_Policy::default_policy_;
+
+ void ORB_Time_Policy::set_time_policy (ACE_Dynamic_Time_Policy_Base const * pol)
+ {
+ if (pol != 0 )
+ {
+ active_policy_ = pol;
+ }
+ }
+
+ void ORB_Time_Policy::reset_time_policy (void)
+ {
+ active_policy_ = &default_policy_;
+ }
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/ORB_Time_Policy.h b/TAO/tao/ORB_Time_Policy.h
new file mode 100644
index 00000000000..8e60cee3506
--- /dev/null
+++ b/TAO/tao/ORB_Time_Policy.h
@@ -0,0 +1,68 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ORB_Time_Policy.h
+ *
+ * $Id$
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+//=============================================================================
+
+#ifndef ORB_TIME_POLICY_H
+#define ORB_TIME_POLICY_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "tao/TAO_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Versioned_Namespace.h"
+#include "ace/Time_Policy.h"
+#include "ace/Time_Policy_T.h"
+#include "ace/Countdown_Time_T.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ /**
+ * @class ORB_Time_Policy
+ *
+ * @brief Implement a time policy class which returns timer according
+ * to the active ORB time policy.
+ *
+ */
+ class TAO_Export ORB_Time_Policy
+ {
+ public:
+ /// Return the current time according to this policy
+ ACE_Time_Value operator() () const;
+
+ static void set_time_policy (ACE_Dynamic_Time_Policy_Base const * pol);
+ static void reset_time_policy (void);
+
+ private:
+ static ACE_Time_Policy_T<ACE_Default_Time_Policy> default_policy_;
+ static ACE_Dynamic_Time_Policy_Base const * active_policy_;
+ };
+
+ // Declare a countdown timer type based on ORB time policy
+ typedef ACE_Countdown_Time_T<ORB_Time_Policy> ORB_Countdown_Time;
+
+}; // TAO
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+# include "tao/ORB_Time_Policy.inl"
+#endif /* ! __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* ORB_TIME_POLICY_H */
diff --git a/TAO/tao/ORB_Time_Policy.inl b/TAO/tao/ORB_Time_Policy.inl
new file mode 100644
index 00000000000..1a87174c021
--- /dev/null
+++ b/TAO/tao/ORB_Time_Policy.inl
@@ -0,0 +1,18 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ ACE_INLINE ACE_Time_Value
+ ORB_Time_Policy::operator() () const
+ {
+ return (*active_policy_) ();
+ }
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Profile_Transport_Resolver.cpp b/TAO/tao/Profile_Transport_Resolver.cpp
index 5e1f92a1d85..1e74a539c96 100644
--- a/TAO/tao/Profile_Transport_Resolver.cpp
+++ b/TAO/tao/Profile_Transport_Resolver.cpp
@@ -18,7 +18,7 @@
#include "tao/SystemException.h"
#include "tao/Client_Strategy_Factory.h"
-#include "ace/Countdown_Time.h"
+#include "tao/ORB_Time_Policy.h"
#include "ace/CORBA_macros.h"
#if !defined (__ACE_INLINE__)
@@ -76,7 +76,7 @@ namespace TAO
void
Profile_Transport_Resolver::resolve (ACE_Time_Value *max_time_val)
{
- ACE_Countdown_Time countdown (max_time_val);
+ TAO::ORB_Countdown_Time countdown (max_time_val);
TAO_Invocation_Endpoint_Selector *es =
this->stub_->orb_core ()->endpoint_selector_factory ()->get_selector ();
diff --git a/TAO/tao/Strategies/advanced_resource.cpp b/TAO/tao/Strategies/advanced_resource.cpp
index 735321d25ed..a18de20b366 100644
--- a/TAO/tao/Strategies/advanced_resource.cpp
+++ b/TAO/tao/Strategies/advanced_resource.cpp
@@ -34,6 +34,7 @@
#include "ace/Local_Memory_Pool.h"
#include "ace/Null_Mutex.h"
#include "ace/OS_NS_strings.h"
+#include "ace/Auto_Ptr.h"
#if !defined (TAO_DEFAULT_REACTOR_TYPE)
#define TAO_DEFAULT_REACTOR_TYPE TAO_REACTOR_TP
@@ -421,13 +422,16 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
/*
* Hook for specializing the Reactor implementation in TAO.
*/
+ // get a timer queue (or not) from a possibly configured
+ // time policy
+ TAO_RSF_Timer_Queue_Ptr tmq (*this, this->create_timer_queue ());
//@@ TAO_ADVANCED_RESOURCE_REACTOR_SPL_COMMENT_HOOK_START
switch (this->reactor_type_)
{
case TAO_REACTOR_SELECT_MT:
ACE_NEW_RETURN (impl,
TAO_REACTOR ((ACE_Sig_Handler*)0,
- (ACE_Timer_Queue*)0,
+ tmq.get (),
0,
(ACE_Reactor_Notify*)0,
this->reactor_mask_signals_),
@@ -437,7 +441,7 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
case TAO_REACTOR_SELECT_ST:
ACE_NEW_RETURN (impl,
TAO_NULL_LOCK_REACTOR ((ACE_Sig_Handler*)0,
- (ACE_Timer_Queue*)0,
+ tmq.get (),
0,
(ACE_Reactor_Notify*)0,
this->reactor_mask_signals_),
@@ -446,7 +450,7 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
case TAO_REACTOR_WFMO:
#if defined(ACE_WIN32)
- ACE_NEW_RETURN (impl, ACE_WFMO_Reactor, 0);
+ ACE_NEW_RETURN (impl, ACE_WFMO_Reactor (0, tmq.get ()), 0);
#endif /* ACE_WIN32 */
break;
@@ -455,7 +459,7 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
&& !defined (ACE_HAS_WINCE) \
&& !defined (ACE_HAS_PHARLAP)
case TAO_REACTOR_MSGWFMO:
- ACE_NEW_RETURN (impl, ACE_Msg_WFMO_Reactor, 0);
+ ACE_NEW_RETURN (impl, ACE_Msg_WFMO_Reactor (0, tmq.get ()), 0);
break;
#endif /* ACE_WIN32 && !ACE_LACKS_MSG_WFMO */
@@ -465,7 +469,7 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
ACE_Dev_Poll_Reactor (ACE::max_handles (),
1, // restart
(ACE_Sig_Handler*)0,
- (ACE_Timer_Queue*)0,
+ tmq.get (),
0, // Do not disable notify
0, // Allocate notify handler
this->reactor_mask_signals_,
@@ -480,7 +484,7 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
ACE_TP_Reactor (ACE::max_handles (),
1,
(ACE_Sig_Handler*)0,
- (ACE_Timer_Queue*)0,
+ tmq.get (),
this->reactor_mask_signals_,
this->threadqueue_type_ == TAO_THREAD_QUEUE_FIFO ?
ACE_Select_Reactor_Token::FIFO :
@@ -491,6 +495,8 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const
//@@ TAO_ADVANCED_RESOURCE_REACTOR_SPL_COMMENT_HOOK_END
+ // safe to release timer queue
+ tmq.release ();
return impl;
}
diff --git a/TAO/tao/Synch_Invocation.cpp b/TAO/tao/Synch_Invocation.cpp
index 29b16cef49d..c7ebfc0a670 100644
--- a/TAO/tao/Synch_Invocation.cpp
+++ b/TAO/tao/Synch_Invocation.cpp
@@ -23,7 +23,7 @@
#include "ace/Auto_Ptr.h"
#include "ace/OS_NS_string.h"
-#include "ace/Countdown_Time.h"
+#include "tao/ORB_Time_Policy.h"
#if !defined (__ACE_INLINE__)
# include "tao/Synch_Invocation.inl"
@@ -48,7 +48,7 @@ namespace TAO
Invocation_Status
Synch_Twoway_Invocation::remote_twoway (ACE_Time_Value *max_wait_time)
{
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
TAO_Synch_Reply_Dispatcher *rd_p = 0;
ACE_NEW_NORETURN (rd_p, TAO_Synch_Reply_Dispatcher (this->resolver_.stub ()->orb_core (),
@@ -649,7 +649,7 @@ namespace TAO
Invocation_Status
Synch_Oneway_Invocation::remote_oneway (ACE_Time_Value *max_wait_time)
{
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
CORBA::Octet const response_flags = this->details_.response_flags ();
diff --git a/TAO/tao/TAO_Internal.cpp b/TAO/tao/TAO_Internal.cpp
index 30c2851c98b..1f87dd689ca 100644
--- a/TAO/tao/TAO_Internal.cpp
+++ b/TAO/tao/TAO_Internal.cpp
@@ -21,6 +21,8 @@
#include "tao/Default_Collocation_Resolver.h"
#include "tao/Codeset_Manager_Factory_Base.h"
#include "tao/Codeset_Manager.h"
+#include "tao/Time_Policy_Manager.h"
+#include "tao/HR_Time_Policy_Strategy.h"
#include "tao/debug.h"
#include "ace/Dynamic_Service.h"
@@ -680,6 +682,10 @@ namespace
pcfg->process_directive (
ace_svc_desc_TAO_Default_Thread_Lane_Resources_Manager_Factory);
pcfg->process_directive (ace_svc_desc_TAO_Default_Collocation_Resolver);
+#if (TAO_HAS_TIME_POLICY == 1)
+ pcfg->process_directive (ace_svc_desc_TAO_Time_Policy_Manager);
+ pcfg->process_directive (ace_svc_desc_TAO_HR_Time_Policy_Strategy);
+#endif
} /* register_global_services_i */
diff --git a/TAO/tao/Time_Policy_Manager.cpp b/TAO/tao/Time_Policy_Manager.cpp
new file mode 100644
index 00000000000..8bd8945a444
--- /dev/null
+++ b/TAO/tao/Time_Policy_Manager.cpp
@@ -0,0 +1,164 @@
+// $Id$
+
+#include "tao/Time_Policy_Manager.h"
+#include "tao/ORB_Time_Policy.h"
+#include "tao/debug.h"
+
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_strings.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_Time_Policy_Manager::TAO_Time_Policy_Manager ()
+ : time_policy_strategy_ (0)
+#if defined(TAO_USE_HR_TIME_POLICY_STRATEGY)
+ , time_policy_setting_ (TAO_HR_TIME_POLICY)
+#else
+ , time_policy_setting_ (TAO_OS_TIME_POLICY)
+#endif
+{
+}
+
+TAO_Time_Policy_Manager::~TAO_Time_Policy_Manager ()
+{
+ TAO::ORB_Time_Policy::reset_time_policy ();
+}
+
+// = Service Configurator hooks.
+/// Dynamic linking hook
+int
+TAO_Time_Policy_Manager::init (int argc, ACE_TCHAR* argv[])
+{
+ return this->parse_args (argc, argv);
+}
+
+/// Parse svc.conf arguments
+int
+TAO_Time_Policy_Manager::parse_args (int argc, ACE_TCHAR* argv[])
+{
+ ACE_TRACE ("TAO_Time_Policy_Manager::parse_args");
+
+ int curarg;
+
+ for (curarg = 0; curarg < argc && argv[curarg]; ++curarg)
+ {
+ if (ACE_OS::strcasecmp (argv[curarg],
+ ACE_TEXT("-ORBTimePolicyStrategy")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ if (ACE_OS::strcasecmp (name,
+ ACE_TEXT("OS")) == 0)
+ this->time_policy_setting_ = TAO_OS_TIME_POLICY;
+ else if (ACE_OS::strcasecmp (name,
+ ACE_TEXT("HR")) == 0)
+ this->time_policy_setting_ = TAO_HR_TIME_POLICY;
+ else
+ {
+ this->time_policy_setting_ = TAO_DYN_TIME_POLICY;
+ this->time_policy_name_ = name;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+ACE_Timer_Queue * TAO_Time_Policy_Manager::create_timer_queue (void)
+{
+ if (this->time_policy_setting_ != TAO_OS_TIME_POLICY)
+ {
+ // locking scope
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ monitor,
+ this->lock_,
+ 0);
+
+ // check if time policy strategy has already been initialized
+ if (this->time_policy_strategy_ == 0)
+ {
+ // load strategy
+ if (this->time_policy_setting_ == TAO_HR_TIME_POLICY)
+ {
+ this->time_policy_name_ = ACE_TEXT ("TAO_HR_TIME_POLICY");
+ this->time_policy_strategy_ =
+ ACE_Dynamic_Service<TAO_Time_Policy_Strategy>::instance (
+ this->time_policy_name_.c_str ());
+ }
+ else
+ this->time_policy_strategy_ =
+ ACE_Dynamic_Service<TAO_Time_Policy_Strategy>::instance (
+ this->time_policy_name_.c_str ());
+ if (this->time_policy_strategy_ == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - TAO_Time_Policy_Manager: ")
+ ACE_TEXT ("FAILED to load time policy strategy '%C'\n"),
+ this->time_policy_name_.c_str ()));
+ return 0;
+ }
+
+ if (TAO_debug_level > 1)
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - TAO_Time_Policy_Manager: ")
+ ACE_TEXT ("loaded time policy strategy '%C'\n"),
+ this->time_policy_name_.c_str ()));
+ }
+
+ // handle one time initialization of ORB_Time_Policy
+ TAO::ORB_Time_Policy::set_time_policy (
+ this->time_policy_strategy_->get_time_policy ());
+ }
+ }
+
+ return this->time_policy_strategy_->create_timer_queue ();
+ }
+
+ // OS time policy is builtin default
+ return 0;
+}
+
+void
+TAO_Time_Policy_Manager::destroy_timer_queue (ACE_Timer_Queue *tmq)
+{
+ if (this->time_policy_setting_ != TAO_OS_TIME_POLICY)
+ {
+ // locking scope
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ monitor,
+ this->lock_);
+
+ // check if time policy strategy has already been initialized
+ if (this->time_policy_strategy_ == 0)
+ {
+ return;
+ }
+ }
+
+ this->time_policy_strategy_->destroy_timer_queue (tmq);
+ }
+}
+
+
+ACE_STATIC_SVC_DEFINE (TAO_Time_Policy_Manager,
+ ACE_TEXT ("Time_Policy_Manager"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_Time_Policy_Manager),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (TAO, TAO_Time_Policy_Manager)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_TIME_POLICY */
diff --git a/TAO/tao/Time_Policy_Manager.h b/TAO/tao/Time_Policy_Manager.h
new file mode 100644
index 00000000000..b53d8a516b0
--- /dev/null
+++ b/TAO/tao/Time_Policy_Manager.h
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Time_Policy_Manager.h
+ *
+ * $Id$
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+//=============================================================================
+
+#ifndef TIME_POLICY_MANAGER_H
+#define TIME_POLICY_MANAGER_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/TAO_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/orbconf.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+#include "tao/Time_Policy_Strategy.h"
+
+#include "ace/Service_Object.h"
+#include "ace/Timer_Queuefwd.h"
+#include "ace/Time_Policy.h"
+#include "ace/Service_Config.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class Time_Policy_Manager
+ *
+ * @brief Manager service for time policy strategy services.
+ *
+ */
+class TAO_Export TAO_Time_Policy_Manager
+ : public ACE_Service_Object
+{
+public:
+ TAO_Time_Policy_Manager ();
+ virtual ~TAO_Time_Policy_Manager ();
+
+ // = Service Configurator hooks.
+ /// Dynamic linking hook
+ virtual int init (int argc, ACE_TCHAR* argv[]);
+
+ /// Parse svc.conf arguments
+ int parse_args (int argc, ACE_TCHAR* argv[]);
+
+ virtual ACE_Timer_Queue * create_timer_queue (void);
+
+ virtual void destroy_timer_queue (ACE_Timer_Queue *tmq);
+
+private:
+ enum Time_Policy_Setting
+ {
+ TAO_OS_TIME_POLICY,
+ TAO_HR_TIME_POLICY,
+ TAO_DYN_TIME_POLICY
+ };
+
+ TAO_SYNCH_MUTEX lock_;
+
+ TAO_Time_Policy_Strategy * time_policy_strategy_;
+
+ Time_Policy_Setting time_policy_setting_;
+
+ ACE_CString time_policy_name_;
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO, TAO_Time_Policy_Manager)
+ACE_FACTORY_DECLARE (TAO, TAO_Time_Policy_Manager)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_TIME_POLICY */
+
+#include /**/ "ace/post.h"
+
+#endif /* TIME_POLICY_MANAGER_H */
diff --git a/TAO/tao/Time_Policy_Strategy.h b/TAO/tao/Time_Policy_Strategy.h
new file mode 100644
index 00000000000..41111c666bf
--- /dev/null
+++ b/TAO/tao/Time_Policy_Strategy.h
@@ -0,0 +1,61 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Time_Policy_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+//=============================================================================
+
+#ifndef TIME_POLICY_STRATEGY_H
+#define TIME_POLICY_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+
+#include /**/ "tao/TAO_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/orbconf.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+#include "tao/Versioned_Namespace.h"
+
+#include "ace/Service_Object.h"
+#include "ace/Timer_Queuefwd.h"
+#include "ace/Time_Policy.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_Time_Policy_Strategy
+ *
+ * @brief Abstract base class for time policy strategy services.
+ *
+ */
+class TAO_Export TAO_Time_Policy_Strategy
+ : public ACE_Service_Object
+{
+public:
+ virtual ~TAO_Time_Policy_Strategy () {}
+
+ virtual ACE_Timer_Queue * create_timer_queue (void) = 0;
+
+ virtual void destroy_timer_queue (ACE_Timer_Queue *tmq) = 0;
+
+ virtual ACE_Dynamic_Time_Policy_Base * get_time_policy (void) = 0;
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_TIME_POLICY */
+
+#include /**/ "ace/post.h"
+
+#endif /* TIME_POLICY_STRATEGY_H */
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index ce7224a2287..4c0f1731d68 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -25,13 +25,13 @@
#include "tao/SystemException.h"
#include "tao/operation_details.h"
#include "tao/Transport_Descriptor_Interface.h"
+#include "tao/ORB_Time_Policy.h"
#include "ace/OS_NS_sys_time.h"
#include "ace/OS_NS_stdio.h"
#include "ace/Reactor.h"
#include "ace/os_include/sys/os_uio.h"
#include "ace/High_Res_Timer.h"
-#include "ace/Countdown_Time.h"
#include "ace/CORBA_macros.h"
/*
@@ -1002,7 +1002,7 @@ TAO_Transport::drain_queue_helper (int &iovcnt, iovec iov[],
// As a side-effect, this decrements the timeout() pointed-to value by
// the time used in this function. That might be important as there are
// potentially long running system calls invoked from here.
- ACE_Countdown_Time countdown(dc.timeout());
+ TAO::ORB_Countdown_Time countdown(dc.timeout());
size_t byte_count = 0;
diff --git a/TAO/tao/Wait_On_Reactor.cpp b/TAO/tao/Wait_On_Reactor.cpp
index 2cc6c83ffe4..874d108d611 100644
--- a/TAO/tao/Wait_On_Reactor.cpp
+++ b/TAO/tao/Wait_On_Reactor.cpp
@@ -4,9 +4,9 @@
#include "tao/ORB_Core.h"
#include "tao/Transport.h"
#include "tao/Synch_Reply_Dispatcher.h"
+#include "tao/ORB_Time_Policy.h"
#include "ace/Reactor.h"
-#include "ace/Countdown_Time.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -25,7 +25,7 @@ TAO_Wait_On_Reactor::wait (ACE_Time_Value *max_wait_time,
{
// Start the count down timer to account for the time spent in this
// method.
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
// Reactor does not change inside the loop.
ACE_Reactor *const reactor =
diff --git a/TAO/tao/Wait_On_Read.cpp b/TAO/tao/Wait_On_Read.cpp
index bb9ce367838..9864010e872 100644
--- a/TAO/tao/Wait_On_Read.cpp
+++ b/TAO/tao/Wait_On_Read.cpp
@@ -6,8 +6,8 @@
#include "tao/Synch_Reply_Dispatcher.h"
#include "tao/Client_Strategy_Factory.h"
#include "tao/ORB_Core.h"
+#include "tao/ORB_Time_Policy.h"
#include "ace/Reactor.h"
-#include "ace/Countdown_Time.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -80,7 +80,7 @@ TAO_Wait_On_Read::wait (ACE_Time_Value * max_wait_time,
{
// Start the count down timer to account for the time spent in this
// method.
- ACE_Countdown_Time countdown (max_wait_time);
+ TAO::ORB_Countdown_Time countdown (max_wait_time);
rd.state_changed (TAO_LF_Event::LFS_ACTIVE,
this->transport_->orb_core ()->leader_follower ());
diff --git a/TAO/tao/default_resource.cpp b/TAO/tao/default_resource.cpp
index cf02fc6404d..76d27c9226c 100644
--- a/TAO/tao/default_resource.cpp
+++ b/TAO/tao/default_resource.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-// $Id: default_resource.cpp 93496 2011-03-07 09:37:27Z johnnyw $
+// $Id$
#include "tao/default_resource.h"
@@ -19,6 +19,7 @@
#include "tao/On_Demand_Fragmentation_Strategy.h"
#include "tao/MMAP_Allocator.h"
#include "tao/Load_Protocol_Factory_T.h"
+#include "tao/Time_Policy_Manager.h"
#include "ace/TP_Reactor.h"
#include "ace/Malloc.h"
@@ -28,6 +29,10 @@
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_strings.h"
+#if !defined (__ACE_INLINE__)
+#include "tao/default_resource.inl"
+#endif /* __ACE_INLINE__ */
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
TAO_Codeset_Parameters::TAO_Codeset_Parameters (void)
@@ -705,6 +710,50 @@ TAO_Default_Resource_Factory::get_connector_registry (void)
return cr;
}
+#if (TAO_HAS_TIME_POLICY == 1)
+TAO_Time_Policy_Manager*
+TAO_Default_Resource_Factory::time_policy_manager (void) const
+{
+ // get time policy manager service
+ TAO_Time_Policy_Manager * tpm =
+ ACE_Dynamic_Service<TAO_Time_Policy_Manager>::instance (ACE_TEXT ("Time_Policy_Manager"));
+
+ if (tpm == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - TAO_Default_Resource_Factory::time_policy_manager: ")
+ ACE_TEXT ("FAILED to retrieve service Time_Policy_Manager\n")));
+ }
+
+ return tpm;
+}
+#endif /* TAO_HAS_TIME_POLICY */
+
+ACE_Timer_Queue *
+TAO_Default_Resource_Factory::create_timer_queue (void) const
+{
+#if (TAO_HAS_TIME_POLICY == 1)
+ TAO_Time_Policy_Manager * tpm = this->time_policy_manager ();
+ if (tpm)
+ {
+ return tpm->create_timer_queue ();
+ }
+#endif /* TAO_HAS_TIME_POLICY */
+ return 0;
+}
+
+void
+TAO_Default_Resource_Factory::destroy_timer_queue (ACE_Timer_Queue *tmq) const
+{
+#if (TAO_HAS_TIME_POLICY == 1)
+ TAO_Time_Policy_Manager * tpm = this->time_policy_manager ();
+ if (tpm)
+ {
+ tpm->destroy_timer_queue (tmq);
+ }
+#endif /* TAO_HAS_TIME_POLICY */
+}
+
ACE_Reactor_Impl*
TAO_Default_Resource_Factory::allocate_reactor_impl (void) const
{
@@ -712,16 +761,21 @@ TAO_Default_Resource_Factory::allocate_reactor_impl (void) const
/*
* Hook to specialize TAO's reactor implementation.
*/
+ // get a timer queue (or not) from a possibly configured
+ // time policy
+ TAO_RSF_Timer_Queue_Ptr tmq (*this, this->create_timer_queue ());
//@@ TAO_REACTOR_SPL_COMMENT_HOOK_START
ACE_NEW_RETURN (impl,
ACE_TP_Reactor (ACE::max_handles (),
1,
(ACE_Sig_Handler*)0,
- (ACE_Timer_Queue*)0,
+ tmq.get (),
this->reactor_mask_signals_,
ACE_Select_Reactor_Token::LIFO),
0);
//@@ TAO_REACTOR_SPL_COMMENT_HOOK_END
+ // safe to release timer queue
+ tmq.release ();
return impl;
}
@@ -735,8 +789,13 @@ TAO_Default_Resource_Factory::get_reactor (void)
if (reactor->initialized () == 0)
{
+ // backup timer queue
+ ACE_Timer_Queue *tmq = reactor->timer_queue ();
+ // clean up reactor
delete reactor;
reactor = 0;
+ // clean up timer queue in case it was created by time policy
+ this->destroy_timer_queue (tmq);
}
else
this->dynamically_allocated_reactor_ = true;
@@ -748,7 +807,14 @@ void
TAO_Default_Resource_Factory::reclaim_reactor (ACE_Reactor *reactor)
{
if (this->dynamically_allocated_reactor_)
- delete reactor;
+ {
+ // backup timer queue
+ ACE_Timer_Queue *tmq = reactor->timer_queue ();
+ // clean up reactor
+ delete reactor;
+ // clean up timer queue in case it was created by time policy
+ this->destroy_timer_queue (tmq);
+ }
}
diff --git a/TAO/tao/default_resource.h b/TAO/tao/default_resource.h
index 9b5e7907d98..e4da5867cf8 100644
--- a/TAO/tao/default_resource.h
+++ b/TAO/tao/default_resource.h
@@ -29,12 +29,16 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Reactor_Impl;
ACE_END_VERSIONED_NAMESPACE_DECL
+#include "ace/Timer_Queuefwd.h"
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
class TAO_Object_Adapter;
class TAO_IOR_Parser;
class TAO_LF_Strategy;
class TAO_Codeset_Descriptor_Base;
+class TAO_Time_Policy_Manager;
+class TAO_RSF_Timer_Queue_Ptr;
/**
* @class TAO_Codeset_Parameters
@@ -190,6 +194,16 @@ public:
protected:
+ friend class TAO_RSF_Timer_Queue_Ptr;
+
+#if (TAO_HAS_TIME_POLICY == 1)
+ TAO_Time_Policy_Manager* time_policy_manager (void) const;
+#endif
+
+ ACE_Timer_Queue * create_timer_queue (void) const;
+
+ void destroy_timer_queue (ACE_Timer_Queue *tmq) const;
+
/// Obtain the reactor implementation
virtual ACE_Reactor_Impl *allocate_reactor_impl (void) const;
@@ -313,7 +327,32 @@ private:
ACE_STATIC_SVC_DECLARE_EXPORT (TAO, TAO_Default_Resource_Factory)
ACE_FACTORY_DECLARE (TAO, TAO_Default_Resource_Factory)
+/**
+ * @class TAO_RSF_Timer_Queue_Ptr
+ *
+ * @brief A simple auto_ptr like class to manage timer queues dynamically
+ * allocated by a time policy.
+ */
+class TAO_Export TAO_RSF_Timer_Queue_Ptr
+{
+public:
+ TAO_RSF_Timer_Queue_Ptr (TAO_Default_Resource_Factory const &, ACE_Timer_Queue*);
+ ~TAO_RSF_Timer_Queue_Ptr ();
+
+ ACE_Timer_Queue* get ();
+ void release ();
+
+private:
+ TAO_Default_Resource_Factory const & resource_factory_;
+ ACE_Timer_Queue * timer_queue_;
+};
+
TAO_END_VERSIONED_NAMESPACE_DECL
+#if defined (__ACE_INLINE__)
+#include "tao/default_resource.inl"
+#endif /* __ACE_INLINE__ */
+
#include /**/ "ace/post.h"
+
#endif /* TAO_DEFAULT_CLIENT_H */
diff --git a/TAO/tao/default_resource.inl b/TAO/tao/default_resource.inl
new file mode 100644
index 00000000000..c404dc048d3
--- /dev/null
+++ b/TAO/tao/default_resource.inl
@@ -0,0 +1,32 @@
+// -*- C++ -*-
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+TAO_RSF_Timer_Queue_Ptr::TAO_RSF_Timer_Queue_Ptr (TAO_Default_Resource_Factory const & rsf, ACE_Timer_Queue* tmq)
+ : resource_factory_ (rsf),
+ timer_queue_ (tmq)
+{
+}
+
+ACE_INLINE
+TAO_RSF_Timer_Queue_Ptr::~TAO_RSF_Timer_Queue_Ptr ()
+{
+ if (this->timer_queue_ != 0)
+ this->resource_factory_.destroy_timer_queue (this->timer_queue_);
+}
+
+ACE_INLINE ACE_Timer_Queue*
+TAO_RSF_Timer_Queue_Ptr::get ()
+{
+ return this->timer_queue_;
+}
+
+ACE_INLINE void
+TAO_RSF_Timer_Queue_Ptr::release ()
+{
+ this->timer_queue_ = 0;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/orbconf.h b/TAO/tao/orbconf.h
index 8e8efb4f900..c0510e792f2 100644
--- a/TAO/tao/orbconf.h
+++ b/TAO/tao/orbconf.h
@@ -429,6 +429,14 @@ const size_t TAO_DEFAULT_VALUE_FACTORY_TABLE_SIZE = 128;
# define TAO_DISABLE_CORBA_MESSAGING_POLICIES 0
#endif /* !TAO_DISABLE_CORBA_MESSAGING_POLICIES */
+// To explicitly disable TIME_POLICY support uncomment the following
+// #define TAO_HAS_TIME_POLICY 0
+
+// Default TIME_POLICY settings
+#if !defined (TAO_HAS_TIME_POLICY)
+# define TAO_HAS_TIME_POLICY 1
+#endif /* !TAO_HAS_TIME_POLICY */
+
// To explicitly disable REBIND_POLICY support uncomment the following
// #define TAO_HAS_REBIND_POLICY 0
diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc
index acd680317d0..8c90d52c842 100644
--- a/TAO/tao/tao.mpc
+++ b/TAO/tao/tao.mpc
@@ -155,6 +155,7 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
GIOP_Message_State.cpp
GIOP_Message_Version.cpp
GIOPC.cpp
+ HR_Time_Policy_Strategy.cpp
HTTP_Client.cpp
HTTP_Handler.cpp
HTTP_Parser.cpp
@@ -225,6 +226,7 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
ORB_Core_Auto_Ptr.cpp
ORB_Core_TSS_Resources.cpp
ORB_Table.cpp
+ ORB_Time_Policy.cpp
ParameterModeC.cpp
params.cpp
Parser_Registry.cpp
@@ -288,6 +290,7 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
Thread_Lane_Resources.cpp
Thread_Lane_Resources_Manager.cpp
Thread_Per_Connection_Handler.cpp
+ Time_Policy_Manager.cpp
TimeBaseC.cpp
Transport.cpp
Transport_Acceptor.cpp
@@ -427,6 +430,7 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
GIOPS.h
GIOP_Utils.h
GUIResource_Factory.h
+ HR_Time_Policy_Strategy.h
HTTP_Client.h
HTTP_Handler.h
HTTP_Parser.h
@@ -515,6 +519,7 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
ORBInitializer_Registry.h
ORBInitializer_Registry_Adapter.h
ORB_Table.h
+ ORB_Time_Policy.h
orb_typesC.h
orb_typesS.h
ParameterModeC.h
@@ -601,6 +606,8 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
Thread_Lane_Resources.h
Thread_Lane_Resources_Manager.h
Thread_Per_Connection_Handler.h
+ Time_Policy_Manager.h
+ Time_Policy_Strategy.h
TimeBaseC.h
TimeBaseS.h
Timeprobe.h
diff --git a/TAO/tests/Time_Policy/Time_Policy.mpc b/TAO/tests/Time_Policy/Time_Policy.mpc
new file mode 100644
index 00000000000..d6bb48b97f2
--- /dev/null
+++ b/TAO/tests/Time_Policy/Time_Policy.mpc
@@ -0,0 +1,12 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Exe): taoserver {
+ exename = test
+ Source_Files {
+ main.cpp
+ }
+ IDL_Files {
+ }
+}
+
diff --git a/TAO/tests/Time_Policy/hr_time.conf b/TAO/tests/Time_Policy/hr_time.conf
new file mode 100644
index 00000000000..40e24b42ded
--- /dev/null
+++ b/TAO/tests/Time_Policy/hr_time.conf
@@ -0,0 +1,3 @@
+# $Id$
+
+static Time_Policy_Manager "-ORBTimePolicyStrategy HR"
diff --git a/TAO/tests/Time_Policy/hr_time.conf.xml b/TAO/tests/Time_Policy/hr_time.conf.xml
new file mode 100644
index 00000000000..27d781c308d
--- /dev/null
+++ b/TAO/tests/Time_Policy/hr_time.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from hr_time.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="Time_Policy_Manager" params="-ORBTimePolicyStrategy HR"/>
+</ACE_Svc_Conf>
diff --git a/TAO/tests/Time_Policy/main.cpp b/TAO/tests/Time_Policy/main.cpp
new file mode 100644
index 00000000000..93fed1dcd7d
--- /dev/null
+++ b/TAO/tests/Time_Policy/main.cpp
@@ -0,0 +1,194 @@
+//=============================================================================
+/**
+ * @file main.cpp
+ *
+ * $Id$
+ *
+ * Implementation of the server.
+ *
+ *
+ * @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
+ * @author Michael Kircher <Michael.Kircher@mchp.siemens.de>
+ */
+//=============================================================================
+
+#include "tao/ORB.h"
+#include "tao/ORB_Core.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/Reactor.h"
+#include "ace/Timer_Queue.h"
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Get_Opt.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+#if defined(TAO_USE_HR_TIME_POLICY_STRATEGY)
+bool uses_hr_time = true;
+#else
+bool uses_hr_time = false;
+#endif
+
+class TestHandler
+ : public ACE_Event_Handler
+{
+public:
+ TestHandler (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb)),
+ timeout_triggered_ (false)
+ {}
+
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg);
+
+ bool trigger_in(const ACE_Time_Value &delay);
+
+ bool timeout_triggered () { return this->timeout_triggered_; }
+
+private:
+ CORBA::ORB_var orb_;
+ bool timeout_triggered_;
+};
+
+int TestHandler::handle_timeout (const ACE_Time_Value &,
+ const void *)
+{
+ ACE_DEBUG ((LM_DEBUG, "TestHandler::handle_timeout - timeout triggered\n"));
+ this->timeout_triggered_ = true;
+ this->orb_->shutdown (false);
+ return 0;
+}
+
+bool TestHandler::trigger_in(const ACE_Time_Value &delay)
+{
+ return -1 != this->orb_->orb_core ()->reactor ()->schedule_timer (this, 0, delay, ACE_Time_Value (0));
+}
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("h"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'h':
+ uses_hr_time = true;
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-h "
+ "\n"
+ "\t-h\t: uses highres time policy\n",
+ argv [0]),
+ -1);
+ break;
+ }
+
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ if (CORBA::is_nil (poa_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to initialize the POA.\n"),
+ 1);
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ poa_manager->activate ();
+
+ TestHandler test_handler (orb.in ());
+
+ // trigger in 2 seconds
+ if (!test_handler.trigger_in (ACE_Time_Value (2, 0)))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to schedule trigger.\n"),
+ 1);
+
+ // reset system clock 4 seconds backwards
+ timespec_t curts;
+ ACE_Time_Value curtime = ACE_OS::gettimeofday ();
+ curtime -= ACE_Time_Value (4, 0);
+ curts = curtime;
+ if (ACE_OS::clock_settime (CLOCK_REALTIME, &curts) != 0)
+ {
+ ACE_DEBUG((LM_INFO,
+ "Unable to reset OS time. Insufficient privileges or not supported.\n"));
+
+ root_poa->destroy (1, // ethernalize objects
+ 0 // wait for completion
+ );
+
+ orb->destroy ();
+
+ return 0;
+ }
+ else
+ {
+ // run for max. 4 seconds
+ ACE_Time_Value timeout (4, 0);
+ orb->run (timeout);
+
+ root_poa->destroy (1, // ethernalize objects
+ 0 // wait for completion
+ );
+
+ orb->destroy ();
+
+ ACE_DEBUG ((LM_DEBUG, "event loop finished\n"));
+
+ // reset system clock to correct time
+ curtime = ACE_OS::gettimeofday ();
+ curtime += ACE_Time_Value (4, 0);
+ curts = curtime;
+ ACE_OS::clock_settime (CLOCK_REALTIME, &curts);
+
+ if (!test_handler.timeout_triggered ())
+ {
+ ACE_DEBUG ((LM_DEBUG, "timer handler did not trigger\n"));
+ return uses_hr_time ? 1 : 0;
+ }
+ else
+ {
+ return uses_hr_time ? 0 : 1;
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Caught exception:");
+ return 1;
+ }
+}
+
+#else
+int
+ACE_TMAIN(int , ACE_TCHAR * [])
+{
+ ACE_DEBUG ((LM_INFO, "TAO built without Time Policy support\n"));
+ return 0;
+}
+#endif /* TAO_HAS_TIME_POLICY != 1 */
diff --git a/TAO/tests/Time_Policy/run_test.pl b/TAO/tests/Time_Policy/run_test.pl
new file mode 100755
index 00000000000..c66074e5acc
--- /dev/null
+++ b/TAO/tests/Time_Policy/run_test.pl
@@ -0,0 +1,38 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+
+$server_debug_level = '0';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $server_debug_level = '10';
+ }
+}
+
+$SV = $server->CreateProcess ("test", "-ORBdebuglevel $server_debug_level");
+
+$server_status = $SV->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval()*2);
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+exit $status;
diff --git a/TAO/tests/Time_Policy/run_test_hr.pl b/TAO/tests/Time_Policy/run_test_hr.pl
new file mode 100755
index 00000000000..9f3b49e6f01
--- /dev/null
+++ b/TAO/tests/Time_Policy/run_test_hr.pl
@@ -0,0 +1,44 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+$server_conf_base = "hr_time$PerlACE::svcconf_ext";
+$server_conf = $server->LocalFile ($server_conf_base);
+if ($server->PutFile ($server_conf_base) == -1) {
+ print STDERR "ERROR: cannot set file <$server_conf>\n";
+ exit 1;
+}
+
+$server_debug_level = '0';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $server_debug_level = '10';
+ }
+}
+
+$SV = $server->CreateProcess ("test", "-h -ORBsvcconf $server_conf -ORBdebuglevel $server_debug_level");
+
+$server_status = $SV->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval()*2);
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+exit $status;
diff --git a/TAO/tests/Time_Policy_Custom/Custom_Time_Policy.mpc b/TAO/tests/Time_Policy_Custom/Custom_Time_Policy.mpc
new file mode 100644
index 00000000000..d4fcbfbf01d
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/Custom_Time_Policy.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Lib): taolib {
+ sharedname = CustomTimePolicy
+ Source_Files {
+ Custom_Time_Policy_Strategy.cpp
+ }
+}
+
+project(*Exe): taoserver {
+ after += *Lib
+ libs += CustomTimePolicy
+ exename = test
+ Source_Files {
+ main.cpp
+ }
+ IDL_Files {
+ }
+}
+
diff --git a/TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.cpp b/TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.cpp
new file mode 100644
index 00000000000..737b881c498
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.cpp
@@ -0,0 +1,63 @@
+// $Id$
+
+#include "Custom_Time_Policy_Strategy.h"
+
+#include "ace/Timer_Heap_T.h"
+#include "ace/Event_Handler_Handle_Timeout_Upcall.h"
+#include "ace/High_Res_Timer.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+class ACE_Export Custom_Time_Policy
+{
+public:
+ /// Return the current time according to this policy
+ ACE_Time_Value operator() () const
+ {
+ ACE_Time_Value tv = ACE_High_Res_Timer::gettimeofday_hr ();
+ return (tv += ACE_Time_Value (10, 0));
+ }
+};
+
+static ACE_Time_Policy_T<Custom_Time_Policy> custom_time_policy_;
+
+Custom_Time_Policy_Strategy::~Custom_Time_Policy_Strategy ()
+{
+}
+
+ACE_Timer_Queue * Custom_Time_Policy_Strategy::create_timer_queue (void)
+{
+ ACE_Timer_Queue * tmq = 0;
+
+ typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
+ ACE_Event_Handler_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX,
+ Custom_Time_Policy> timer_queue_type;
+ ACE_NEW_RETURN (tmq, timer_queue_type (), 0);
+
+ return tmq;
+}
+
+void
+Custom_Time_Policy_Strategy::destroy_timer_queue (ACE_Timer_Queue *tmq)
+{
+ delete tmq;
+}
+
+ACE_Dynamic_Time_Policy_Base * Custom_Time_Policy_Strategy::get_time_policy (void)
+{
+ return &custom_time_policy_;
+}
+
+
+ACE_STATIC_SVC_DEFINE (Custom_Time_Policy_Strategy,
+ ACE_TEXT ("CUSTOM_TIME_POLICY"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (Custom_Time_Policy_Strategy),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (TPTEST, Custom_Time_Policy_Strategy)
+
+#endif /* TAO_HAS_TIME_POLICY */
diff --git a/TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.h b/TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.h
new file mode 100644
index 00000000000..e65af83f6cc
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/Custom_Time_Policy_Strategy.h
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Custom_Time_Policy_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Martin Corino <mcorino@remedy.nl>
+ */
+//=============================================================================
+
+#ifndef CUSTOM_TIME_POLICY_STRATEGY_H
+#define CUSTOM_TIME_POLICY_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+#include "tao/Time_Policy_Strategy.h"
+
+#include "ace/Time_Policy_T.h"
+#include "ace/Service_Config.h"
+
+#include "TPTest_Export.h"
+
+/**
+ * @class Custom_Time_Policy_Strategy
+ *
+ */
+class TPTEST_Export Custom_Time_Policy_Strategy
+ : public TAO_Time_Policy_Strategy
+{
+public:
+ virtual ~Custom_Time_Policy_Strategy ();
+
+ virtual ACE_Timer_Queue * create_timer_queue (void);
+
+ virtual void destroy_timer_queue (ACE_Timer_Queue *tmq);
+
+ virtual ACE_Dynamic_Time_Policy_Base * get_time_policy (void);
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TPTEST, Custom_Time_Policy_Strategy)
+ACE_FACTORY_DECLARE (TPTEST, Custom_Time_Policy_Strategy)
+
+#endif /* TAO_HAS_TIME_POLICY */
+
+#include /**/ "ace/post.h"
+
+#endif /* CUSTOM_TIME_POLICY_STRATEGY_H */
diff --git a/TAO/tests/Time_Policy_Custom/TPTest_Export.h b/TAO/tests/Time_Policy_Custom/TPTest_Export.h
new file mode 100644
index 00000000000..4dcfe63f844
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/TPTest_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl TPTEST
+// ------------------------------
+#ifndef TPTEST_EXPORT_H
+#define TPTEST_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TPTEST_HAS_DLL)
+# define TPTEST_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TPTEST_HAS_DLL */
+
+#if !defined (TPTEST_HAS_DLL)
+# define TPTEST_HAS_DLL 1
+#endif /* ! TPTEST_HAS_DLL */
+
+#if defined (TPTEST_HAS_DLL) && (TPTEST_HAS_DLL == 1)
+# if defined (TPTEST_BUILD_DLL)
+# define TPTEST_Export ACE_Proper_Export_Flag
+# define TPTEST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TPTEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TPTEST_BUILD_DLL */
+# define TPTEST_Export ACE_Proper_Import_Flag
+# define TPTEST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TPTEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TPTEST_BUILD_DLL */
+#else /* TPTEST_HAS_DLL == 1 */
+# define TPTEST_Export
+# define TPTEST_SINGLETON_DECLARATION(T)
+# define TPTEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TPTEST_HAS_DLL == 1 */
+
+// Set TPTEST_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TPTEST_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TPTEST_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TPTEST_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TPTEST_NTRACE */
+
+#if (TPTEST_NTRACE == 1)
+# define TPTEST_TRACE(X)
+#else /* (TPTEST_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TPTEST_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TPTEST_NTRACE == 1) */
+
+#endif /* TPTEST_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tests/Time_Policy_Custom/custom_time.conf b/TAO/tests/Time_Policy_Custom/custom_time.conf
new file mode 100644
index 00000000000..952f722cf1e
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/custom_time.conf
@@ -0,0 +1,7 @@
+# $Id$
+
+dynamic CUSTOM_TIME_POLICY Service_Object *
+ CustomTimePolicy:_make_Custom_Time_Policy_Strategy()
+ ""
+
+static Time_Policy_Manager "-ORBTimePolicyStrategy CUSTOM_TIME_POLICY"
diff --git a/TAO/tests/Time_Policy_Custom/custom_time.conf.xml b/TAO/tests/Time_Policy_Custom/custom_time.conf.xml
new file mode 100644
index 00000000000..24a070f4a3d
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/custom_time.conf.xml
@@ -0,0 +1,9 @@
+<?xml version='1.0'?>
+<!-- Converted from custom_time.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <dynamic id="CUSTOM_TIME_POLICY" type="Service_Object">
+ <initializer path="CustomTimePolicy" init="_make_Custom_Time_Policy_Strategy"/>
+ </dynamic>
+ <static id="Time_Policy_Manager" params="-ORBTimePolicyStrategy CUSTOM_TIME_POLICY"/>
+</ACE_Svc_Conf>
diff --git a/TAO/tests/Time_Policy_Custom/main.cpp b/TAO/tests/Time_Policy_Custom/main.cpp
new file mode 100644
index 00000000000..6a0648bc8ce
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/main.cpp
@@ -0,0 +1,163 @@
+//=============================================================================
+/**
+ * @file main.cpp
+ *
+ * $Id$
+ *
+ * Implementation of the server.
+ *
+ *
+ * @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
+ * @author Michael Kircher <Michael.Kircher@mchp.siemens.de>
+ */
+//=============================================================================
+
+#include "tao/ORB.h"
+#include "tao/ORB_Core.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/Reactor.h"
+#include "ace/Timer_Queue.h"
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Service_Config.h"
+#include "ace/ARGV.h"
+
+#if (TAO_HAS_TIME_POLICY == 1)
+
+#include "Custom_Time_Policy_Strategy.h"
+
+class TestHandler
+ : public ACE_Event_Handler
+{
+public:
+ TestHandler (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb)),
+ timeout_triggered_ (false)
+ {}
+
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg);
+
+ bool trigger_in(const ACE_Time_Value &delay);
+
+ bool timeout_triggered () { return this->timeout_triggered_; }
+
+private:
+ CORBA::ORB_var orb_;
+ bool timeout_triggered_;
+};
+
+int TestHandler::handle_timeout (const ACE_Time_Value &,
+ const void *)
+{
+ ACE_DEBUG ((LM_DEBUG, "TestHandler::handle_timeout - timeout triggered\n"));
+ this->timeout_triggered_ = true;
+ this->orb_->shutdown (false);
+ return 0;
+}
+
+bool TestHandler::trigger_in(const ACE_Time_Value &delay)
+{
+ return -1 != this->orb_->orb_core ()->reactor ()->schedule_timer (this, 0, delay, ACE_Time_Value (0));
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ ACE_ARGV my_argv;
+ if (argc>1 && argv[1][0]=='-' && argv[1][1]=='s')
+ {
+ ACE_DEBUG ((LM_DEBUG, "loading static service\n"));
+
+ ACE_Service_Config::process_directive (ace_svc_desc_Custom_Time_Policy_Strategy);
+ my_argv.add(argv[0]);
+ for (int i=2; i<argc ;++i)
+ my_argv.add (argv[i]);
+
+ my_argv.add (ACE_TEXT ("-ORBSvcConfDirective"));
+ my_argv.add (ACE_TEXT ("static Time_Policy_Manager \"-ORBTimePolicyStrategy CUSTOM_TIME_POLICY\""), true);
+ }
+ else
+ {
+ for (int i=0; i<argc ;++i)
+ my_argv.add (argv[i]);
+ }
+
+ int my_argc = my_argv.argc ();
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (my_argc, my_argv.argv ());
+
+ // check if custom policy installed in ORB
+ ACE_Time_Value tv_hr = ACE_High_Res_Timer::gettimeofday_hr ();
+ ACE_Time_Value tv_orb = orb->orb_core ()->reactor ()->timer_queue ()->gettimeofday ();
+ ACE_Time_Value tv_diff = tv_orb - tv_hr;
+ // The custom policy gives an offset of +10s
+ if (tv_diff.sec () != 10)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Incorrect time offset (%us). Time policy doesn't seem to be loaded\n", tv_diff.sec ()),
+ 1);
+ }
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ if (CORBA::is_nil (poa_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to initialize the POA.\n"),
+ 1);
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ poa_manager->activate ();
+
+ TestHandler test_handler (orb.in ());
+
+ // trigger in 2 seconds
+ if (!test_handler.trigger_in (ACE_Time_Value (2, 0)))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to schedule trigger.\n"),
+ 1);
+
+ // run for max. 4 seconds
+ ACE_Time_Value timeout (4, 0);
+ orb->run (timeout);
+
+ root_poa->destroy (1, // ethernalize objects
+ 0 // wait for completion
+ );
+
+ orb->destroy ();
+
+ ACE_DEBUG ((LM_DEBUG, "event loop finished\n"));
+
+ if (!test_handler.timeout_triggered ())
+ {
+ ACE_DEBUG ((LM_DEBUG, "timer handler did not trigger\n"));
+ return 1;
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Caught exception:");
+ return 1;
+ }
+
+ return 0;
+}
+
+#else
+int
+ACE_TMAIN(int , ACE_TCHAR * [])
+{
+ ACE_DEBUG ((LM_INFO, "TAO built without Time Policy support\n"));
+ return 0;
+}
+#endif /* TAO_HAS_TIME_POLICY != 1 */
diff --git a/TAO/tests/Time_Policy_Custom/run_test.pl b/TAO/tests/Time_Policy_Custom/run_test.pl
new file mode 100755
index 00000000000..d5573d32809
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/run_test.pl
@@ -0,0 +1,38 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+
+$server_debug_level = '0';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $server_debug_level = '10';
+ }
+}
+
+$SV = $server->CreateProcess ("test", "-s -ORBdebuglevel $server_debug_level");
+
+$server_status = $SV->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval()*2);
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+exit $status;
diff --git a/TAO/tests/Time_Policy_Custom/run_test_dyn.pl b/TAO/tests/Time_Policy_Custom/run_test_dyn.pl
new file mode 100755
index 00000000000..8e7d359bd95
--- /dev/null
+++ b/TAO/tests/Time_Policy_Custom/run_test_dyn.pl
@@ -0,0 +1,44 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+$server_conf_base = "custom_time$PerlACE::svcconf_ext";
+$server_conf = $server->LocalFile ($server_conf_base);
+if ($server->PutFile ($server_conf_base) == -1) {
+ print STDERR "ERROR: cannot set file <$server_conf>\n";
+ exit 1;
+}
+
+$server_debug_level = '0';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $server_debug_level = '10';
+ }
+}
+
+$SV = $server->CreateProcess ("test", "-ORBsvcconf $server_conf -ORBdebuglevel $server_debug_level");
+
+$server_status = $SV->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval()*2);
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+exit $status;