2 //=============================================================================
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"
29 static const char *one_second_timeout
= "one second timeout";
30 static const char *two_second_timeout
= "two second timeout";
34 inline void WAIT_FOR_NEXT_EVENT (ACE_Timer_Queue
&timer_queue
)
36 ACE_Time_Value
const earliest_time
= timer_queue
.earliest_time ();
37 ACE_Time_Value
const time_of_day
= timer_queue
.gettimeofday ();
38 if (earliest_time
> time_of_day
)
40 ACE_OS::sleep (earliest_time
- time_of_day
);
45 class Reference_Counted_Event_Handler
: public ACE_Event_Handler
49 Reference_Counted_Event_Handler (int expected_number_of_handle_close_calls
);
51 ~Reference_Counted_Event_Handler () override
;
53 int handle_timeout (const ACE_Time_Value
&,
54 const void *) override
;
56 int handle_close (ACE_HANDLE handle
,
57 ACE_Reactor_Mask masks
) override
;
59 int expected_number_of_handle_close_calls_
;
60 int number_of_handle_close_calls_
;
63 Reference_Counted_Event_Handler::Reference_Counted_Event_Handler (int expected_number_of_handle_close_calls
)
64 : expected_number_of_handle_close_calls_ (expected_number_of_handle_close_calls
),
65 number_of_handle_close_calls_ (0)
67 this->reference_counting_policy ().value
68 (ACE_Event_Handler::Reference_Counting_Policy::ENABLED
);
72 "Reference count in Reference_Counted_Event_Handler() is %d\n",
73 this->reference_count_
.load ()));
76 Reference_Counted_Event_Handler::~Reference_Counted_Event_Handler ()
80 "Reference count in ~Reference_Counted_Event_Handler() is %d\n",
81 this->reference_count_
.load ()));
83 if (this->expected_number_of_handle_close_calls_
!= -1)
84 ACE_TEST_ASSERT (this->number_of_handle_close_calls_
==
85 this->expected_number_of_handle_close_calls_
);
89 Reference_Counted_Event_Handler::handle_timeout (const ACE_Time_Value
&,
94 "Reference count in Reference_Counted_Event_Handler::handle_timeout() for arg = %C is %d\n",
96 this->reference_count_
.load ()));
102 Reference_Counted_Event_Handler::handle_close (ACE_HANDLE handle
,
103 ACE_Reactor_Mask masks
)
106 ACE_DEBUG ((LM_DEBUG
,
107 "Reference_Counted_Event_Handler::handle_close() called with handle = %d and masks = %d. "
108 "Reference count is %d\n",
111 this->reference_count_
.load ()));
113 ++this->number_of_handle_close_calls_
;
119 cancellation (ACE_Timer_Queue
&timer_queue
,
123 int dont_call_handle_close
)
127 int expected_number_of_handle_close_calls
= -1;
129 if (!dont_call_handle_close
)
132 expected_number_of_handle_close_calls
= 1;
133 else if (second_timer
)
134 expected_number_of_handle_close_calls
= 2;
136 expected_number_of_handle_close_calls
= 1;
139 Reference_Counted_Event_Handler
*handler
=
140 new Reference_Counted_Event_Handler (expected_number_of_handle_close_calls
);
142 ACE_Event_Handler_var
safe_handler (handler
);
144 long first_timer_id
= -1;
145 long second_timer_id
= -1;
150 timer_queue
.schedule (handler
,
152 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
154 ACE_TEST_ASSERT (first_timer_id
!= -1);
159 timer_queue
.schedule (handler
,
161 ACE_Time_Value (1) + timer_queue
.gettimeofday ());
162 ACE_TEST_ASSERT (first_timer_id
!= -1);
168 timer_queue
.schedule (handler
,
170 ACE_Time_Value (2) + timer_queue
.gettimeofday (),
172 ACE_TEST_ASSERT (second_timer_id
!= -1);
178 timer_queue
.cancel (handler
,
179 dont_call_handle_close
);
182 ACE_TEST_ASSERT (result
== 2);
184 ACE_TEST_ASSERT (result
== 1);
189 timer_queue
.cancel (first_timer_id
,
191 dont_call_handle_close
);
192 ACE_TEST_ASSERT (result
== 1);
197 timer_queue
.cancel (second_timer_id
,
199 dont_call_handle_close
);
200 ACE_TEST_ASSERT (result
== 1);
205 template <class TIMER_QUEUE
>
206 class cancellation_test
209 cancellation_test (const char *);
212 template <class TIMER_QUEUE
>
213 cancellation_test
<TIMER_QUEUE
>::cancellation_test (const char *timer_queue_type
)
215 ACE_DEBUG ((LM_DEBUG
,
216 "\nCancellation test for %C\n\n",
239 i
< (int) (sizeof configs
/ (sizeof (int) * 5));
242 TIMER_QUEUE timer_queue
;
244 cancellation (timer_queue
,
252 using Expire_Function
= int (*)(ACE_Timer_Queue
&);
255 invoke_expire (ACE_Timer_Queue
&timer_queue
)
257 return timer_queue
.expire ();
261 invoke_one_upcall (ACE_Timer_Queue
&timer_queue
)
263 ACE_Noop_Command command
;
264 return timer_queue
.expire_single(command
);
268 expire (ACE_Timer_Queue
&timer_queue
,
269 Expire_Function expire_function
)
274 Reference_Counted_Event_Handler
*handler
=
275 new Reference_Counted_Event_Handler (1);
277 ACE_Event_Handler_var
safe_handler (handler
);
280 timer_queue
.schedule (handler
,
282 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
284 ACE_TEST_ASSERT (timer_id
!= -1);
287 timer_queue
.schedule (handler
,
289 ACE_Time_Value (2) + timer_queue
.gettimeofday ());
290 ACE_TEST_ASSERT (result
!= -1);
294 for (int i
= 0; i
< events
;)
296 WAIT_FOR_NEXT_EVENT (timer_queue
);
299 expire_function (timer_queue
);
301 ACE_TEST_ASSERT (result
>= 0);
306 timer_queue
.cancel (timer_id
, 0, 0);
309 template<class TIMER_QUEUE
>
313 expire_test (const char *);
316 template <class TIMER_QUEUE
>
317 expire_test
<TIMER_QUEUE
>::expire_test (const char *timer_queue_type
)
319 ACE_DEBUG ((LM_DEBUG
,
320 "\nExpire test for %C\n\n",
323 TIMER_QUEUE timer_queue
;
329 template<class TIMER_QUEUE
>
333 upcall_test (const char *);
336 template <class TIMER_QUEUE
>
337 upcall_test
<TIMER_QUEUE
>::upcall_test (const char *timer_queue_type
)
339 ACE_DEBUG ((LM_DEBUG
,
340 "\nOne upcall test for %C\n\n",
343 TIMER_QUEUE timer_queue
;
349 class Simple_Event_Handler
: public ACE_Event_Handler
353 Simple_Event_Handler ();
355 ~Simple_Event_Handler () override
;
357 int handle_timeout (const ACE_Time_Value
&,
358 const void *) override
;
360 int handle_close (ACE_HANDLE
,
361 ACE_Reactor_Mask
) override
;
364 Simple_Event_Handler::Simple_Event_Handler ()
367 ACE_DEBUG ((LM_DEBUG
,
368 "Simple_Event_Handler()\n"));
371 Simple_Event_Handler::~Simple_Event_Handler ()
374 ACE_DEBUG ((LM_DEBUG
,
375 "~Simple_Event_Handler()\n"));
379 Simple_Event_Handler::handle_timeout (const ACE_Time_Value
&,
383 ACE_DEBUG ((LM_DEBUG
,
384 "Simple_Event_Handler::handle_timeout() for arg = %C\n",
385 (const char *) arg
));
390 Simple_Event_Handler::handle_close (ACE_HANDLE handle
,
391 ACE_Reactor_Mask masks
)
394 ACE_DEBUG ((LM_DEBUG
,
395 "Simple_Event_Handler::handle_close() called with handle = %d and masks = %d.\n",
405 simple (ACE_Timer_Queue
&timer_queue
)
412 Simple_Event_Handler
*handler
=
413 new Simple_Event_Handler
;
416 timer_queue
.schedule (handler
,
418 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
420 ACE_TEST_ASSERT (timer_id
!= -1);
423 timer_queue
.cancel (timer_id
,
426 ACE_TEST_ASSERT (result
== 1);
430 Simple_Event_Handler
*handler
=
431 new Simple_Event_Handler
;
434 timer_queue
.schedule (handler
,
436 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
438 ACE_TEST_ASSERT (timer_id
!= -1);
443 for (int i
= 0; i
< events
;)
445 WAIT_FOR_NEXT_EVENT (timer_queue
);
448 timer_queue
.expire ();
450 ACE_TEST_ASSERT (result
>= 0);
455 timer_queue
.cancel (timer_id
, 0, 0);
458 template <class TIMER_QUEUE
>
462 simple_test (const char *);
465 template <class TIMER_QUEUE
>
466 simple_test
<TIMER_QUEUE
>::simple_test (const char *timer_queue_type
)
468 ACE_DEBUG ((LM_DEBUG
,
469 "\nSimple test for %C\n\n",
472 TIMER_QUEUE timer_queue
;
474 simple (timer_queue
);
480 static int wheel
= 1;
481 static int hashheap
= 1;
482 static int test_cancellation
= 1;
483 static int test_expire
= 1;
484 static int test_one_upcall
= 1;
485 static int test_simple
= 1;
488 parse_args (int argc
, ACE_TCHAR
*argv
[])
490 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("a:b:c:d:e:l:m:n:o:z:"));
493 while ((cc
= get_opt ()) != -1)
498 heap
= ACE_OS::atoi (get_opt
.opt_arg ());
501 list
= ACE_OS::atoi (get_opt
.opt_arg ());
504 hash
= ACE_OS::atoi (get_opt
.opt_arg ());
507 wheel
= ACE_OS::atoi (get_opt
.opt_arg ());
510 hashheap
= ACE_OS::atoi (get_opt
.opt_arg ());
513 test_cancellation
= ACE_OS::atoi (get_opt
.opt_arg ());
516 test_expire
= ACE_OS::atoi (get_opt
.opt_arg ());
519 test_one_upcall
= ACE_OS::atoi (get_opt
.opt_arg ());
522 test_simple
= ACE_OS::atoi (get_opt
.opt_arg ());
525 debug
= ACE_OS::atoi (get_opt
.opt_arg ());
528 ACE_ERROR ((LM_ERROR
,
529 ACE_TEXT ("\nusage: %s \n\n")
530 ACE_TEXT ("\t[-a heap] (defaults to %d)\n")
531 ACE_TEXT ("\t[-b list] (defaults to %d)\n")
532 ACE_TEXT ("\t[-c hash] (defaults to %d)\n")
533 ACE_TEXT ("\t[-d wheel] (defaults to %d)\n")
534 ACE_TEXT ("\t[-e hashheap] (defaults to %d)\n")
535 ACE_TEXT ("\t[-l test_cancellation] (defaults to %d)\n")
536 ACE_TEXT ("\t[-m test_expire] (defaults to %d)\n")
537 ACE_TEXT ("\t[-n test_one_upcall] (defaults to %d)\n")
538 ACE_TEXT ("\t[-o test_simple] (defaults to %d)\n")
539 ACE_TEXT ("\t[-z debug] (defaults to %d)\n")
560 run_main (int argc
, ACE_TCHAR
*argv
[])
562 ACE_START_TEST (ACE_TEXT ("Timer_Queue_Reference_Counting_Test"));
566 parse_args (argc
, argv
);
570 if (test_cancellation
)
572 ACE_DEBUG ((LM_DEBUG
,
573 "\nCancellation test...\n\n"));
575 if (heap
) { cancellation_test
<ACE_Timer_Heap
> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test
); }
576 if (list
) { cancellation_test
<ACE_Timer_List
> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test
); }
577 if (hash
) { cancellation_test
<ACE_Timer_Hash
> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test
); }
578 if (wheel
) { cancellation_test
<ACE_Timer_Wheel
> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test
); }
579 if (hashheap
) { cancellation_test
<ACE_Timer_Hash_Heap
> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test
); }
584 ACE_DEBUG ((LM_DEBUG
,
585 "\nExpire test...\n\n"));
587 if (heap
) { expire_test
<ACE_Timer_Heap
> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test
); }
588 if (list
) { expire_test
<ACE_Timer_List
> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test
); }
589 if (hash
) { expire_test
<ACE_Timer_Hash
> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test
); }
590 if (wheel
) { expire_test
<ACE_Timer_Wheel
> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test
); }
591 if (hashheap
) { expire_test
<ACE_Timer_Hash_Heap
> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test
); }
596 ACE_DEBUG ((LM_DEBUG
,
597 "\nOne upcall at a time test...\n\n"));
599 if (heap
) { upcall_test
<ACE_Timer_Heap
> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test
); }
600 if (list
) { upcall_test
<ACE_Timer_List
> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test
); }
601 if (hash
) { upcall_test
<ACE_Timer_Hash
> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test
); }
602 if (wheel
) { upcall_test
<ACE_Timer_Wheel
> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test
); }
603 if (hashheap
) { upcall_test
<ACE_Timer_Hash_Heap
> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test
); }
608 ACE_DEBUG ((LM_DEBUG
,
609 "\nSimple test...\n\n"));
611 if (heap
) { simple_test
<ACE_Timer_Heap
> test ("ACE_Timer_Heap"); ACE_UNUSED_ARG (test
); }
612 if (list
) { simple_test
<ACE_Timer_List
> test ("ACE_Timer_List"); ACE_UNUSED_ARG (test
); }
613 if (hash
) { simple_test
<ACE_Timer_Hash
> test ("ACE_Timer_Hash"); ACE_UNUSED_ARG (test
); }
614 if (wheel
) { simple_test
<ACE_Timer_Wheel
> test ("ACE_Timer_Wheel"); ACE_UNUSED_ARG (test
); }
615 if (hashheap
) { simple_test
<ACE_Timer_Hash_Heap
> test ("ACE_Timer_Hash_Heap"); ACE_UNUSED_ARG (test
); }