// -*- C++ -*- // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // Timer_Queue_Adapters.h // // = AUTHOR // Douglas C. Schmidt and Carlos O'Ryan // // ============================================================================ #if !defined (ACE_TIMER_QUEUE_ADAPTERS_H) #define ACE_TIMER_QUEUE_ADAPTERS_H #include "ace/Task.h" #include "ace/Signal.h" template class ACE_Export ACE_Async_Timer_Queue_Adapter : public ACE_Event_Handler { // = TITLE // Adapts a to be run asynchronously. // // = DESCRIPTION // This implementation uses the call, which generates // the SIGARLM signal that is caught by this class. public: typedef TQ TIMER_QUEUE; ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask = 0); // Register the SIGALRM handler. If == 0 then block all // signals when is run. Otherwise, just block the signals // indicated in . long schedule (ACE_Event_Handler *type, const void *act, const ACE_Time_Value &delay, const ACE_Time_Value &interval = ACE_Time_Value::zero); // Schedule the timer according to the semantics of the // . However, this timer gets dispatched via a // signal, rather than by a user calling . int cancel (long timer_id, const void **act = 0); // Cancel the and pass back the if an address is // passed in. int expire (void); // Dispatch all timers whose values are <= . Returns the // number of timers canceled. TQ &timer_queue (void); // Access the underlying . private: virtual int schedule_ualarm (void); // Perform the logic to compute the new ualarm(2) setting. virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); // Called back by handler. ACE_Sig_Handler sig_handler_; // Handler for the signal, so that we can access our state // without requiring any global variables. TQ timer_queue_; // Implementation of the timer queue (e.g., , // , etc.). ACE_Sig_Set mask_; // Mask of signals to be blocked when we're servicing . }; template class ACE_Export ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base { // = TITLE // Adapts a Timer_Queue using a separate thread for dispatching. // // = DESCRIPTION // This implementation of a Timer_Queue 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 were template parameters will be useful, but // (IMHO) the effort and portability problems discourage their // use. public: typedef TQ TIMER_QUEUE; ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager * = ACE_Thread_Manager::instance ()); // Creates the timer queue. Activation of the task is the user's // responsibility. long schedule (ACE_Event_Handler* handler, const void *act, const ACE_Time_Value &delay, const ACE_Time_Value &interval = ACE_Time_Value::zero); // Schedule the timer according to the semantics of the ; wakes // up the dispatching thread. int cancel (long timer_id, const void **act = 0); // Cancel the add return the parameter if an // address is passed in. Also wakes up the dispatching thread. virtual int svc (void); // Runs the dispatching thread. virtual void deactivate (void); // Inform the dispatching thread that it should terminate. ACE_SYNCH_MUTEX &mutex (void); // Access the locking mechanism, useful for iteration. TQ &timer_queue (void); // Access the implementation queue, useful for iteration. ACE_thread_t thr_id (void); // Return the thread id of our active object. virtual int activate (long flags = THR_NEW_LWP, 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); // We override the default method so that we can ensure // that only a single thread is ever spawned. Otherwise, too many // weird things can happen... private: TQ timer_queue_; // The underlying Timer_Queue. ACE_SYNCH_CONDITION condition_; // 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_MUTEX mutex_; // The mutual exclusion mechanism which is required to use the // . int active_; // When deactivate is called this variable turns to false and the // dispatching thread is signalled, to terminate its main loop. ACE_thread_t thr_id_; // Thread id of our active object task. }; #if defined (__ACE_INLINE__) #include "ace/Timer_Queue_Adapters.i" #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 */ #endif /* ACE_TIMER_QUEUE_ADAPTERS_H */