2 //=============================================================================
4 * @file Async_Timer_Queue_Test.cpp
6 * This test exercises the <ACE_Asynch_Timer_Queue_Adapter>
7 * using an <ACE_Timer_Heap>.
9 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu> and Sergio Flores-Gaitan <sergio@cs.wustl.edu>
11 //=============================================================================
14 #include "ace/OS_NS_sys_time.h"
15 #include "ace/Signal.h"
16 #include "ace/Timer_Heap.h"
17 #include "ace/Timer_Queue_Adapters.h"
19 #include "Async_Timer_Queue_Test.h"
22 // Hook method that is called to handle the expiration of a timer.
24 Async_Timer_Handler::handle_timeout (const ACE_Time_Value
&tv
,
27 // Print some information here (note that this is not strictly
28 // signal-safe since the ACE logging mechanism uses functions that
29 // aren't guaranteed to work in all signal handlers).
31 "handle_timeout() = (%d, %d) %d\n",
41 // Initialize the Singleton pointer.
42 Async_Timer_Queue
*Async_Timer_Queue::instance_
= 0;
44 // Implement the Singleton logic.
46 Async_Timer_Queue::instance ()
48 if (Async_Timer_Queue::instance_
== 0)
50 // Initialize with all signals enabled.
53 // But, don't block out SIGQUIT since we always want that
54 // signal to interrupt the program.
57 ACE_NEW_RETURN (Async_Timer_Queue::instance_
, Async_Timer_Queue (&ss
), 0);
59 return Async_Timer_Queue::instance_
;
62 // Sets the signal set to mask, for the timer queue.
64 Async_Timer_Queue::Async_Timer_Queue (ACE_Sig_Set
*ss
) :
69 // Dump the contents of the queue when we receive ^C.
72 Async_Timer_Queue::dump ()
74 ACE_DEBUG ((LM_DEBUG
, "begin dumping timer queue\n"));
76 // This iterator is implicitly protected since SIGINT and SIGALRM
77 // signals cannot occur while it is running.
79 for (ACE_Timer_Heap_Iterator
iter (this->tq_
.timer_queue ());
82 iter
.item ()->dump ();
84 ACE_DEBUG ((LM_DEBUG
, "end dumping timer queue\n"));
90 Async_Timer_Queue::schedule (u_int microsecs
)
92 ACE_Time_Value
tv (0, microsecs
);
94 // Create a new Event_Handler for our timer.
96 ACE_Event_Handler
*eh
;
97 ACE_NEW (eh
, Async_Timer_Handler
);
99 // Schedule the timer to run in the future.
100 long tid
= this->tq_
.schedule(eh
,
101 0, // Note that our "magic cookie" ACT is always NULL.
102 ACE_OS::gettimeofday () + tv
);
105 ACE_ERROR ((LM_ERROR
, "%p\n", "schedule_timer"));
111 Async_Timer_Queue::cancel (long timer_id
)
113 ACE_DEBUG ((LM_DEBUG
, "canceling %d\n", timer_id
));
117 if (this->tq_
.cancel (timer_id
, &act
) == -1)
118 ACE_ERROR ((LM_ERROR
, "%p\n", "cancel_timer"));
120 // In this case, the act will be 0, but it could be a real pointer
122 delete (ACE_Event_Handler
*) act
;
125 // Schedule timer hook method. This method is called from the driver.
128 Async_Timer_Queue::schedule_timer (void *argument
)
130 u_long useconds
= *(int *)argument
;
133 Async_Timer_Queue::instance ()->schedule (useconds
);
138 // Cancel timer hook method. Is called from the driver class.
141 Async_Timer_Queue::cancel_timer (void *argument
)
143 u_long id
= *(int *)argument
;
146 Async_Timer_Queue::instance ()->cancel (id
);
151 // Dummy list timer hook method. The listing of timers is done from a
152 // signal handler using SIGINT, not from the driver.
155 Async_Timer_Queue::list_timer (void *)
157 // Display an error message.
158 ACE_ERROR_RETURN ((LM_ERROR
, "invalid input\n"), 0);
161 // Dummy shutdown timer hook method. The shutdown of the timer queue
162 // is done with a signal handler using SIGQUIT, not from the driver.
165 Async_Timer_Queue::shutdown_timer (void *)
167 // Display an error message.
168 ACE_ERROR_RETURN ((LM_ERROR
, "invalid input\n"), 0);
171 // Handler for the SIGINT and SIGQUIT signals.
174 signal_handler (int signum
)
176 ACE_DEBUG ((LM_DEBUG
, "handling signal %S\n", signum
));
181 Async_Timer_Queue::instance ()->dump ();
185 #if !defined (ACE_LACKS_UNIX_SIGNALS)
187 ACE_ERROR ((LM_ERROR
, "shutting down on SIGQUIT%a\n", 1));
194 // Register the signal handlers for SIGQUIT and SIGINT. We must
195 // ensure that the SIGINT handler isn't interrupted by SIGALRM.
196 // However, SIGQUIT is never blocked...
199 register_signal_handlers ()
201 #if !defined (ACE_LACKS_UNIX_SIGNALS)
202 // Register SIGQUIT (never blocked).
203 ACE_Sig_Action
sigquit ((ACE_SignalHandler
) signal_handler
, SIGQUIT
);
204 ACE_UNUSED_ARG (sigquit
);
207 // Don't let the SIGALRM interrupt the SIGINT handler!
209 ss
.sig_add (SIGALRM
);
211 // Register SIGINT (note that system calls will be restarted
213 ACE_Sig_Action
sigint ((ACE_SignalHandler
) signal_handler
,
217 ACE_UNUSED_ARG (sigint
);
222 Async_Timer_Queue_Test_Driver::Async_Timer_Queue_Test_Driver ()
226 // displays the menu of options.
229 Async_Timer_Queue_Test_Driver::display_menu ()
231 // The menu of options provided to the user.
234 "1) schedule timer <usecs>\n"
235 "2) cancel timer <timer_id>\n"
237 "^\\ exit program\n";
239 ACE_DEBUG ((LM_DEBUG
, "%s", menu
));
243 // Initializes the test driver.
246 Async_Timer_Queue_Test_Driver::init ()
248 typedef Command
<Async_Timer_Queue
, Async_Timer_Queue::ACTION
> CMD
;
250 // Initialize <Command> objects with their corresponding <Input_Task> methods.
251 ACE_NEW_RETURN (schedule_cmd_
,
252 CMD (*Async_Timer_Queue::instance (),
253 &Async_Timer_Queue::schedule_timer
),
256 ACE_NEW_RETURN (cancel_cmd_
,
257 CMD (*Async_Timer_Queue::instance (),
258 &Async_Timer_Queue::cancel_timer
),
261 ACE_NEW_RETURN (list_cmd_
,
262 CMD (*Async_Timer_Queue::instance (),
263 &Async_Timer_Queue::list_timer
),
266 ACE_NEW_RETURN (shutdown_cmd_
,
267 CMD (*Async_Timer_Queue::instance (),
268 &Async_Timer_Queue::shutdown_timer
),
271 register_signal_handlers ();