2 //=============================================================================
4 * @file Thread_Timer_Queue_Test.cpp
6 * This test exercises the <ACE_Thread_Timer_Queue_Adapter>
7 * using an <ACE_Timer_Heap>.
9 * @author Carlos O'Ryan <coryan@cs.wustl.edu> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
11 //=============================================================================
14 #include "ace/OS_NS_stdio.h"
15 #include "ace/OS_NS_sys_time.h"
17 #include "ace/Timer_Heap_T.h"
18 #include "ace/Timer_Queue_Adapters.h"
20 #include "Thread_Timer_Queue_Test.h"
22 #include "ace/Condition_T.h"
23 #include "ace/Thread_Mutex.h"
26 // Administrivia methods...
27 Handler::Handler(const ACE_Time_Value
&expiration_time
)
28 : expires_ (expiration_time
),
38 Handler::set_id (int id
)
43 // This is the method invoked when the Timer expires.
46 Handler::handle_timeout (const ACE_Time_Value
¤t_time
,
49 ACE_Time_Value delay
= current_time
- this->expires_
;
51 // No need to protect this printf is always called from a Async safe
53 ACE_OS::printf ("\nexpiring timer %d at %lu.%7.7lu secs\n"
54 "\tthere was a %lu.%7.7lu secs delay\n",
56 static_cast<unsigned long> (current_time
.sec ()),
57 static_cast<unsigned long> (current_time
.usec ()),
58 static_cast<unsigned long> (delay
.sec ()),
59 static_cast<unsigned long> (delay
.usec ()));
60 // Notice this delete is protected.
65 Input_Task::Input_Task (Thread_Timer_Queue
*queue
,
66 Thread_Timer_Queue_Test_Driver
&timer_queue_driver
)
67 : ACE_Task_Base (ACE_Thread_Manager::instance ()),
69 usecs_ (ACE_ONE_SECOND_IN_USECS
),
70 driver_ (timer_queue_driver
)
74 // Svc method is called from the thread library to read input from the
81 // call back to the driver's implementation on how to read and
83 if (this->driver_
.get_next_request () == -1)
87 this->queue_
->deactivate ();
89 "terminating input thread\n"));
93 // schedule a new timer. This method will be called from inside the
94 // <Timer_Queue_Test_Driver> class. (see Command pattern)
97 Input_Task::add_timer (void *argument
)
99 u_long useconds
= *reinterpret_cast<int *> (argument
);
100 ACE_Time_Value
interval (useconds
/ usecs_
,
102 ACE_Time_Value expire_at
= ACE_OS::gettimeofday () + interval
;
110 int id
= queue_
->schedule (h
, 0, expire_at
);
113 ACE_ERROR_RETURN ((LM_ERROR
,
117 // We store the id into the handler, this is only used to produce
121 ACE_OS::printf ("scheduling timer %d\n",
126 // Cancel a timer. This method will be called from inside the
127 // <Timer_Queue_Test_Driver> class. (see Command pattern)
130 Input_Task::cancel_timer (void *argument
)
132 return this->queue_
->cancel (*reinterpret_cast<int *> (argument
));
135 // Lists the timers in the queue. Ignores the argument. This method
136 // will be called from inside the <Timer_Queue_Test_Driver> class.
137 // (see Command pattern)
140 Input_Task::list_timer (void *)
142 // Dump the timer queue contents.
148 // Shutdown the timer queue. Return -1 indicates to the
149 // <Timer_Queue_Test_Driver> class that we are done.
152 Input_Task::shutdown_timer (void *)
154 #if defined (ACE_LACKS_PTHREAD_CANCEL)
155 // Cancel the thread timer queue task "voluntarily."
156 this->queue_
->deactivate ();
158 // Cancel the thread timer queue task "preemptively."
159 if (ACE_Thread::cancel (this->queue_
->thr_id ()) == -1)
160 ACE_ERROR ((LM_ERROR
,
163 #endif /* ACE_LACKS_PTHREAD_CANCEL */
165 // -1 indicates we are shutting down the application.
172 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, ace_mon
, this->queue_
->mutex ());
174 ACE_DEBUG ((LM_DEBUG
,
175 "begin dumping timer queue\n"));
177 for (Timer_Heap_Iterator
i (*this->queue_
->timer_queue ());
182 ACE_DEBUG ((LM_DEBUG
,
183 "end dumping timer queue\n"));
188 Thread_Timer_Queue_Test_Driver::Thread_Timer_Queue_Test_Driver ()
189 : input_task_ (&timer_queue_
, *this)
193 Thread_Timer_Queue_Test_Driver::~Thread_Timer_Queue_Test_Driver ()
198 Thread_Timer_Queue_Test_Driver::run_test ()
205 Thread_Timer_Queue_Test_Driver::display_menu ()
209 "1 <microseconds>: setups a new timer\n"
210 "2 <timerid>: removes a timer\n"
211 "3 : prints timer queue\n"
214 ACE_DEBUG ((LM_DEBUG
,
221 Thread_Timer_Queue_Test_Driver::init ()
223 typedef Command
<Input_Task
, Input_Task::ACTION
> CMD
;
225 // initialize the <Command> objects with their corresponding
226 // methods from <Input_Task>
227 ACE_NEW_RETURN (schedule_cmd_
,
228 CMD (input_task_
, &Input_Task::add_timer
),
231 ACE_NEW_RETURN (cancel_cmd_
,
232 CMD (input_task_
, &Input_Task::cancel_timer
),
235 ACE_NEW_RETURN (list_cmd_
,
236 CMD (input_task_
, &Input_Task::list_timer
),
239 ACE_NEW_RETURN (shutdown_cmd_
,
240 CMD (input_task_
, &Input_Task::shutdown_timer
),
243 if (this->input_task_
.activate () == -1)
244 ACE_ERROR_RETURN ((LM_ERROR
,
245 "cannot activate input task"),
247 else if (this->timer_queue_
.activate () == -1)
248 ACE_ERROR_RETURN ((LM_ERROR
,
249 "cannot activate timer queue"),
251 else if (ACE_Thread_Manager::instance ()->wait () == -1)
252 ACE_ERROR_RETURN ((LM_ERROR
,
253 "wait on Thread_Manager failed"),