/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // Timer_Queue.h // // = AUTHOR // Doug Schmidt // // ============================================================================ #if !defined (ACE_TIMER_QUEUE_H) #define ACE_TIMER_QUEUE_H #include "ace/Event_Handler.h" #include "ace/Time_Value.h" #include "ace/Synch.h" // This should be nested within the ACE_Timer_Queue class but some C++ // compilers still don't like this... struct ACE_Timer_Node // = TITLE // Maintains the state associated with a Timer entry. { friend class ACE_Timer_Queue; private: ACE_Timer_Node (ACE_Event_Handler *h, const void *a, const ACE_Time_Value &t, const ACE_Time_Value &i, ACE_Timer_Node *n, int timer_id); // Constructor. ACE_Event_Handler *handler_; // Handler to invoke on when a timeout occurs. const void *arg_; // Argument to pass to . ACE_Time_Value timer_value_; // Time until the timer expires. ACE_Time_Value interval_; // If this is a periodic timer this holds the time until the next // timeout. ACE_Timer_Node *next_; // Pointer to next timer. int timer_id_; // Id of this timer (used to cancel timers before they expire). ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. void dump (void) const; // Dump the state of an object. }; class ACE_Export ACE_Timer_Queue // = TITLE // Provides an interface to timers. // // = DESCRIPTION // This is a simple implementation that uses a linked list of // absolute times. A more clever implementation would use a // delta-list, a heap, or timing wheels, etc. { public: // = Initialization and termination methods. ACE_Timer_Queue (void); // Default constructor. virtual ~ACE_Timer_Queue (void); int is_empty (void) const; // True if queue is empty, else false. const ACE_Time_Value &earliest_time (void) const; // Returns the time of the earlier node in the Timer_Queue. virtual int schedule (ACE_Event_Handler *event_handler, const void *arg, const ACE_Time_Value &delay, const ACE_Time_Value &interval = ACE_Time_Value::zero); // Schedule an that will expire after amount // of time. If it expires then is passed in as the value to // the 's callback method. If // is != to then it is used to // reschedule the automatically. This method // returns a timer handle that uniquely identifies the // in an internal list. This timer handle can be // used to cancel an 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. virtual int cancel (ACE_Event_Handler *event_handler); // Cancel all that match the address of // . virtual int cancel (int timer_id, const void **arg = 0); // Cancel the single that matches the // value (which was returned from the method). If arg is // non-NULL then it will be set to point to the ``magic cookie'' // argument passed in when the was registered. This // makes it possible to free up the memory and avoid memory leaks. virtual int expire (const ACE_Time_Value ¤t_time); // Run the method for all Timers whose values are // <= . virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max); // Determine the next event to timeout. Returns if there are // no pending timers or if all pending timers are longer than max. void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. private: ACE_Time_Value timeout_; // Returned by calculate_timeout. virtual void reschedule (ACE_Timer_Node *); // Reschedule a "period" Timer_Node. ACE_Timer_Node *head_; // Pointer to linked list of ACE_Timer_Handles. int timer_id_; // Keeps track of the timer id that uniquely identifies each timer. // This id can be used to cancel a timer via the // method. #if defined (ACE_MT_SAFE) ACE_Recursive_Thread_Mutex lock_; // Synchronization variable for the MT_SAFE ACE_Reactor #endif /* ACE_MT_SAFE */ }; #include "ace/Timer_Queue.i" #endif /* ACE_TIMER_QUEUE_H */