Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Timer_Queue_Adapters.h
blob6e731a1caf9ca0dd8a9f05041adc77bf917a8335
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Timer_Queue_Adapters.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu> and
8 * Carlos O'Ryan <coryan@uci.edu>
9 */
10 //=============================================================================
12 #ifndef ACE_TIMER_QUEUE_ADAPTERS_H
13 #define ACE_TIMER_QUEUE_ADAPTERS_H
14 #include /**/ "ace/pre.h"
16 #include "ace/Task.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 # pragma once
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #include "ace/Signal.h"
23 #include "ace/Sig_Handler.h"
24 #include "ace/Condition_Recursive_Thread_Mutex.h"
26 #if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
27 # include "ace/Unbounded_Queue.h"
28 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
29 class ACE_Command_Base;
30 ACE_END_VERSIONED_NAMESPACE_DECL
31 #endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
33 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
35 class ACE_Sig_Set;
37 /**
38 * @class ACE_Async_Timer_Queue_Adapter
40 * @brief Adapts an ACE timer queue to be driven asynchronously using signals.
42 * This implementation uses the ACE_OS::ualarm call, to generate
43 * the SIGARLM signal that is caught by this class.
45 * @note This adapter only works on platforms that support ualarm().
46 * POSIX platforms generally do; Windows and some others do not.
48 * @todo This adapter does not automatically reschedule repeating timers.
50 template <class TQ, class TYPE = ACE_Event_Handler*>
51 class ACE_Async_Timer_Queue_Adapter : public ACE_Event_Handler
53 public:
54 typedef TQ TIMER_QUEUE;
56 /// Constructor
57 /**
58 * Register the SIGALRM handler. If @a mask == 0 then block all
59 * signals when @c SIGALRM is run. Otherwise, just block the signals
60 * indicated in @a mask.
62 ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask = 0);
64 /// Schedule the timer according to the semantics of the
65 /// ACE_Timer_List.
66 /**
67 * This timer gets dispatched via a signal, rather than by a user
68 * calling expire(). Note that interval timers are not implemented
69 * yet.
71 long schedule (TYPE type,
72 const void *act,
73 const ACE_Time_Value &future_time,
74 const ACE_Time_Value &interval = ACE_Time_Value::zero);
76 /// Cancel the @a timer_id and pass back the @a act if an address is
77 /// passed in.
78 int cancel (long timer_id, const void **act = 0);
80 /// Dispatch all timers with expiry time at or before the current time.
81 /// Returns the number of timers expired.
82 int expire ();
84 /// Return a reference to the underlying timer queue.
85 TQ &timer_queue ();
87 private:
88 /// Perform the logic to compute the new ualarm(2) setting.
89 virtual int schedule_ualarm ();
91 /// Called back by @c SIGALRM handler.
92 virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
94 /// Handler for the @c SIGALRM signal, so that we can access our state
95 /// without requiring any global variables.
96 ACE_Sig_Handler sig_handler_;
98 /// Implementation of the timer queue (e.g., ACE_Timer_List,
99 /// ACE_Timer_Heap, etc.).
100 TQ timer_queue_;
102 /// Mask of signals to be blocked when we're servicing @c SIGALRM.
103 ACE_Sig_Set mask_;
107 * @class ACE_Thread_Timer_Queue_Adapter
109 * @brief Adapts an ACE timer queue using a separate thread for dispatching.
111 * This implementation uses a separate thread to dispatch the timers.
112 * The base queue need not be thread safe; this class takes all the
113 * necessary locks.
115 * @note This is a case where template parameters will be useful, but
116 * (IMHO) the effort and portability problems discourage their
117 * use.
119 template <class TQ, class TYPE = ACE_Event_Handler*>
120 class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base
122 public:
123 /// Trait for the underlying queue type.
124 typedef TQ TIMER_QUEUE;
126 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
128 /// Typedef for the position at which to enqueue a deferred
129 /// execution command.
130 enum COMMAND_ENQUEUE_POSITION {HEAD, TAIL};
132 # endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
134 /// Creates the timer queue. Activation of the task is the user's
135 /// responsibility. Optionally a pointer to a timer queue can be passed,
136 /// when no pointer is passed, a TQ is dynamically created
137 ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager * = ACE_Thread_Manager::instance (),
138 TQ* timer_queue = 0);
140 /// Destructor.
141 virtual ~ACE_Thread_Timer_Queue_Adapter ();
143 /// Schedule the timer according to the semantics of the <TQ>; wakes
144 /// up the dispatching thread.
145 long schedule (TYPE handler,
146 const void *act,
147 const ACE_Time_Value &future_time,
148 const ACE_Time_Value &interval = ACE_Time_Value::zero);
150 /// Cancel the @a timer_id and return the @a act parameter if an
151 /// address is passed in. Also wakes up the dispatching thread.
152 int cancel (long timer_id, const void **act = 0);
154 /// Runs the dispatching thread.
155 virtual int svc ();
157 /// Inform the dispatching thread that it should terminate.
158 virtual void deactivate ();
160 /// Access the locking mechanism, useful for iteration.
161 ACE_SYNCH_RECURSIVE_MUTEX &mutex ();
163 /// Set a user-specified timer queue.
164 int timer_queue (TQ *tq);
166 /// Return the current <TQ>.
167 TQ *timer_queue () const;
169 /// Return the thread id of our active object.
170 ACE_thread_t thr_id () const;
173 * We override the default activate() method so that we can ensure
174 * that only a single thread is ever spawned. Otherwise, too many
175 * weird things can happen...
177 virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE,
178 int n_threads = 1,
179 int force_active = 0,
180 long priority = ACE_DEFAULT_THREAD_PRIORITY,
181 int grp_id = -1,
182 ACE_Task_Base *task = 0,
183 ACE_hthread_t thread_handles[] = 0,
184 void *stack[] = 0,
185 size_t stack_size[] = 0,
186 ACE_thread_t thread_ids[] = 0,
187 const char* thr_name[] = 0);
189 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
192 * Enqueues a command object for execution just before waiting on the next
193 * timer event. This allows deferred execution of commands that cannot
194 * be performed in the timer event handler context, such as registering
195 * or cancelling timers on platforms where the timer queue mutex is not
196 * recursive.
198 int enqueue_command (ACE_Command_Base *command_,
199 COMMAND_ENQUEUE_POSITION pos = TAIL);
201 # endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
203 private:
204 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
205 /// Dispatches all command objects enqueued in the most
206 /// recent event handler context.
207 int dispatch_commands ();
209 /// Queue of commands for deferred execution.
210 ACE_Unbounded_Queue<ACE_Command_Base *> command_queue_;
212 /// The mutual exclusion mechanism for the command queue.
213 ACE_SYNCH_MUTEX command_mutex_;
214 # endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
216 /// The underlying Timer_Queue.
217 TQ* timer_queue_;
219 /// Keeps track of whether we should delete the timer queue (if we
220 /// didn't create it, then we don't delete it).
221 bool delete_timer_queue_;
223 /// The mutual exclusion mechanism that is required to use the
224 /// <condition_>.
225 ACE_SYNCH_RECURSIVE_MUTEX mutex_;
227 /// Attributes to initialize condition with.
228 /* We only need this because some crappy compilers can't
229 properly handle initializing the conditions with
230 temporary objects. */
231 ACE_Condition_Attributes_T<typename TQ::time_policy_t> cond_attr_;
234 * The dispatching thread sleeps on this condition while waiting to
235 * dispatch the next timer; it is used to wake it up if there is a
236 * change on the timer queue.
238 ACE_SYNCH_RECURSIVE_CONDITION condition_;
240 /// When deactivate is called this variable turns to false and the
241 /// dispatching thread is signalled, to terminate its main loop.
242 bool active_;
244 /// Thread id of our active object task.
245 ACE_thread_t thr_id_;
248 ACE_END_VERSIONED_NAMESPACE_DECL
250 #if defined (__ACE_INLINE__)
251 # include "ace/Timer_Queue_Adapters.inl"
252 #endif /* __ACE_INLINE__ */
254 # include "ace/Timer_Queue_Adapters.cpp"
256 #include /**/ "ace/post.h"
257 #endif /* ACE_TIMER_QUEUE_ADAPTERS_H */