diff options
author | mcorino <mcorino@users.noreply.github.com> | 2011-12-08 18:35:38 +0000 |
---|---|---|
committer | mcorino <mcorino@users.noreply.github.com> | 2011-12-08 18:35:38 +0000 |
commit | 01eb039cbc2232bb44b589635d11952e656902fa (patch) | |
tree | 1a632c5f5641b72fbdc137866384f49fa5c6442d | |
parent | bc9acf7697ed3ebf81153735dd29a3bb5a41fc4a (diff) | |
download | ATCD-01eb039cbc2232bb44b589635d11952e656902fa.tar.gz |
merged time policy changes from local branch
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 ¤t_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 ¤t_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 ¤t_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 ¤t_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; |