Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Timer_Queue_Adapters.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Timer_Queue_Adapters.h
00006  *
00007  *  $Id: Timer_Queue_Adapters.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00008  *
00009  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu> and
00010  *          Carlos O'Ryan <coryan@uci.edu>
00011  */
00012 //=============================================================================
00013 
00014 #ifndef ACE_TIMER_QUEUE_ADAPTERS_H
00015 #define ACE_TIMER_QUEUE_ADAPTERS_H
00016 #include "ace/pre.h"
00017 
00018 #include "ace/Task.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "ace/Signal.h"
00025 
00026 /**
00027  * @class ACE_Async_Timer_Queue_Adapter
00028  *
00029  * @brief Adapts a <TQ> to be run asynchronously.
00030  *
00031  * This implementation uses the <ualarm> call, which generates
00032  * the SIGARLM signal that is caught by this class.
00033  */
00034 template <class TQ>
00035 class ACE_Async_Timer_Queue_Adapter : public ACE_Event_Handler
00036 {
00037 public:
00038   typedef TQ TIMER_QUEUE;
00039 
00040   /// Constructor
00041   /**
00042    * Register the SIGALRM handler.  If <mask> == 0 then block all
00043    * signals when <SIGALRM> is run.  Otherwise, just block the signals
00044    * indicated in <mask>.
00045    */
00046   ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask = 0);
00047 
00048   /// Schedule the timer according to the semantics of the
00049   /// <ACE_Timer_List>.
00050   /**
00051    * This timer gets dispatched via a signal, rather than by a user
00052    * calling expire().  Note that interval timers are not implemented
00053    * yet.
00054    */
00055   long schedule (ACE_Event_Handler *type,
00056                  const void *act,
00057                  const ACE_Time_Value &future_time,
00058                  const ACE_Time_Value &interval = ACE_Time_Value::zero);
00059 
00060   /// Cancel the @a timer_id and pass back the @a act if an address is
00061   /// passed in.
00062   int cancel (long timer_id, const void **act = 0);
00063 
00064   /// Dispatch all timers whose values are <= <cur_time>.  Returns the
00065   /// number of timers canceled.
00066   int expire (void);
00067 
00068   /// Access the underlying <TIMER_QUEUE>.
00069   TQ &timer_queue (void);
00070 
00071 private:
00072   /// Perform the logic to compute the new ualarm(2) setting.
00073   virtual int schedule_ualarm (void);
00074 
00075   /// Called back by <SIGALRM> handler.
00076   virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
00077 
00078   /// Handler for the <SIGALRM> signal, so that we can access our state
00079   /// without requiring any global variables.
00080   ACE_Sig_Handler sig_handler_;
00081 
00082   /// Implementation of the timer queue (e.g., <ACE_Timer_List>,
00083   /// <ACE_Timer_Heap>, etc.).
00084   TQ timer_queue_;
00085 
00086   /// Mask of signals to be blocked when we're servicing <SIGALRM>.
00087   ACE_Sig_Set mask_;
00088 };
00089 
00090 /**
00091  * @class ACE_Thread_Timer_Queue_Adapter
00092  *
00093  * @brief Adapts a Timer_Queue using a separate thread for dispatching.
00094  *
00095  * This implementation of a Timer_Queue uses a separate thread to
00096  * dispatch the timers. The base queue need not be thread safe,
00097  * this class takes all the necessary locks.
00098  *
00099  * @note This is a case where template parameters will be useful, but
00100  * (IMHO) the effort and portability problems discourage their
00101  * use.
00102  *
00103  */
00104 template <class TQ>
00105 class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base
00106 {
00107 public:
00108   /// Trait for the underlying queue type.
00109   typedef TQ TIMER_QUEUE;
00110 
00111 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
00112 
00113   /// Typedef for the position at which to enqueue a deferred
00114   /// execution command.
00115   enum COMMAND_ENQUEUE_POSITION {HEAD, TAIL};
00116 
00117 # endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
00118 
00119   /// Creates the timer queue.  Activation of the task is the user's
00120   /// responsibility. Optionally a pointer to a timer queue can be passed,
00121   /// when no pointer is passed, a TQ is dynamically created
00122   ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager * = ACE_Thread_Manager::instance (),
00123                                   TQ* timer_queue = 0);
00124 
00125   /// Destructor.
00126   virtual ~ACE_Thread_Timer_Queue_Adapter (void);
00127 
00128   /// Schedule the timer according to the semantics of the <TQ>; wakes
00129   /// up the dispatching thread.
00130   long schedule (ACE_Event_Handler *handler,
00131                  const void *act,
00132                  const ACE_Time_Value &future_time,
00133                  const ACE_Time_Value &interval = ACE_Time_Value::zero);
00134 
00135   /// Cancel the <timer_id> and return the <act> parameter if an
00136   /// address is passed in. Also wakes up the dispatching thread.
00137   int cancel (long timer_id, const void **act = 0);
00138 
00139   /// Runs the dispatching thread.
00140   virtual int svc (void);
00141 
00142   /// Inform the dispatching thread that it should terminate.
00143   virtual void deactivate (void);
00144 
00145   /// Access the locking mechanism, useful for iteration.
00146   ACE_SYNCH_RECURSIVE_MUTEX &mutex (void);
00147 
00148   /// @deprecated Access the implementation queue, useful for iteration.
00149   /// Use the method that returns a pointer instead
00150   TQ &timer_queue (void);
00151 
00152   /// Set a user-specified timer queue.
00153   int timer_queue (TQ *tq);
00154 
00155   /// Return the current <TQ>.
00156   TQ *timer_queue (void) const;
00157 
00158   /// Return the thread id of our active object.
00159   ACE_thread_t thr_id (void) const;
00160 
00161   /**
00162    * We override the default activate() method so that we can ensure
00163    * that only a single thread is ever spawned.  Otherwise, too many
00164    * weird things can happen...
00165    */
00166   virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE,
00167                         int n_threads = 1,
00168                         int force_active = 0,
00169                         long priority = ACE_DEFAULT_THREAD_PRIORITY,
00170                         int grp_id = -1,
00171                         ACE_Task_Base *task = 0,
00172                         ACE_hthread_t thread_handles[] = 0,
00173                         void *stack[] = 0,
00174                         size_t stack_size[] = 0,
00175                         ACE_thread_t thread_names[] = 0);
00176 
00177 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
00178 
00179   /**
00180    * Enqueues a command object for execution just before waiting on the next
00181    * timer event. This allows deferred execution of commands that cannot
00182    * be performed in the timer event handler context, such as registering
00183    * or cancelling timers on platforms where the timer queue mutex is not
00184    * recursive.
00185    */
00186   int enqueue_command (ACE_Command_Base *command_,
00187                        COMMAND_ENQUEUE_POSITION pos = TAIL);
00188 
00189 # endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
00190 
00191 private:
00192 
00193 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
00194   /// Dispatches all command objects enqueued in the most
00195   /// recent event handler context.
00196   int dispatch_commands (void);
00197 
00198   /// Queue of commands for deferred execution.
00199   ACE_Unbounded_Queue<ACE_Command_Base *> command_queue_;
00200 
00201   /// The mutual exclusion mechanism for the command queue.
00202   ACE_SYNCH_MUTEX command_mutex_;
00203 # endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
00204 
00205   /// The underlying Timer_Queue.
00206   TQ* timer_queue_;
00207 
00208   /// Keeps track of whether we should delete the timer queue (if we
00209   /// didn't create it, then we don't delete it).
00210   int delete_timer_queue_;
00211 
00212   /// The mutual exclusion mechanism that is required to use the
00213   /// <condition_>.
00214   ACE_SYNCH_RECURSIVE_MUTEX mutex_;
00215 
00216   /**
00217    * The dispatching thread sleeps on this condition while waiting to
00218    * dispatch the next timer; it is used to wake it up if there is a
00219    * change on the timer queue.
00220    */
00221   ACE_SYNCH_RECURSIVE_CONDITION condition_;
00222 
00223   /// When deactivate is called this variable turns to false and the
00224   /// dispatching thread is signalled, to terminate its main loop.
00225   int active_;
00226 
00227   /// Thread id of our active object task.
00228   ACE_thread_t thr_id_;
00229 };
00230 
00231 #if defined (__ACE_INLINE__)
00232 # include "ace/Timer_Queue_Adapters.i"
00233 #endif /* __ACE_INLINE__ */
00234 
00235 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
00236 # include "ace/Timer_Queue_Adapters.cpp"
00237 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
00238 
00239 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
00240 # pragma implementation ("Timer_Queue_Adapters.cpp")
00241 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
00242 
00243 #include "ace/post.h"
00244 #endif /* ACE_TIMER_QUEUE_ADAPTERS_H */

Generated on Mon Jun 16 11:21:51 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002