Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / tests / Reactor_Timer_Test.cpp
blob04318c2e0dd63b547c3caa884ab907c425c4bc58
1 //=============================================================================
2 /**
3 * @file Reactor_Timer_Test.cpp
5 * This is a simple test that illustrates the timer mechanism of
6 * the reactor. Scheduling timers, resetting timer intervals,
7 * handling expired timers and cancelling scheduled timers are
8 * all exercised in this test.
10 * @author Prashant Jain <pjain@cs.wustl.edu> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
12 //=============================================================================
14 #include "test_config.h"
15 #include "ace/Timer_Queue.h"
16 #include "ace/Reactor.h"
17 #include "ace/High_Res_Timer.h"
18 #include "ace/Trace.h"
19 #include "ace/Recursive_Thread_Mutex.h"
20 #include "ace/Log_Msg.h"
21 #include "ace/Timer_Heap.h"
22 #include <memory>
24 static int done = 0;
25 static int the_count = 0;
26 static int odd = 0;
28 class Time_Handler : public ACE_Event_Handler
30 public:
31 /// Default constructor
32 Time_Handler ();
34 /// Handle the timeout.
35 int handle_timeout (const ACE_Time_Value &tv,
36 const void *arg) override;
38 /// Called when <Time_Handler> is removed.
39 int handle_close (ACE_HANDLE handle,
40 ACE_Reactor_Mask close_mask) override;
42 /// Return our timer id.
43 long timer_id () const;
45 /// Set our timer id;
46 void timer_id (long);
48 private:
49 /// Stores the id of this timer.
50 long timer_id_;
53 Time_Handler::Time_Handler ()
54 : timer_id_ (-1)
56 // Nothing
59 int
60 Time_Handler::handle_close (ACE_HANDLE handle,
61 ACE_Reactor_Mask close_mask)
63 ACE_DEBUG ((LM_DEBUG,
64 ACE_TEXT ("[%x] handle = %d, close_mask = %d, timer id = %d\n"),
65 this,
66 handle,
67 close_mask,
68 this->timer_id ()));
69 return 0;
72 int
73 Time_Handler::handle_timeout (const ACE_Time_Value &tv,
74 const void *arg)
76 long current_count = static_cast<long> (reinterpret_cast<size_t> (arg));
77 if (current_count >= 0)
78 ACE_TEST_ASSERT (current_count == the_count);
80 ACE_DEBUG ((LM_DEBUG,
81 ACE_TEXT ("[%x] Timer id %d with count #%d|%d timed out at %d!\n"),
82 this,
83 this->timer_id (),
84 the_count,
85 current_count,
86 tv.sec ()));
88 if (current_count == long (ACE_MAX_TIMERS - 1))
89 done = 1;
90 else if (the_count == long (ACE_MAX_TIMERS - 1))
92 done = 1;
93 return -1;
95 else if (current_count == -1)
97 int result = ACE_Reactor::instance ()->reset_timer_interval (this->timer_id (),
98 std::chrono::seconds {the_count + 1});
99 if (result == -1)
100 ACE_ERROR ((LM_ERROR,
101 ACE_TEXT ("Error resetting timer interval\n")));
103 the_count += (1 + odd);
104 return 0;
107 long
108 Time_Handler::timer_id () const
110 return this->timer_id_;
113 void
114 Time_Handler::timer_id (long t)
116 this->timer_id_ = t;
119 static void
120 test_registering_all_handlers ()
122 ACE_Trace t (ACE_TEXT ("test_registering_all_handler"),
123 __LINE__,
124 ACE_TEXT_CHAR_TO_TCHAR (__FILE__));
125 Time_Handler rt[ACE_MAX_TIMERS];
126 long t_id[ACE_MAX_TIMERS];
128 for (size_t i = 0; i < ACE_MAX_TIMERS; i++)
130 t_id[i] =
131 ACE_Reactor::instance ()->schedule_timer (&rt[i],
132 (const void *) i,
133 std::chrono::seconds {2 * i + 1});
134 ACE_TEST_ASSERT (t_id[i] != -1);
135 rt[i].timer_id (t_id[i]);
138 while (!done)
139 ACE_Reactor::instance ()->handle_events ();
142 static void
143 test_registering_one_handler ()
145 ACE_Trace t (ACE_TEXT ("test_registering_one_handler"),
146 __LINE__,
147 ACE_TEXT_CHAR_TO_TCHAR (__FILE__));
148 Time_Handler rt[ACE_MAX_TIMERS];
149 long t_id[ACE_MAX_TIMERS];
151 done = 0;
152 the_count = 0;
154 for (size_t i = 0; i < ACE_MAX_TIMERS; i++)
156 t_id[i] =
157 ACE_Reactor::instance ()->schedule_timer (&rt[0],
158 (const void *) i,
159 ACE_Time_Value (2 * i + 1));
160 ACE_TEST_ASSERT (t_id[i] != -1);
163 while (!done)
164 ACE_Reactor::instance ()->handle_events ();
167 static void
168 test_canceling_odd_timers ()
170 ACE_Trace t (ACE_TEXT ("test_canceling_odd_timers"),
171 __LINE__,
172 ACE_TEXT_CHAR_TO_TCHAR (__FILE__));
173 Time_Handler rt[ACE_MAX_TIMERS];
174 long t_id[ACE_MAX_TIMERS];
176 done = 0;
177 the_count = 1;
178 odd = 1;
180 for (size_t i = 0; i < ACE_MAX_TIMERS; i++)
182 t_id[i] = ACE_Reactor::instance ()->schedule_timer (&rt[i],
183 (const void *) i,
184 ACE_Time_Value (2 * i + 1));
185 ACE_TEST_ASSERT (t_id[i] != -1);
186 rt[i].timer_id (t_id[i]);
189 for (size_t j = 0; (u_long) j < ACE_MAX_TIMERS; j++)
190 // Cancel handlers with odd numbered timer ids.
191 if (ACE_ODD (rt[j].timer_id ()))
193 int result =
194 ACE_Reactor::instance ()->cancel_timer (rt[j].timer_id ());
195 if (result == -1)
196 ACE_ERROR ((LM_ERROR,
197 ACE_TEXT ("Error cancelling timer\n")));
200 while (!done)
201 ACE_Reactor::instance ()->handle_events ();
204 static void
205 test_resetting_timer_intervals ()
207 ACE_Trace t (ACE_TEXT ("test_resetting_timer_intervals"),
208 __LINE__,
209 ACE_TEXT_CHAR_TO_TCHAR (__FILE__));
210 Time_Handler rt;
211 long t_id;
213 done = 0;
214 the_count = 0;
215 odd = 0;
217 t_id =
218 ACE_Reactor::instance ()->schedule_timer
219 (&rt,
220 (const void *) -1,
221 ACE_Time_Value (1),
222 // Start off by making this an interval timer.
223 ACE_Time_Value (1));
225 ACE_TEST_ASSERT (t_id != -1);
226 rt.timer_id (t_id);
228 while (!done)
229 ACE_Reactor::instance ()->handle_events ();
232 // If any command line arg is given, run the test with high res timer
233 // queue. Else run it normally.
235 run_main (int argc, ACE_TCHAR *[])
237 ACE_START_TEST (ACE_TEXT ("Reactor_Timer_Test"));
239 if (argc > 1)
241 ACE_DEBUG ((LM_DEBUG,
242 ACE_TEXT ("Running with high-res timer queue\n")));
243 ACE_Reactor *r = ACE_Reactor::instance ();
245 (void) ACE_High_Res_Timer::global_scale_factor ();
247 // Change the source of time in the Reactor to the
248 // high-resolution timer. Why does this test require such
249 // precision for a 1 second timer is beyond me ... I think it
250 // is a cut&paste error.
252 // The use of auto_ptr<> is optional, ACE uses dangerous memory
253 // management idioms everywhere, I thought I could demonstrate how
254 // to do it right in at least one test. Notice the lack of
255 // ACE_NEW_RETURN, that monstrosity has no business in proper C++
256 // code ...
257 std::unique_ptr<ACE_Timer_Heap_Variable_Time_Source> tq(
258 new ACE_Timer_Heap_Variable_Time_Source);
259 // ... notice how the policy is in the derived timer queue type.
260 // The abstract timer queue does not have a time policy ...
261 tq->set_time_policy(&ACE_High_Res_Timer::gettimeofday_hr);
262 // ... and then the timer queue is replaced. Strangely, the
263 // Reactor does *not* copy the timers, it just deletes the
264 // existing timer queue ....
265 r->timer_queue(tq.get());
266 // ... the Reactor has assumed ownership, release the
267 // auto_ptr<> ...
268 tq.release();
271 // Register all different handlers, i.e., one per timer.
272 test_registering_all_handlers ();
274 // Now try multiple timers for ONE event handler (should produce the
275 // same result).
276 test_registering_one_handler ();
278 // Try canceling handlers with odd numbered timer ids.
279 test_canceling_odd_timers ();
281 // Make sure <reset_timer_inverval> works.
282 test_resetting_timer_intervals ();
284 ACE_END_TEST;
285 return 0;