Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / examples / Timer_Queue / Thread_Timer_Queue_Test.cpp
blob5c238e99af1f30c43fa4125191569fbdd991fa0e
2 //=============================================================================
3 /**
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"
16 #include "ace/Task.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),
29 id_ (0)
33 Handler::~Handler ()
37 void
38 Handler::set_id (int id)
40 this->id_ = id;
43 // This is the method invoked when the Timer expires.
45 int
46 Handler::handle_timeout (const ACE_Time_Value &current_time,
47 const void *)
49 ACE_Time_Value delay = current_time - this->expires_;
51 // No need to protect this printf is always called from a Async safe
52 // point.
53 ACE_OS::printf ("\nexpiring timer %d at %lu.%7.7lu secs\n"
54 "\tthere was a %lu.%7.7lu secs delay\n",
55 this->id_,
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.
61 delete this;
62 return 0;
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 ()),
68 queue_ (queue),
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
75 // user.
77 int
78 Input_Task::svc ()
80 for (;;)
81 // call back to the driver's implementation on how to read and
82 // parse input.
83 if (this->driver_.get_next_request () == -1)
84 break;
86 // we are done.
87 this->queue_->deactivate ();
88 ACE_DEBUG ((LM_DEBUG,
89 "terminating input thread\n"));
90 return 0;
93 // schedule a new timer. This method will be called from inside the
94 // <Timer_Queue_Test_Driver> class. (see Command pattern)
96 int
97 Input_Task::add_timer (void *argument)
99 u_long useconds = *reinterpret_cast<int *> (argument);
100 ACE_Time_Value interval (useconds / usecs_,
101 useconds % usecs_);
102 ACE_Time_Value expire_at = ACE_OS::gettimeofday () + interval;
104 Handler *h;
106 ACE_NEW_RETURN (h,
107 Handler (expire_at),
108 -1);
110 int id = queue_->schedule (h, 0, expire_at);
112 if (id == -1)
113 ACE_ERROR_RETURN ((LM_ERROR,
114 "schedule failed"),
115 -1);
117 // We store the id into the handler, this is only used to produce
118 // nicer messages.
119 h->set_id (id);
121 ACE_OS::printf ("scheduling timer %d\n",
122 id);
123 return 0;
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.
143 this->dump ();
145 return 0;
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 ();
157 #else
158 // Cancel the thread timer queue task "preemptively."
159 if (ACE_Thread::cancel (this->queue_->thr_id ()) == -1)
160 ACE_ERROR ((LM_ERROR,
161 "%p\n",
162 "cancel"));
163 #endif /* ACE_LACKS_PTHREAD_CANCEL */
165 // -1 indicates we are shutting down the application.
166 return -1;
169 void
170 Input_Task::dump ()
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 ());
178 i.item () != 0;
179 i.next ())
180 i.item ()->dump ();
182 ACE_DEBUG ((LM_DEBUG,
183 "end dumping timer queue\n"));
186 // constructor
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 ()
200 this->init ();
201 return 0;
205 Thread_Timer_Queue_Test_Driver::display_menu ()
207 static char menu[] =
208 "Usage:\n"
209 "1 <microseconds>: setups a new timer\n"
210 "2 <timerid>: removes a timer\n"
211 "3 : prints timer queue\n"
212 "4 : exit\n";
214 ACE_DEBUG ((LM_DEBUG,
215 "%s",
216 menu));
217 return 0;
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),
229 -1);
231 ACE_NEW_RETURN (cancel_cmd_,
232 CMD (input_task_, &Input_Task::cancel_timer),
233 -1);
235 ACE_NEW_RETURN (list_cmd_,
236 CMD (input_task_, &Input_Task::list_timer),
237 -1);
239 ACE_NEW_RETURN (shutdown_cmd_,
240 CMD (input_task_, &Input_Task::shutdown_timer),
241 -1);
243 if (this->input_task_.activate () == -1)
244 ACE_ERROR_RETURN ((LM_ERROR,
245 "cannot activate input task"),
246 -1);
247 else if (this->timer_queue_.activate () == -1)
248 ACE_ERROR_RETURN ((LM_ERROR,
249 "cannot activate timer queue"),
250 -1);
251 else if (ACE_Thread_Manager::instance ()->wait () == -1)
252 ACE_ERROR_RETURN ((LM_ERROR,
253 "wait on Thread_Manager failed"),
254 -1);
255 return 0;