Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Thread_Timer_Queue_Adapter_Test.cpp
blobb5d62df79a66a07ba6d11863773c6c06641050f9
1 /**
2 * @file Thread_Timer_Queue_Adapter_Test.cpp
4 * @author Alon Diamant <diamant.alon@gmail.com>
6 * This test verifies the functionality of the ACE_Timer_Queue_Thread_Adapter.
7 * It also shows the usage of custom event handlers.
8 */
9 //=============================================================================
11 #include "ace/Timer_Wheel.h"
12 #include "ace/Timer_Queue_Adapters.h"
13 #include "ace/Truncate.h"
14 #include "test_config.h"
16 #if defined (ACE_HAS_THREADS)
18 /// ICustomEventHandler
19 ///
20 /// Used to demonstrate the usage of custom event handlers. This is called by the
21 /// timer queue thread adapter.
22 class ICustomEventHandler
24 public:
25 /// Default constructor.
26 ///
27 /// @return
28 ICustomEventHandler()
32 /// Default destructor.
33 ///
34 /// @return
35 virtual ~ICustomEventHandler()
39 /// Main functor method.
40 ///
41 /// @return int
42 /// @param p_vParameter
43 virtual int operator() (void* p_vParameter) = 0;
46 /// CCustomEventHandlerUpcall
47 ///
48 /// Implements the Upcall interface used by the ACE_Timer_Queue, specifically for the
49 /// ICustomEventHandler interface.
50 class CCustomEventHandlerUpcall
52 public:
53 using TTimerQueue = ACE_Timer_Queue_T<ICustomEventHandler *, CCustomEventHandlerUpcall, ACE_Null_Mutex>;
55 /// Default constructor
56 CCustomEventHandlerUpcall()
60 /// Destructor.
61 ~CCustomEventHandlerUpcall()
65 /// This method is called when the timer expires.
66 int timeout (TTimerQueue&,
67 ICustomEventHandler* p_Handler,
68 const void* p_vParameter,
69 int /*recurring_timer*/,
70 const ACE_Time_Value& /*cur_time*/)
72 ACE_TRACE("timeout");
74 return (*p_Handler)(const_cast<void*> (p_vParameter));
77 /// This method is called when a timer is registered.
78 int registration(TTimerQueue&, ICustomEventHandler*, const void*) { return 0; }
80 /// This method is called before the timer expires.
81 int preinvoke(TTimerQueue&, ICustomEventHandler*, const void*,
82 int, const ACE_Time_Value&, const void*&) { return 0; }
84 /// This method is called after the timer expires.
85 int postinvoke(TTimerQueue&, ICustomEventHandler*, const void*,
86 int, const ACE_Time_Value&, const void*) { return 0; }
88 /// This method is called when a handler is canceled
89 int cancel_type(TTimerQueue&, ICustomEventHandler*, int, int&) { return 0; }
91 /// This method is called when a timer is canceled
92 int cancel_timer(TTimerQueue&, ICustomEventHandler* p_Handler, int, int)
94 ACE_TRACE("cancel_timer");
95 delete p_Handler;
96 return 0;
99 /// This method is called when the timer queue is destroyed and
100 /// the timer is still contained in it
101 int deletion(TTimerQueue&, ICustomEventHandler* p_Handler, const void*)
103 ACE_TRACE("deletion");
104 delete p_Handler;
105 return 0;
109 /// ICustomEventHandler
111 /// Used to demonstrate the usage of custom event handlers. This is called by the
112 /// timer queue thread adapter.
113 class CTestEventHandler : public ICustomEventHandler
115 public:
116 /// Default constructor.
118 /// @return
119 CTestEventHandler(long* p_iCallCount)
120 : m_p_iCallCount(p_iCallCount)
122 ACE_DEBUG((LM_DEBUG, ACE_TEXT("%I(%t) Initializing test event handler.\n")));
125 /// Default destructor.
127 /// @return
128 ~CTestEventHandler() override
130 ACE_DEBUG((LM_DEBUG, ACE_TEXT("%I(%t) Destroying test event handler.\n")));
133 /// Main functor method.
135 /// @return int
136 /// @param p_vParameter
137 int operator() (void* p_vParameter) override
139 long iParameter = ACE_Utils::truncate_cast<long> ((intptr_t)p_vParameter);
141 ACE_DEBUG((LM_DEBUG,
142 ACE_TEXT("%I(%t) Incrementing test event handler call count by %d.\n"),
143 iParameter));
145 m_Mutex.acquire();
146 *m_p_iCallCount += iParameter;
147 m_Mutex.release();
149 // Success
150 return 0;
153 private:
154 long* m_p_iCallCount;
155 ACE_Thread_Mutex m_Mutex;
158 // Used for the actual timer queue thread adapter
159 using TTimerWheel = ACE_Timer_Wheel_T<ICustomEventHandler *, CCustomEventHandlerUpcall, ACE_Null_Mutex>;
160 using TTimerWheelIterator = ACE_Timer_Wheel_Iterator_T<ICustomEventHandler *, CCustomEventHandlerUpcall, ACE_Null_Mutex>;
161 using TTimerWheelThreadAdapter = ACE_Thread_Timer_Queue_Adapter<TTimerWheel, ICustomEventHandler *>;
163 #endif /* ACE_HAS_THREADS */
166 run_main (int, ACE_TCHAR *[])
168 ACE_START_TEST (ACE_TEXT ("Thread_Timer_Queue_Adapter_Test"));
170 #if defined (ACE_HAS_THREADS)
172 // Start the thread adapter
173 TTimerWheelThreadAdapter TimerWheelThreadAdapter;
174 TimerWheelThreadAdapter.activate();
176 // Single timer
178 // Create a test event handler
179 long iCallCount = 0;
180 CTestEventHandler* p_TestEventHandler = 0;
181 ACE_NEW_RETURN(p_TestEventHandler, CTestEventHandler(&iCallCount), -1);
183 ACE_DEBUG((LM_DEBUG,
184 ACE_TEXT("%I(%t) Scheduling timer...\n")));
186 TimerWheelThreadAdapter.schedule(p_TestEventHandler,
187 (void*) 1,
188 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0));
190 ACE_OS::sleep(ACE_Time_Value(1, 100 * 1000));
191 ACE_TEST_ASSERT(iCallCount == 1);
193 delete p_TestEventHandler;
195 ACE_DEBUG((LM_DEBUG, ACE_TEXT("%I(%t) Success in Single timer test.\n")));
198 // Single timer with cancellation
200 // Create a test event handler
201 long iCallCount = 0;
202 CTestEventHandler* p_TestEventHandler = 0;
203 ACE_NEW_RETURN(p_TestEventHandler, CTestEventHandler(&iCallCount), -1);
205 ACE_DEBUG((LM_DEBUG,
206 ACE_TEXT("%I(%t) Scheduling timer...\n")));
208 long lTimerHandle =
209 TimerWheelThreadAdapter.schedule(p_TestEventHandler,
210 (void*) 1,
211 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0));
213 // Cancel the repeating timer
214 TimerWheelThreadAdapter.cancel(lTimerHandle);
216 ACE_OS::sleep(ACE_Time_Value(1, 100 * 1000));
218 ACE_TEST_ASSERT(iCallCount == 0);
220 // Test event handler was deleted by the timer.
222 ACE_DEBUG((LM_DEBUG, ACE_TEXT("%I(%t) Success in Single timer with cancellation test.\n")));
225 // Repeating timer with cancellation
227 // Create a test event handler
228 long iCallCount = 0;
229 CTestEventHandler* p_TestEventHandler = 0;
230 ACE_NEW_RETURN(p_TestEventHandler, CTestEventHandler(&iCallCount), -1);
232 ACE_DEBUG((LM_DEBUG,
233 ACE_TEXT("%I(%t) Scheduling timer...\n")));
235 long lTimerHandle =
236 TimerWheelThreadAdapter.schedule
237 (p_TestEventHandler,
238 (void*) 1,
239 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0),
240 ACE_Time_Value(1, 0));
242 ACE_OS::sleep(ACE_Time_Value(3, 500 * 1000));
243 ACE_TEST_ASSERT(iCallCount == 3);
245 // Cancel the repeating timer
246 TimerWheelThreadAdapter.cancel(lTimerHandle);
248 ACE_TEST_ASSERT(iCallCount == 3);
250 ACE_DEBUG((LM_DEBUG,
251 ACE_TEXT("%I(%t) Success in Repeating timer with cancellation test.\n")));
254 // Multiple timers
256 // Create a test event handler
257 long iCallCount = 0;
258 CTestEventHandler* p_TestEventHandler = 0;
259 ACE_NEW_RETURN(p_TestEventHandler, CTestEventHandler(&iCallCount), -1);
261 ACE_DEBUG((LM_DEBUG,
262 ACE_TEXT("%I(%t) Scheduling timer...\n")));
264 TimerWheelThreadAdapter.schedule
265 (p_TestEventHandler,
266 (void*) 1,
267 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0));
269 TimerWheelThreadAdapter.schedule
270 (p_TestEventHandler,
271 (void*) 1,
272 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0));
274 TimerWheelThreadAdapter.schedule
275 (p_TestEventHandler,
276 (void*) 1,
277 ACE_OS::gettimeofday() + ACE_Time_Value(2, 0));
279 ACE_OS::sleep(ACE_Time_Value(3, 0));
280 ACE_TEST_ASSERT(iCallCount == 3);
282 delete p_TestEventHandler;
284 ACE_DEBUG((LM_DEBUG, ACE_TEXT("%I(%t) Success in Multiple timers test.\n")));
287 #else
288 ACE_ERROR ((LM_INFO,
289 ACE_TEXT ("threads not supported on this platform\n")));
290 #endif /* ACE_HAS_THREADS */
291 ACE_END_TEST;
293 return 0;