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"
28 static const char *one_second_timeout
= "one second timeout";
29 static const char *two_second_timeout
= "two second timeout";
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
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
);
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 ()
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_
);
87 Reference_Counted_Event_Handler::handle_timeout (const ACE_Time_Value
&,
92 "Reference count in Reference_Counted_Event_Handler::handle_timeout() for arg = %C is %d\n",
94 this->reference_count_
.load ()));
100 Reference_Counted_Event_Handler::handle_close (ACE_HANDLE handle
,
101 ACE_Reactor_Mask masks
)
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",
109 this->reference_count_
.load ()));
111 ++this->number_of_handle_close_calls_
;
117 cancellation (ACE_Timer_Queue
&timer_queue
,
121 int dont_call_handle_close
)
125 int expected_number_of_handle_close_calls
= -1;
127 if (!dont_call_handle_close
)
130 expected_number_of_handle_close_calls
= 1;
131 else if (second_timer
)
132 expected_number_of_handle_close_calls
= 2;
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;
148 timer_queue
.schedule (handler
,
150 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
152 ACE_TEST_ASSERT (first_timer_id
!= -1);
157 timer_queue
.schedule (handler
,
159 ACE_Time_Value (1) + timer_queue
.gettimeofday ());
160 ACE_TEST_ASSERT (first_timer_id
!= -1);
166 timer_queue
.schedule (handler
,
168 ACE_Time_Value (2) + timer_queue
.gettimeofday (),
170 ACE_TEST_ASSERT (second_timer_id
!= -1);
176 timer_queue
.cancel (handler
,
177 dont_call_handle_close
);
180 ACE_TEST_ASSERT (result
== 2);
182 ACE_TEST_ASSERT (result
== 1);
187 timer_queue
.cancel (first_timer_id
,
189 dont_call_handle_close
);
190 ACE_TEST_ASSERT (result
== 1);
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
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",
237 i
< (int) (sizeof configs
/ (sizeof (int) * 5));
240 TIMER_QUEUE timer_queue
;
242 cancellation (timer_queue
,
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
);
266 expire (ACE_Timer_Queue
&timer_queue
,
267 Expire_Function expire_function
)
272 Reference_Counted_Event_Handler
*handler
=
273 new Reference_Counted_Event_Handler (1);
275 ACE_Event_Handler_var
safe_handler (handler
);
278 timer_queue
.schedule (handler
,
280 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
282 ACE_TEST_ASSERT (timer_id
!= -1);
285 timer_queue
.schedule (handler
,
287 ACE_Time_Value (2) + timer_queue
.gettimeofday ());
288 ACE_TEST_ASSERT (result
!= -1);
292 for (int i
= 0; i
< events
;)
294 WAIT_FOR_NEXT_EVENT (timer_queue
);
297 expire_function (timer_queue
);
299 ACE_TEST_ASSERT (result
>= 0);
304 timer_queue
.cancel (timer_id
, 0, 0);
307 template<class TIMER_QUEUE
>
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",
321 TIMER_QUEUE timer_queue
;
327 template<class TIMER_QUEUE
>
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",
341 TIMER_QUEUE timer_queue
;
347 class Simple_Event_Handler
: public ACE_Event_Handler
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 ()
364 ACE_DEBUG ((LM_DEBUG
,
365 "Simple_Event_Handler()\n"));
368 Simple_Event_Handler::~Simple_Event_Handler ()
371 ACE_DEBUG ((LM_DEBUG
,
372 "~Simple_Event_Handler()\n"));
376 Simple_Event_Handler::handle_timeout (const ACE_Time_Value
&,
380 ACE_DEBUG ((LM_DEBUG
,
381 "Simple_Event_Handler::handle_timeout() for arg = %C\n",
382 (const char *) arg
));
387 Simple_Event_Handler::handle_close (ACE_HANDLE handle
,
388 ACE_Reactor_Mask masks
)
391 ACE_DEBUG ((LM_DEBUG
,
392 "Simple_Event_Handler::handle_close() called with handle = %d and masks = %d.\n",
402 simple (ACE_Timer_Queue
&timer_queue
)
409 Simple_Event_Handler
*handler
=
410 new Simple_Event_Handler
;
413 timer_queue
.schedule (handler
,
415 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
417 ACE_TEST_ASSERT (timer_id
!= -1);
420 timer_queue
.cancel (timer_id
,
423 ACE_TEST_ASSERT (result
== 1);
427 Simple_Event_Handler
*handler
=
428 new Simple_Event_Handler
;
431 timer_queue
.schedule (handler
,
433 ACE_Time_Value (1) + timer_queue
.gettimeofday (),
435 ACE_TEST_ASSERT (timer_id
!= -1);
440 for (int i
= 0; i
< events
;)
442 WAIT_FOR_NEXT_EVENT (timer_queue
);
445 timer_queue
.expire ();
447 ACE_TEST_ASSERT (result
>= 0);
452 timer_queue
.cancel (timer_id
, 0, 0);
455 template <class TIMER_QUEUE
>
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",
469 TIMER_QUEUE timer_queue
;
471 simple (timer_queue
);
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;
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:"));
490 while ((cc
= get_opt ()) != -1)
495 heap
= ACE_OS::atoi (get_opt
.opt_arg ());
498 list
= ACE_OS::atoi (get_opt
.opt_arg ());
501 hash
= ACE_OS::atoi (get_opt
.opt_arg ());
504 wheel
= ACE_OS::atoi (get_opt
.opt_arg ());
507 hashheap
= ACE_OS::atoi (get_opt
.opt_arg ());
510 test_cancellation
= ACE_OS::atoi (get_opt
.opt_arg ());
513 test_expire
= ACE_OS::atoi (get_opt
.opt_arg ());
516 test_one_upcall
= ACE_OS::atoi (get_opt
.opt_arg ());
519 test_simple
= ACE_OS::atoi (get_opt
.opt_arg ());
522 debug
= ACE_OS::atoi (get_opt
.opt_arg ());
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")
557 run_main (int argc
, ACE_TCHAR
*argv
[])
559 ACE_START_TEST (ACE_TEXT ("Timer_Queue_Reference_Counting_Test"));
563 parse_args (argc
, argv
);
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
); }
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
); }
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
); }
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
); }