2 //=============================================================================
4 * @file Recursive_Condition_Bug_Test.cpp
6 * This test program validates the functionality of the
7 * ACE_Condition<ACE_Recursive_Thread_Mutex> template
8 * specialization when combined with the
9 * ACE_Thread_Timer_Queue_Adapter on Win32 and Posix pthreads.
10 * It was added to test for bugs with the ACE_OS recursive
11 * condition implementation.
13 * @author Leonid Kvetnyi <leonidk@nice.com> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
15 //=============================================================================
17 #include "test_config.h"
18 #include "ace/OS_NS_sys_time.h"
19 #include "ace/Task_T.h"
20 #include "ace/Activation_Queue.h"
21 #include "ace/Timer_Heap.h"
22 #include "ace/Timer_Queue_Adapters.h"
23 #include "ace/Condition_Recursive_Thread_Mutex.h"
25 #if defined (ACE_HAS_THREADS)
27 // Number of iterations for the performance tests.
28 static int max_iterations
= 30;
30 using Thread_Timer_Queue
= ACE_Thread_Timer_Queue_Adapter
<ACE_Timer_Heap
>;
34 class Test_Task
: public ACE_Task
<ACE_MT_SYNCH
>
39 while (--max_iterations
> 0)
41 // dequeue the next object
42 ACE_Message_Block
* mb
= 0;
44 if (this->getq (mb
) == -1)
45 ACE_ERROR_RETURN ((LM_ERROR
,
46 ACE_TEXT ("(%t) %p\n"),
47 ACE_TEXT ("getq failed")),
50 Test_Handler
*handler
= reinterpret_cast<Test_Handler
*> (mb
->base ());
53 ACE_Time_Value timeout
= ACE_OS::gettimeofday () + ACE_Time_Value (1, 0);
55 if (timer_queue_
.schedule (reinterpret_cast<ACE_Event_Handler
*> (handler
),
58 ACE_ERROR_RETURN ((LM_ERROR
,
59 ACE_TEXT ("(%t) %p\n"),
60 ACE_TEXT ("schedule failed")),
64 ACE_TEXT ("(%t) %d iteration(s) remain\n"),
68 timer_queue_
.deactivate ();
70 ACE_TEXT ("(%t) leaving the Test_task\n")));
74 //FUZZ: disable check_for_lack_ACE_OS
75 int open (void * = 0) override
77 //FUZZ: enable check_for_lack_ACE_OS
78 if (ACE_Task
<ACE_MT_SYNCH
>::activate (THR_NEW_LWP
, 1) != 0)
79 ACE_ERROR_RETURN ((LM_ERROR
,
80 ACE_TEXT ("(%t) %p\n"),
81 ACE_TEXT ("Test_Task::activate")),
83 if (0 != timer_queue_
.activate ())
84 ACE_ERROR_RETURN ((LM_ERROR
,
85 ACE_TEXT ("(%t) %p\n"),
86 ACE_TEXT ("Test_Task::queue activate")),
92 Thread_Timer_Queue timer_queue_
;
95 class Test_Handler
: public ACE_Event_Handler
98 int handle_timeout (const ACE_Time_Value
&,
99 const void *arg
) override
101 ACE_DEBUG ((LM_DEBUG
,
102 ACE_TEXT ("(%t) Test_Handler::handle_timeout\n")));
104 void *nc_arg
= const_cast<void *> (arg
);
105 Test_Task
*test_task
=
106 reinterpret_cast<Test_Task
*> (nc_arg
);
107 ACE_Message_Block
*mb
= 0;
108 ACE_NEW_MALLOC_RETURN (mb
,
109 static_cast<ACE_Message_Block
*> (ACE_Allocator::instance()->malloc (sizeof (ACE_Message_Block
))),
110 ACE_Message_Block (sizeof (*this), // size
111 ACE_Message_Block::MB_DATA
, // type
113 (char *) this, // data
116 ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
,
117 ACE_Time_Value::zero
,
118 ACE_Time_Value::max_time
,
120 ACE_Allocator::instance()), // data
123 test_task
->putq (mb
);
128 #endif /* ACE_HAS_THREADS */
131 run_main (int, ACE_TCHAR
*[])
133 ACE_START_TEST (ACE_TEXT ("Recursive_Condition_Bug_Test"));
135 #if defined (ACE_HAS_THREADS)
137 // Timer queue usage.
139 Test_Handler handler
;
142 if (0 != task
.open ())
143 ACE_ERROR_RETURN ((LM_ERROR
,
144 ACE_TEXT ("(%t) %p\n"),
148 ACE_Message_Block
*mb
= 0;
149 ACE_NEW_MALLOC_RETURN (mb
,
150 static_cast<ACE_Message_Block
*> (ACE_Allocator::instance()->malloc (sizeof (ACE_Message_Block
))),
151 ACE_Message_Block (sizeof (handler
), // size
152 ACE_Message_Block::MB_DATA
, // type
157 ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
,
158 ACE_Time_Value::zero
,
159 ACE_Time_Value::max_time
,
161 ACE_Allocator::instance()), // data
164 if (-1 == task
.putq (mb
))
165 ACE_ERROR_RETURN ((LM_ERROR
,
166 ACE_TEXT ("(%t) %p\n"),
170 if (ACE_Thread_Manager::instance ()->wait () == -1)
171 ACE_ERROR_RETURN ((LM_ERROR
,
172 "wait on Thread_Manager failed"),
175 ACE_ERROR ((LM_ERROR
,
176 ACE_TEXT ("ACE doesn't support recursive condition variables on this platform\n")));
177 #endif /* ACE_HAS_THREADS */