Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / MT_Reference_Counted_Notify_Test.cpp
blobab03322f09244e86eb5a9bcbaf257f404f484216
2 //=============================================================================
3 /**
4 * @file MT_Reference_Counted_Notify_Test.cpp
6 * This test is used to check reference counting of the event
7 * handlers when it interacts with the reactor notification
8 * mechanism.
10 * @author Irfan Pyarali <irfan@oomworks.com>
12 //=============================================================================
15 #include "test_config.h"
16 #include "ace/OS_NS_unistd.h"
17 #include "ace/Reactor.h"
18 #include "ace/Select_Reactor.h"
19 #include "ace/TP_Reactor.h"
20 #include "ace/WFMO_Reactor.h"
21 #include "ace/Dev_Poll_Reactor.h"
22 #include "ace/Task.h"
23 #include "ace/Get_Opt.h"
25 #if defined (ACE_HAS_THREADS)
27 static int test_select_reactor = 1;
28 static int test_tp_reactor = 1;
29 static int test_wfmo_reactor = 1;
30 static int test_dev_poll_reactor = 1;
31 static int test_empty_notify = 1;
32 static int test_simple_notify = 1;
33 static int test_reference_counted_notify = 1;
34 static int iterations = 5;
35 static int debug = 1;
37 class Reference_Counted_Event_Handler : public ACE_Event_Handler
39 public:
40 Reference_Counted_Event_Handler ();
42 ~Reference_Counted_Event_Handler () override;
44 int handle_input (ACE_HANDLE) override;
46 ACE_Event_Handler::Reference_Count add_reference () override;
48 ACE_Event_Handler::Reference_Count remove_reference () override;
51 Reference_Counted_Event_Handler::Reference_Counted_Event_Handler ()
53 this->reference_counting_policy ().value
54 (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
56 if (debug)
57 ACE_DEBUG
58 ((LM_DEBUG,
59 ACE_TEXT ("Reference count in Reference_Counted_Event_Handler() ")
60 ACE_TEXT ("is %d\n"),
61 this->reference_count_.load ()));
64 Reference_Counted_Event_Handler::~Reference_Counted_Event_Handler ()
66 if (debug)
67 ACE_DEBUG
68 ((LM_DEBUG,
69 ACE_TEXT ("Reference count in ~Reference_Counted_Event_Handler() ")
70 ACE_TEXT ("is %d\n"),
71 this->reference_count_.load ()));
73 if (0 != this->reference_count_.load ())
74 ACE_ERROR
75 ((LM_ERROR,
76 ACE_TEXT ("Reference count in ~Reference_Counted_Event_Handler() ")
77 ACE_TEXT ("should be 0 but is %d\n"),
78 this->reference_count_.load ()));
81 int
82 Reference_Counted_Event_Handler::handle_input (ACE_HANDLE)
84 if (debug)
85 ACE_DEBUG
86 ((LM_DEBUG,
87 ACE_TEXT ("Reference count in Reference_Counted_Event_Handler::")
88 ACE_TEXT ("handle_input() is %d\n"),
89 this->reference_count_.load ()));
91 if (2 != this->reference_count_.load ())
92 ACE_ERROR
93 ((LM_ERROR,
94 ACE_TEXT ("Reference count in Reference_Counted_Event_Handler::")
95 ACE_TEXT ("handle_input() should be 2 but is %d\n"),
96 this->reference_count_.load ()));
98 return 0;
101 ACE_Event_Handler::Reference_Count
102 Reference_Counted_Event_Handler::add_reference ()
104 ACE_Event_Handler::Reference_Count reference_count =
105 this->ACE_Event_Handler::add_reference ();
107 if (debug)
108 ACE_DEBUG ((LM_DEBUG,
109 ACE_TEXT ("Reference count after add_reference() is %d\n"),
110 this->reference_count_.load ()));
112 return reference_count;
115 ACE_Event_Handler::Reference_Count
116 Reference_Counted_Event_Handler::remove_reference ()
118 ACE_Event_Handler::Reference_Count reference_count =
119 this->ACE_Event_Handler::remove_reference ();
121 if (debug)
122 ACE_DEBUG ((LM_DEBUG,
123 ACE_TEXT ("Reference count after remove_reference() is %d\n"),
124 reference_count));
126 return reference_count;
129 class Simple_Event_Handler : public ACE_Event_Handler
131 public:
132 Simple_Event_Handler (int notifies);
134 ~Simple_Event_Handler () override;
136 int handle_input (ACE_HANDLE) override;
138 int notifies_;
141 Simple_Event_Handler::Simple_Event_Handler (int notifies)
142 : notifies_ (notifies)
144 if (debug)
145 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Simple_Event_Handler()\n")));
148 Simple_Event_Handler::~Simple_Event_Handler ()
150 if (debug)
151 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("~Simple_Event_Handler()\n")));
155 Simple_Event_Handler::handle_input (ACE_HANDLE)
157 if (debug)
158 ACE_DEBUG ((LM_DEBUG,
159 ACE_TEXT ("Simple_Event_Handler::handle_input()\n")));
161 this->notifies_--;
163 if (this->notifies_ == 0)
164 delete this;
166 return 0;
169 class Event_Loop_Thread : public ACE_Task_Base
171 public:
172 Event_Loop_Thread (ACE_Thread_Manager &thread_manager,
173 ACE_Reactor &reactor,
174 int extra_iterations_needed);
176 int svc () override;
178 ACE_Reactor &reactor_;
180 int extra_iterations_needed_;
183 Event_Loop_Thread::Event_Loop_Thread (ACE_Thread_Manager &thread_manager,
184 ACE_Reactor &reactor,
185 int extra_iterations_needed)
186 : ACE_Task_Base (&thread_manager),
187 reactor_ (reactor),
188 extra_iterations_needed_ (extra_iterations_needed)
193 Event_Loop_Thread::svc ()
195 int counter = 0;
197 // Simply run the event loop.
198 this->reactor_.owner (ACE_Thread::self ());
200 while (1)
202 counter++;
204 if (debug)
205 ACE_DEBUG ((LM_DEBUG,
206 ACE_TEXT ("Event Loop iteration %d....\n"),
207 counter));
209 this->reactor_.handle_events ();
211 if (counter ==
212 iterations + this->extra_iterations_needed_)
213 break;
216 return 0;
219 void
220 notify (ACE_Reactor &reactor,
221 ACE_Event_Handler *event_handler,
222 int extra_iterations_needed)
224 ACE_Thread_Manager thread_manager;
226 // Create a thread to run the event loop.
227 Event_Loop_Thread event_loop_thread (thread_manager,
228 reactor,
229 extra_iterations_needed);
231 int result =
232 event_loop_thread.activate ();
233 ACE_TEST_ASSERT (result == 0);
235 for (int i = 0;
236 i < iterations;
237 ++i)
239 ACE_OS::sleep (ACE_Time_Value (0, 500 * 1000));
241 result = reactor.notify (event_handler,
242 ACE_Event_Handler::READ_MASK);
244 ACE_TEST_ASSERT (result == 0);
247 thread_manager.wait ();
250 template <class REACTOR_IMPLEMENTATION>
251 class test
253 public:
254 test (int extra_iterations_needed);
257 template <class REACTOR_IMPLEMENTATION>
258 test<REACTOR_IMPLEMENTATION>::test (int extra_iterations_needed)
260 if (test_empty_notify)
262 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\nTesting empty notifies...\n\n")));
264 REACTOR_IMPLEMENTATION impl;
265 ACE_Reactor reactor (&impl, 0);
267 notify (reactor,
269 extra_iterations_needed);
273 if (test_simple_notify)
275 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\nTesting simple notifies...\n\n")));
277 REACTOR_IMPLEMENTATION impl;
278 ACE_Reactor reactor (&impl, 0);
280 Simple_Event_Handler *simple_event_handler =
281 new Simple_Event_Handler (iterations);
283 notify (reactor,
284 simple_event_handler,
285 extra_iterations_needed);
288 if (test_reference_counted_notify)
290 ACE_DEBUG ((LM_DEBUG,
291 ACE_TEXT ("\n\nTesting reference counted notifies...\n\n")));
293 REACTOR_IMPLEMENTATION impl;
294 ACE_Reactor reactor (&impl, 0);
296 Reference_Counted_Event_Handler *reference_counted_event_handler =
297 new Reference_Counted_Event_Handler;
299 ACE_Event_Handler_var safe_event_handler (reference_counted_event_handler);
301 notify (reactor,
302 reference_counted_event_handler,
303 extra_iterations_needed);
307 static int
308 parse_args (int argc, ACE_TCHAR *argv[])
310 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:d:e:f:g:z:"));
312 int cc;
313 while ((cc = get_opt ()) != -1)
315 switch (cc)
317 case 'a':
318 test_select_reactor = ACE_OS::atoi (get_opt.opt_arg ());
319 break;
320 case 'b':
321 test_tp_reactor = ACE_OS::atoi (get_opt.opt_arg ());
322 break;
323 case 'c':
324 test_wfmo_reactor = ACE_OS::atoi (get_opt.opt_arg ());
325 break;
326 case 'd':
327 test_dev_poll_reactor = ACE_OS::atoi (get_opt.opt_arg ());
328 break;
329 case 'e':
330 test_empty_notify = ACE_OS::atoi (get_opt.opt_arg ());
331 break;
332 case 'f':
333 test_simple_notify = ACE_OS::atoi (get_opt.opt_arg ());
334 break;
335 case 'g':
336 test_reference_counted_notify = ACE_OS::atoi (get_opt.opt_arg ());
337 break;
338 case 'z':
339 debug = ACE_OS::atoi (get_opt.opt_arg ());
340 break;
341 default:
342 ACE_ERROR ((LM_ERROR,
343 ACE_TEXT ("\nusage: %s \n\n")
344 ACE_TEXT ("\t[-a test Select Reactor] (defaults to %d)\n")
345 ACE_TEXT ("\t[-b test TP Reactor] (defaults to %d)\n")
346 ACE_TEXT ("\t[-c test WFMO Reactor] (defaults to %d)\n")
347 ACE_TEXT ("\t[-d test Dev Poll Reactor] (defaults to %d)\n")
348 ACE_TEXT ("\t[-e test empty notify] (defaults to %d)\n")
349 ACE_TEXT ("\t[-f test simple notify] (defaults to %d)\n")
350 ACE_TEXT ("\t[-g test reference counted notify] (defaults to %d)\n")
351 ACE_TEXT ("\t[-z debug] (defaults to %d)\n")
352 ACE_TEXT ("\n"),
353 argv[0],
354 test_select_reactor,
355 test_tp_reactor,
356 test_wfmo_reactor,
357 test_dev_poll_reactor,
358 test_empty_notify,
359 test_simple_notify,
360 test_reference_counted_notify,
361 debug));
362 return -1;
366 return 0;
370 run_main (int argc, ACE_TCHAR *argv[])
372 ACE_START_TEST (ACE_TEXT ("MT_Reference_Counted_Notify_Test"));
374 // Validate options.
375 int result =
376 parse_args (argc, argv);
377 if (result != 0)
378 return result;
380 int extra_iterations_needed = 1;
381 int extra_iterations_not_needed = 0;
383 if (test_select_reactor)
385 ACE_DEBUG ((LM_DEBUG,
386 "\n\nTesting Select Reactor....\n\n"));
388 test<ACE_Select_Reactor> test (extra_iterations_not_needed);
389 ACE_UNUSED_ARG (test);
392 if (test_tp_reactor)
394 ACE_DEBUG ((LM_DEBUG,
395 "\n\nTesting TP Reactor....\n\n"));
397 test<ACE_TP_Reactor> test (extra_iterations_not_needed);
398 ACE_UNUSED_ARG (test);
401 #if defined (ACE_HAS_EVENT_POLL)
403 if (test_dev_poll_reactor)
405 ACE_DEBUG ((LM_DEBUG,
406 "\n\nTesting Dev Poll Reactor....\n\n"));
408 test<ACE_Dev_Poll_Reactor> test (extra_iterations_not_needed);
409 ACE_UNUSED_ARG (test);
412 #endif
414 #if defined (ACE_WIN32)
416 if (test_wfmo_reactor)
418 ACE_DEBUG ((LM_DEBUG,
419 "\n\nTesting WFMO Reactor....\n\n"));
421 test<ACE_WFMO_Reactor> test (extra_iterations_needed);
422 ACE_UNUSED_ARG (test);
425 #else /* ACE_WIN32 */
427 ACE_UNUSED_ARG (extra_iterations_needed);
429 #endif /* ACE_WIN32 */
431 ACE_END_TEST;
433 return 0;
436 #else /* ACE_HAS_THREADS */
439 run_main (int, ACE_TCHAR *[])
441 ACE_START_TEST (ACE_TEXT ("MT_Reference_Counted_Notify_Test"));
443 ACE_ERROR ((LM_INFO,
444 ACE_TEXT ("threads not supported on this platform\n")));
446 ACE_END_TEST;
448 return 0;
451 #endif /* ACE_HAS_THREADS */