2 //=============================================================================
4 * @file Reactors_Test.cpp
6 * This is a test that performs a torture test of multiple
7 * <ACE_Reactors> and <ACE_Tasks> in the same process.
9 * @author Prashant Jain <pjain@cs.wustl.edu>
10 * @author Detlef Becker <Detlef.Becker@med.siemens.de>
11 * @author and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
13 //=============================================================================
15 #include "test_config.h"
17 #include "ace/Reactor.h"
18 #include "ace/Atomic_Op.h"
19 #include "ace/Recursive_Thread_Mutex.h"
21 #if defined (ACE_HAS_THREADS)
23 ACE_Thread_Manager
*thr_mgr
;
25 static const int MAX_TASKS
= 20;
30 * @brief Exercise the tasks.
32 class Test_Task
: public ACE_Task
<ACE_MT_SYNCH
>
36 ~Test_Task () override
;
38 //FUZZ: disable check_for_lack_ACE_OS
40 ///FUZZ: enable check_for_lack_ACE_OS
41 int open (void *args
= 0) override
;
42 int close (u_long flags
= 0) override
;
45 // = Event Handler hooks.
46 int handle_input (ACE_HANDLE handle
) override
;
47 int handle_close (ACE_HANDLE fd
,
48 ACE_Reactor_Mask close_mask
) override
;
50 /// Number of iterations handled.
53 /// Number of tasks running.
54 static int task_count_
;
57 // Static data member initialization.
58 int Test_Task::task_count_
= 0;
60 static ACE_Atomic_Op
<ACE_Thread_Mutex
, int> done_count
= MAX_TASKS
* 2;
61 static ACE_Recursive_Thread_Mutex recursive_lock
;
63 Test_Task::Test_Task ()
66 ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
, recursive_lock
);
68 Test_Task::task_count_
++;
71 ACE_TEXT ("(%t) TT+ Test_Task::task_count_ = %d\n"),
72 Test_Task::task_count_
));
75 Test_Task::~Test_Task ()
77 ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
, recursive_lock
);
80 ACE_TEXT ("(%t) TT- Test_Task::task_count_ = %d\n"),
81 Test_Task::task_count_
));
83 ACE_TEST_ASSERT (Test_Task::task_count_
== 0);
87 Test_Task::open (void *args
)
89 this->reactor (reinterpret_cast<ACE_Reactor
*> (args
));
90 return this->activate (THR_NEW_LWP
);
94 Test_Task::close (u_long
)
96 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
, recursive_lock
, -1);
98 Test_Task::task_count_
--;
100 ACE_DEBUG ((LM_DEBUG
,
101 ACE_TEXT ("(%t) close Test_Task::task_count_ = %d\n"),
102 Test_Task::task_count_
));
104 ACE_TEST_ASSERT (Test_Task::task_count_
>= 0);
112 ACE_DEBUG ((LM_DEBUG
,
113 ACE_TEXT ("(%t) svc\n")));
115 for (size_t i
= 0; i
< ACE_MAX_ITERATIONS
; i
++)
117 ACE_OS::thr_yield ();
119 // Only wait up to 10 milliseconds to notify the Reactor.
120 ACE_Time_Value
timeout (0, 10 * 1000);
122 if (this->reactor ()->notify (this,
123 ACE_Event_Handler::READ_MASK
,
127 ACE_DEBUG ((LM_DEBUG
,
128 ACE_TEXT ("(%t) %p\n"),
129 ACE_TEXT ("notify() timed out")));
131 ACE_ERROR_RETURN ((LM_ERROR
,
132 ACE_TEXT ("(%t) %p\n"),
133 ACE_TEXT ("notify")),
142 Test_Task::handle_close (ACE_HANDLE
, ACE_Reactor_Mask
)
148 Test_Task::handle_input (ACE_HANDLE
)
152 if (this->handled_
== ACE_MAX_ITERATIONS
)
155 ACE_DEBUG ((LM_DEBUG
,
156 ACE_TEXT ("(%t) handle_input, handled_ = %d, done_count = %d\n"),
158 done_count
.value ()));
161 ACE_OS::thr_yield ();
168 ACE_Reactor
*reactor
= reinterpret_cast<ACE_Reactor
*> (args
);
170 // Make this thread the owner of the Reactor's event loop.
171 reactor
->owner (ACE_Thread::self ());
173 // Use a timeout to inform the Reactor when to shutdown.
174 ACE_Time_Value
timeout (4);
177 switch (reactor
->handle_events (timeout
))
180 ACE_ERROR_RETURN ((LM_ERROR
,
181 ACE_TEXT ("(%t) %p\n"),
182 ACE_TEXT ("reactor")),
186 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) Reactor shutdown\n")));
190 ACE_NOTREACHED (return 0);
193 #endif /* ACE_HAS_THREADS */
196 run_main (int, ACE_TCHAR
*[])
198 ACE_START_TEST (ACE_TEXT ("Reactors_Test"));
200 #if defined (ACE_HAS_THREADS)
201 ACE_TEST_ASSERT (ACE_LOG_MSG
->op_status () != -1);
203 thr_mgr
= ACE_Thread_Manager::instance ();
206 ACE_TEST_ASSERT (ACE_LOG_MSG
->op_status () != -1);
208 Test_Task tt1
[MAX_TASKS
];
209 Test_Task tt2
[MAX_TASKS
];
211 // Activate all of the Tasks.
213 for (int i
= 0; i
< MAX_TASKS
; i
++)
215 tt1
[i
].open (ACE_Reactor::instance ());
216 tt2
[i
].open (&reactor
);
219 // Spawn two threads each running a different reactor.
221 if (ACE_Thread_Manager::instance ()->spawn
222 (ACE_THR_FUNC (worker
),
223 (void *) ACE_Reactor::instance (),
224 THR_BOUND
| THR_DETACHED
) == -1)
225 ACE_ERROR_RETURN ((LM_ERROR
,
230 else if (ACE_Thread_Manager::instance ()->spawn
231 (ACE_THR_FUNC (worker
), (void *) &reactor
,
232 THR_BOUND
| THR_DETACHED
) == -1)
233 ACE_ERROR_RETURN ((LM_ERROR
,
238 if (ACE_Thread_Manager::instance ()->wait () == -1)
239 ACE_ERROR_RETURN ((LM_ERROR
,
244 ACE_DEBUG ((LM_DEBUG
,
245 ACE_TEXT ("(%t) all threads are finished\n")));
249 ACE_TEXT ("threads not supported on this platform\n")));
250 #endif /* ACE_HAS_THREADS */