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.
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
20 /// Used to demonstrate the usage of custom event handlers. This is called by the
21 /// timer queue thread adapter.
22 class ICustomEventHandler
25 /// Default constructor.
32 /// Default destructor.
35 virtual ~ICustomEventHandler()
39 /// Main functor method.
42 /// @param p_vParameter
43 virtual int operator() (void* p_vParameter
) = 0;
46 /// CCustomEventHandlerUpcall
48 /// Implements the Upcall interface used by the ACE_Timer_Queue, specifically for the
49 /// ICustomEventHandler interface.
50 class CCustomEventHandlerUpcall
53 using TTimerQueue
= ACE_Timer_Queue_T
<ICustomEventHandler
*, CCustomEventHandlerUpcall
, ACE_Null_Mutex
>;
55 /// Default constructor
56 CCustomEventHandlerUpcall()
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*/)
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");
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");
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
116 /// Default constructor.
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.
128 ~CTestEventHandler() override
130 ACE_DEBUG((LM_DEBUG
, ACE_TEXT("%I(%t) Destroying test event handler.\n")));
133 /// Main functor method.
136 /// @param p_vParameter
137 int operator() (void* p_vParameter
) override
139 long iParameter
= ACE_Utils::truncate_cast
<long> ((intptr_t)p_vParameter
);
142 ACE_TEXT("%I(%t) Incrementing test event handler call count by %d.\n"),
146 *m_p_iCallCount
+= iParameter
;
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();
178 // Create a test event handler
180 CTestEventHandler
* p_TestEventHandler
= 0;
181 ACE_NEW_RETURN(p_TestEventHandler
, CTestEventHandler(&iCallCount
), -1);
184 ACE_TEXT("%I(%t) Scheduling timer...\n")));
186 TimerWheelThreadAdapter
.schedule(p_TestEventHandler
,
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
202 CTestEventHandler
* p_TestEventHandler
= 0;
203 ACE_NEW_RETURN(p_TestEventHandler
, CTestEventHandler(&iCallCount
), -1);
206 ACE_TEXT("%I(%t) Scheduling timer...\n")));
209 TimerWheelThreadAdapter
.schedule(p_TestEventHandler
,
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
229 CTestEventHandler
* p_TestEventHandler
= 0;
230 ACE_NEW_RETURN(p_TestEventHandler
, CTestEventHandler(&iCallCount
), -1);
233 ACE_TEXT("%I(%t) Scheduling timer...\n")));
236 TimerWheelThreadAdapter
.schedule
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);
251 ACE_TEXT("%I(%t) Success in Repeating timer with cancellation test.\n")));
256 // Create a test event handler
258 CTestEventHandler
* p_TestEventHandler
= 0;
259 ACE_NEW_RETURN(p_TestEventHandler
, CTestEventHandler(&iCallCount
), -1);
262 ACE_TEXT("%I(%t) Scheduling timer...\n")));
264 TimerWheelThreadAdapter
.schedule
267 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0));
269 TimerWheelThreadAdapter
.schedule
272 ACE_OS::gettimeofday() + ACE_Time_Value(1, 0));
274 TimerWheelThreadAdapter
.schedule
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")));
289 ACE_TEXT ("threads not supported on this platform\n")));
290 #endif /* ACE_HAS_THREADS */