Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Timer_Queue_Reference_Counting_Test.cpp
blob2ada4183a345cd33451f3a5bffcab3e93ffc3fa9
2 //=============================================================================
3 /**
4 * @file Timer_Queue_Reference_Counting_Test.cpp
6 * This test is used to check reference counting of the Event
7 * Handler when it interacts with Timer Queues.
9 * @author Irfan Pyarali <irfan@oomworks.com>
11 //=============================================================================
14 #include "test_config.h"
15 #include "ace/Get_Opt.h"
16 #include "ace/Timer_Queue.h"
17 #include "ace/Timer_Heap.h"
18 #include "ace/Timer_List.h"
19 #include "ace/Timer_Hash.h"
20 #include "ace/Timer_Wheel.h"
21 #include "ace/Reactor.h"
22 #include "ace/Recursive_Thread_Mutex.h"
23 #include "ace/Null_Mutex.h"
24 #include "ace/OS_NS_unistd.h"
27 static int debug = 0;
28 static const char *one_second_timeout = "one second timeout";
29 static const char *two_second_timeout = "two second timeout";
31 namespace
33 inline void WAIT_FOR_NEXT_EVENT (ACE_Timer_Queue &timer_queue)
35 ACE_Time_Value const earliest_time = timer_queue.earliest_time ();
36 ACE_Time_Value const time_of_day = timer_queue.gettimeofday ();
37 if (earliest_time > time_of_day)
39 ACE_OS::sleep (earliest_time - time_of_day);
44 class Reference_Counted_Event_Handler : public ACE_Event_Handler
46 public:
47 Reference_Counted_Event_Handler (int expected_number_of_handle_close_calls);
49 ~Reference_Counted_Event_Handler () override;
51 int handle_timeout (const ACE_Time_Value &,
52 const void *) override;
54 int handle_close (ACE_HANDLE handle,
55 ACE_Reactor_Mask masks) override;
57 int expected_number_of_handle_close_calls_;
58 int number_of_handle_close_calls_;
61 Reference_Counted_Event_Handler::Reference_Counted_Event_Handler (int expected_number_of_handle_close_calls)
62 : expected_number_of_handle_close_calls_ (expected_number_of_handle_close_calls),
63 number_of_handle_close_calls_ (0)
65 this->reference_counting_policy ().value
66 (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
68 if (debug)
69 ACE_DEBUG ((LM_DEBUG,
70 "Reference count in Reference_Counted_Event_Handler() is %d\n",
71 this->reference_count_.load ()));
74 Reference_Counted_Event_Handler::~Reference_Counted_Event_Handler ()
76 if (debug)
77 ACE_DEBUG ((LM_DEBUG,
78 "Reference count in ~Reference_Counted_Event_Handler() is %d\n",
79 this->reference_count_.load ()));
81 if (this->expected_number_of_handle_close_calls_ != -1)
82 ACE_TEST_ASSERT (this->number_of_handle_close_calls_ ==
83 this->expected_number_of_handle_close_calls_);
86 int
87 Reference_Counted_Event_Handler::handle_timeout (const ACE_Time_Value &,
88 const void *arg)
90 if (debug)
91 ACE_DEBUG ((LM_DEBUG,
92 "Reference count in Reference_Counted_Event_Handler::handle_timeout() for arg = %C is %d\n",
93 (const char *) arg,
94 this->reference_count_.load ()));
96 return 0;
99 int
100 Reference_Counted_Event_Handler::handle_close (ACE_HANDLE handle,
101 ACE_Reactor_Mask masks)
103 if (debug)
104 ACE_DEBUG ((LM_DEBUG,
105 "Reference_Counted_Event_Handler::handle_close() called with handle = %d and masks = %d. "
106 "Reference count is %d\n",
107 handle,
108 masks,
109 this->reference_count_.load ()));
111 ++this->number_of_handle_close_calls_;
113 return 0;
116 void
117 cancellation (ACE_Timer_Queue &timer_queue,
118 int repeat_timer,
119 int cancel_handler,
120 int second_timer,
121 int dont_call_handle_close)
123 int result = 0;
125 int expected_number_of_handle_close_calls = -1;
127 if (!dont_call_handle_close)
129 if (cancel_handler)
130 expected_number_of_handle_close_calls = 1;
131 else if (second_timer)
132 expected_number_of_handle_close_calls = 2;
133 else
134 expected_number_of_handle_close_calls = 1;
137 Reference_Counted_Event_Handler *handler =
138 new Reference_Counted_Event_Handler (expected_number_of_handle_close_calls);
140 ACE_Event_Handler_var safe_handler (handler);
142 long first_timer_id = -1;
143 long second_timer_id = -1;
145 if (repeat_timer)
147 first_timer_id =
148 timer_queue.schedule (handler,
149 one_second_timeout,
150 ACE_Time_Value (1) + timer_queue.gettimeofday (),
151 ACE_Time_Value (1));
152 ACE_TEST_ASSERT (first_timer_id != -1);
154 else
156 first_timer_id =
157 timer_queue.schedule (handler,
158 one_second_timeout,
159 ACE_Time_Value (1) + timer_queue.gettimeofday ());
160 ACE_TEST_ASSERT (first_timer_id != -1);
163 if (second_timer)
165 second_timer_id =
166 timer_queue.schedule (handler,
167 two_second_timeout,
168 ACE_Time_Value (2) + timer_queue.gettimeofday (),
169 ACE_Time_Value (2));
170 ACE_TEST_ASSERT (second_timer_id != -1);
173 if (cancel_handler)
175 result =
176 timer_queue.cancel (handler,
177 dont_call_handle_close);
179 if (second_timer)
180 ACE_TEST_ASSERT (result == 2);
181 else
182 ACE_TEST_ASSERT (result == 1);
184 else
186 result =
187 timer_queue.cancel (first_timer_id,
189 dont_call_handle_close);
190 ACE_TEST_ASSERT (result == 1);
192 if (second_timer)
194 result =
195 timer_queue.cancel (second_timer_id,
197 dont_call_handle_close);
198 ACE_TEST_ASSERT (result == 1);
203 template <class TIMER_QUEUE>
204 class cancellation_test
206 public:
207 cancellation_test (const char *);
210 template <class TIMER_QUEUE>
211 cancellation_test<TIMER_QUEUE>::cancellation_test (const char *timer_queue_type)
213 ACE_DEBUG ((LM_DEBUG,
214 "\nCancellation test for %C\n\n",
215 timer_queue_type));
217 int configs[][4] = {
218 { 0, 0, 0, 0, },
219 { 0, 0, 0, 1, },
220 { 0, 0, 1, 0, },
221 { 0, 0, 1, 1, },
222 { 0, 1, 0, 0, },
223 { 0, 1, 0, 1, },
224 { 0, 1, 1, 0, },
225 { 0, 1, 1, 1, },
226 { 1, 0, 0, 0, },
227 { 1, 0, 0, 1, },
228 { 1, 0, 1, 0, },
229 { 1, 0, 1, 1, },
230 { 1, 1, 0, 0, },
231 { 1, 1, 0, 1, },
232 { 1, 1, 1, 0, },
233 { 1, 1, 1, 1, },
236 for (int i = 0;
237 i < (int) (sizeof configs / (sizeof (int) * 5));
238 i++)
240 TIMER_QUEUE timer_queue;
242 cancellation (timer_queue,
243 configs[i][0],
244 configs[i][1],
245 configs[i][2],
246 configs[i][3]);
250 using Expire_Function = int (*)(ACE_Timer_Queue &);
253 invoke_expire (ACE_Timer_Queue &timer_queue)
255 return timer_queue.expire ();
259 invoke_one_upcall (ACE_Timer_Queue &timer_queue)
261 ACE_Noop_Command command;
262 return timer_queue.expire_single(command);
265 void
266 expire (ACE_Timer_Queue &timer_queue,
267 Expire_Function expire_function)
269 int events = 0;
270 int result = 0;
272 Reference_Counted_Event_Handler *handler =
273 new Reference_Counted_Event_Handler (1);
275 ACE_Event_Handler_var safe_handler (handler);
277 long timer_id =
278 timer_queue.schedule (handler,
279 one_second_timeout,
280 ACE_Time_Value (1) + timer_queue.gettimeofday (),
281 ACE_Time_Value (1));
282 ACE_TEST_ASSERT (timer_id != -1);
284 result =
285 timer_queue.schedule (handler,
286 two_second_timeout,
287 ACE_Time_Value (2) + timer_queue.gettimeofday ());
288 ACE_TEST_ASSERT (result != -1);
290 events += 4;
292 for (int i = 0; i < events;)
294 WAIT_FOR_NEXT_EVENT (timer_queue);
296 result =
297 expire_function (timer_queue);
299 ACE_TEST_ASSERT (result >= 0);
301 i += result;
304 timer_queue.cancel (timer_id, 0, 0);
307 template<class TIMER_QUEUE>
308 class expire_test
310 public:
311 expire_test (const char *);
314 template <class TIMER_QUEUE>
315 expire_test<TIMER_QUEUE>::expire_test (const char *timer_queue_type)
317 ACE_DEBUG ((LM_DEBUG,
318 "\nExpire test for %C\n\n",
319 timer_queue_type));
321 TIMER_QUEUE timer_queue;
323 expire (timer_queue,
324 invoke_expire);
327 template<class TIMER_QUEUE>
328 class upcall_test
330 public:
331 upcall_test (const char *);
334 template <class TIMER_QUEUE>
335 upcall_test<TIMER_QUEUE>::upcall_test (const char *timer_queue_type)
337 ACE_DEBUG ((LM_DEBUG,
338 "\nOne upcall test for %C\n\n",
339 timer_queue_type));
341 TIMER_QUEUE timer_queue;
343 expire (timer_queue,
344 invoke_one_upcall);
347 class Simple_Event_Handler : public ACE_Event_Handler
349 public:
350 Simple_Event_Handler ();
352 ~Simple_Event_Handler () override;
354 int handle_timeout (const ACE_Time_Value &,
355 const void *) override;
357 int handle_close (ACE_HANDLE,
358 ACE_Reactor_Mask) override;
361 Simple_Event_Handler::Simple_Event_Handler ()
363 if (debug)
364 ACE_DEBUG ((LM_DEBUG,
365 "Simple_Event_Handler()\n"));
368 Simple_Event_Handler::~Simple_Event_Handler ()
370 if (debug)
371 ACE_DEBUG ((LM_DEBUG,
372 "~Simple_Event_Handler()\n"));
376 Simple_Event_Handler::handle_timeout (const ACE_Time_Value &,
377 const void *arg)
379 if (debug)
380 ACE_DEBUG ((LM_DEBUG,
381 "Simple_Event_Handler::handle_timeout() for arg = %C\n",
382 (const char *) arg));
383 return 0;
387 Simple_Event_Handler::handle_close (ACE_HANDLE handle,
388 ACE_Reactor_Mask masks)
390 if (debug)
391 ACE_DEBUG ((LM_DEBUG,
392 "Simple_Event_Handler::handle_close() called with handle = %d and masks = %d.\n",
393 handle,
394 masks));
396 delete this;
398 return 0;
401 void
402 simple (ACE_Timer_Queue &timer_queue)
404 int events = 0;
405 int result = 0;
406 long timer_id = -1;
409 Simple_Event_Handler *handler =
410 new Simple_Event_Handler;
412 timer_id =
413 timer_queue.schedule (handler,
414 one_second_timeout,
415 ACE_Time_Value (1) + timer_queue.gettimeofday (),
416 ACE_Time_Value (1));
417 ACE_TEST_ASSERT (timer_id != -1);
419 result =
420 timer_queue.cancel (timer_id,
423 ACE_TEST_ASSERT (result == 1);
427 Simple_Event_Handler *handler =
428 new Simple_Event_Handler;
430 timer_id =
431 timer_queue.schedule (handler,
432 one_second_timeout,
433 ACE_Time_Value (1) + timer_queue.gettimeofday (),
434 ACE_Time_Value (1));
435 ACE_TEST_ASSERT (timer_id != -1);
437 events += 3;
440 for (int i = 0; i < events;)
442 WAIT_FOR_NEXT_EVENT (timer_queue);
444 result =
445 timer_queue.expire ();
447 ACE_TEST_ASSERT (result >= 0);
449 i += result;
452 timer_queue.cancel (timer_id, 0, 0);
455 template <class TIMER_QUEUE>
456 class simple_test
458 public:
459 simple_test (const char *);
462 template <class TIMER_QUEUE>
463 simple_test<TIMER_QUEUE>::simple_test (const char *timer_queue_type)
465 ACE_DEBUG ((LM_DEBUG,
466 "\nSimple test for %C\n\n",
467 timer_queue_type));
469 TIMER_QUEUE timer_queue;
471 simple (timer_queue);
474 static int heap = 1;
475 static int list = 1;
476 static int hash = 1;
477 static int wheel = 1;
478 static int hashheap = 1;
479 static int test_cancellation = 1;
480 static int test_expire = 1;
481 static int test_one_upcall = 1;
482 static int test_simple = 1;
484 static int
485 parse_args (int argc, ACE_TCHAR *argv[])
487 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:d:e:l:m:n:o:z:"));
489 int cc;
490 while ((cc = get_opt ()) != -1)
492 switch (cc)
494 case 'a':
495 heap = ACE_OS::atoi (get_opt.opt_arg ());
496 break;
497 case 'b':
498 list = ACE_OS::atoi (get_opt.opt_arg ());
499 break;
500 case 'c':
501 hash = ACE_OS::atoi (get_opt.opt_arg ());
502 break;
503 case 'd':
504 wheel = ACE_OS::atoi (get_opt.opt_arg ());
505 break;
506 case 'e':
507 hashheap = ACE_OS::atoi (get_opt.opt_arg ());
508 break;
509 case 'l':
510 test_cancellation = ACE_OS::atoi (get_opt.opt_arg ());
511 break;
512 case 'm':
513 test_expire = ACE_OS::atoi (get_opt.opt_arg ());
514 break;
515 case 'n':
516 test_one_upcall = ACE_OS::atoi (get_opt.opt_arg ());
517 break;
518 case 'o':
519 test_simple = ACE_OS::atoi (get_opt.opt_arg ());
520 break;
521 case 'z':
522 debug = ACE_OS::atoi (get_opt.opt_arg ());
523 break;
524 default:
525 ACE_ERROR ((LM_ERROR,
526 ACE_TEXT ("\nusage: %s \n\n")
527 ACE_TEXT ("\t[-a heap] (defaults to %d)\n")
528 ACE_TEXT ("\t[-b list] (defaults to %d)\n")
529 ACE_TEXT ("\t[-c hash] (defaults to %d)\n")
530 ACE_TEXT ("\t[-d wheel] (defaults to %d)\n")
531 ACE_TEXT ("\t[-e hashheap] (defaults to %d)\n")
532 ACE_TEXT ("\t[-l test_cancellation] (defaults to %d)\n")
533 ACE_TEXT ("\t[-m test_expire] (defaults to %d)\n")
534 ACE_TEXT ("\t[-n test_one_upcall] (defaults to %d)\n")
535 ACE_TEXT ("\t[-o test_simple] (defaults to %d)\n")
536 ACE_TEXT ("\t[-z debug] (defaults to %d)\n")
537 ACE_TEXT ("\n"),
538 argv[0],
539 heap,
540 list,
541 hash,
542 wheel,
543 hashheap,
544 test_cancellation,
545 test_expire,
546 test_one_upcall,
547 test_simple,
548 debug));
549 return -1;
553 return 0;
557 run_main (int argc, ACE_TCHAR *argv[])
559 ACE_START_TEST (ACE_TEXT ("Timer_Queue_Reference_Counting_Test"));
561 // Validate options.
562 int result =
563 parse_args (argc, argv);
564 if (result != 0)
565 return result;
567 if (test_cancellation)
569 ACE_DEBUG ((LM_DEBUG,
570 "\nCancellation test...\n\n"));
572 if (heap) { cancellation_test<ACE_Timer_Heap> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test); }
573 if (list) { cancellation_test<ACE_Timer_List> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test); }
574 if (hash) { cancellation_test<ACE_Timer_Hash> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test); }
575 if (wheel) { cancellation_test<ACE_Timer_Wheel> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test); }
576 if (hashheap) { cancellation_test<ACE_Timer_Hash_Heap> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test); }
579 if (test_expire)
581 ACE_DEBUG ((LM_DEBUG,
582 "\nExpire test...\n\n"));
584 if (heap) { expire_test<ACE_Timer_Heap> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test); }
585 if (list) { expire_test<ACE_Timer_List> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test); }
586 if (hash) { expire_test<ACE_Timer_Hash> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test); }
587 if (wheel) { expire_test<ACE_Timer_Wheel> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test); }
588 if (hashheap) { expire_test<ACE_Timer_Hash_Heap> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test); }
591 if (test_one_upcall)
593 ACE_DEBUG ((LM_DEBUG,
594 "\nOne upcall at a time test...\n\n"));
596 if (heap) { upcall_test<ACE_Timer_Heap> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test); }
597 if (list) { upcall_test<ACE_Timer_List> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test); }
598 if (hash) { upcall_test<ACE_Timer_Hash> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test); }
599 if (wheel) { upcall_test<ACE_Timer_Wheel> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test); }
600 if (hashheap) { upcall_test<ACE_Timer_Hash_Heap> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test); }
603 if (test_simple)
605 ACE_DEBUG ((LM_DEBUG,
606 "\nSimple test...\n\n"));
608 if (heap) { simple_test<ACE_Timer_Heap> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test); }
609 if (list) { simple_test<ACE_Timer_List> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test); }
610 if (hash) { simple_test<ACE_Timer_Hash> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test); }
611 if (wheel) { simple_test<ACE_Timer_Wheel> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test); }
612 if (hashheap) { simple_test<ACE_Timer_Hash_Heap> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test); }
615 ACE_END_TEST;
617 return 0;