diff options
Diffstat (limited to 'ACE/ace/Timer_Queue_Adapters.h')
-rw-r--r-- | ACE/ace/Timer_Queue_Adapters.h | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/ACE/ace/Timer_Queue_Adapters.h b/ACE/ace/Timer_Queue_Adapters.h new file mode 100644 index 00000000000..3905b1d18b7 --- /dev/null +++ b/ACE/ace/Timer_Queue_Adapters.h @@ -0,0 +1,260 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Queue_Adapters.h + * + * $Id$ + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> and + * Carlos O'Ryan <coryan@uci.edu> + */ +//============================================================================= + +#ifndef ACE_TIMER_QUEUE_ADAPTERS_H +#define ACE_TIMER_QUEUE_ADAPTERS_H +#include /**/ "ace/pre.h" + +#include "ace/Task.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" + +#if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) +# include "ace/Unbounded_Queue.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Command_Base; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Sig_Set; + +/** + * @class ACE_Async_Timer_Queue_Adapter + * + * @brief Adapts an ACE timer queue to be driven asynchronously using signals. + * + * This implementation uses the ACE_OS::ualarm call, to generate + * the SIGARLM signal that is caught by this class. + * + * @note This adapter only works on platforms that support ualarm(). + * POSIX platforms generally do; Windows and some others do not. + * + * @todo This adapter does not automatically reschedule repeating timers. + */ +template <class TQ> +class ACE_Async_Timer_Queue_Adapter : public ACE_Event_Handler +{ +public: + typedef TQ TIMER_QUEUE; + + /// Constructor + /** + * Register the SIGALRM handler. If @a mask == 0 then block all + * signals when @c SIGALRM is run. Otherwise, just block the signals + * indicated in @a mask. + */ + ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask = 0); + + /// Schedule the timer according to the semantics of the + /// ACE_Timer_List. + /** + * This timer gets dispatched via a signal, rather than by a user + * calling expire(). Note that interval timers are not implemented + * yet. + */ + long schedule (ACE_Event_Handler *type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /// Cancel the @a timer_id and pass back the @a act if an address is + /// passed in. + int cancel (long timer_id, const void **act = 0); + + /// Dispatch all timers with expiry time at or before the current time. + /// Returns the number of timers expired. + int expire (void); + + /// Return a reference to the underlying timer queue. + TQ &timer_queue (void); + +private: + /// Perform the logic to compute the new ualarm(2) setting. + virtual int schedule_ualarm (void); + + /// Called back by @c SIGALRM handler. + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + /// Handler for the @c SIGALRM signal, so that we can access our state + /// without requiring any global variables. + ACE_Sig_Handler sig_handler_; + + /// Implementation of the timer queue (e.g., ACE_Timer_List, + /// ACE_Timer_Heap, etc.). + TQ timer_queue_; + + /// Mask of signals to be blocked when we're servicing @c SIGALRM. + ACE_Sig_Set mask_; +}; + +/** + * @class ACE_Thread_Timer_Queue_Adapter + * + * @brief Adapts an ACE timer queue using a separate thread for dispatching. + * + * This implementation uses a separate thread to dispatch the timers. + * The base queue need not be thread safe; this class takes all the + * necessary locks. + * + * @note This is a case where template parameters will be useful, but + * (IMHO) the effort and portability problems discourage their + * use. + * + */ +template <class TQ> +class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base +{ +public: + /// Trait for the underlying queue type. + typedef TQ TIMER_QUEUE; + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + + /// Typedef for the position at which to enqueue a deferred + /// execution command. + enum COMMAND_ENQUEUE_POSITION {HEAD, TAIL}; + +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + + /// Creates the timer queue. Activation of the task is the user's + /// responsibility. Optionally a pointer to a timer queue can be passed, + /// when no pointer is passed, a TQ is dynamically created + ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager * = ACE_Thread_Manager::instance (), + TQ* timer_queue = 0); + + /// Destructor. + virtual ~ACE_Thread_Timer_Queue_Adapter (void); + + /// Schedule the timer according to the semantics of the <TQ>; wakes + /// up the dispatching thread. + long schedule (ACE_Event_Handler *handler, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /// Cancel the @a timer_id and return the @a act parameter if an + /// address is passed in. Also wakes up the dispatching thread. + int cancel (long timer_id, const void **act = 0); + + /// Runs the dispatching thread. + virtual int svc (void); + + /// Inform the dispatching thread that it should terminate. + virtual void deactivate (void); + + /// Access the locking mechanism, useful for iteration. + ACE_SYNCH_RECURSIVE_MUTEX &mutex (void); + + /// Set a user-specified timer queue. + int timer_queue (TQ *tq); + + /// Return the current <TQ>. + TQ *timer_queue (void) const; + + /// Return the thread id of our active object. + ACE_thread_t thr_id (void) const; + + /** + * We override the default activate() method so that we can ensure + * that only a single thread is ever spawned. Otherwise, too many + * weird things can happen... + */ + virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE, + int n_threads = 1, + int force_active = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_thread_t thread_names[] = 0); + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + + /** + * Enqueues a command object for execution just before waiting on the next + * timer event. This allows deferred execution of commands that cannot + * be performed in the timer event handler context, such as registering + * or cancelling timers on platforms where the timer queue mutex is not + * recursive. + */ + int enqueue_command (ACE_Command_Base *command_, + COMMAND_ENQUEUE_POSITION pos = TAIL); + +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + +private: + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + /// Dispatches all command objects enqueued in the most + /// recent event handler context. + int dispatch_commands (void); + + /// Queue of commands for deferred execution. + ACE_Unbounded_Queue<ACE_Command_Base *> command_queue_; + + /// The mutual exclusion mechanism for the command queue. + ACE_SYNCH_MUTEX command_mutex_; +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + + /// The underlying Timer_Queue. + TQ* timer_queue_; + + /// Keeps track of whether we should delete the timer queue (if we + /// didn't create it, then we don't delete it). + int delete_timer_queue_; + + /// The mutual exclusion mechanism that is required to use the + /// <condition_>. + ACE_SYNCH_RECURSIVE_MUTEX mutex_; + + /** + * The dispatching thread sleeps on this condition while waiting to + * dispatch the next timer; it is used to wake it up if there is a + * change on the timer queue. + */ + ACE_SYNCH_RECURSIVE_CONDITION condition_; + + /// When deactivate is called this variable turns to false and the + /// dispatching thread is signalled, to terminate its main loop. + int active_; + + /// Thread id of our active object task. + ACE_thread_t thr_id_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/Timer_Queue_Adapters.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +# include "ace/Timer_Queue_Adapters.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +# pragma implementation ("Timer_Queue_Adapters.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_QUEUE_ADAPTERS_H */ |