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 */
1.2.14 written by Dimitri van Heesch,
© 1997-2002