Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / ACE / tests / MT_Reference_Counted_Notify_Test.cpp
blob6d6b67a9030021014e119d35614a9f27d903346a
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:
41 Reference_Counted_Event_Handler (void);
43 ~Reference_Counted_Event_Handler (void);
45 int handle_input (ACE_HANDLE);
47 ACE_Event_Handler::Reference_Count add_reference (void);
49 ACE_Event_Handler::Reference_Count remove_reference (void);
53 Reference_Counted_Event_Handler::Reference_Counted_Event_Handler (void)
55 this->reference_counting_policy ().value
56 (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
58 if (debug)
59 ACE_DEBUG
60 ((LM_DEBUG,
61 ACE_TEXT ("Reference count in Reference_Counted_Event_Handler() ")
62 ACE_TEXT ("is %d\n"),
63 this->reference_count_.value ()));
66 Reference_Counted_Event_Handler::~Reference_Counted_Event_Handler (void)
68 if (debug)
69 ACE_DEBUG
70 ((LM_DEBUG,
71 ACE_TEXT ("Reference count in ~Reference_Counted_Event_Handler() ")
72 ACE_TEXT ("is %d\n"),
73 this->reference_count_.value ()));
75 if (0 != this->reference_count_.value ())
76 ACE_ERROR
77 ((LM_ERROR,
78 ACE_TEXT ("Reference count in ~Reference_Counted_Event_Handler() ")
79 ACE_TEXT ("should be 0 but is %d\n"),
80 this->reference_count_.value ()));
83 int
84 Reference_Counted_Event_Handler::handle_input (ACE_HANDLE)
86 if (debug)
87 ACE_DEBUG
88 ((LM_DEBUG,
89 ACE_TEXT ("Reference count in Reference_Counted_Event_Handler::")
90 ACE_TEXT ("handle_input() is %d\n"),
91 this->reference_count_.value ()));
93 if (2 != this->reference_count_.value ())
94 ACE_ERROR
95 ((LM_ERROR,
96 ACE_TEXT ("Reference count in Reference_Counted_Event_Handler::")
97 ACE_TEXT ("handle_input() should be 2 but is %d\n"),
98 this->reference_count_.value ()));
100 return 0;
103 ACE_Event_Handler::Reference_Count
104 Reference_Counted_Event_Handler::add_reference (void)
106 ACE_Event_Handler::Reference_Count reference_count =
107 this->ACE_Event_Handler::add_reference ();
109 if (debug)
110 ACE_DEBUG ((LM_DEBUG,
111 ACE_TEXT ("Reference count after add_reference() is %d\n"),
112 this->reference_count_.value ()));
114 return reference_count;
117 ACE_Event_Handler::Reference_Count
118 Reference_Counted_Event_Handler::remove_reference (void)
120 ACE_Event_Handler::Reference_Count reference_count =
121 this->ACE_Event_Handler::remove_reference ();
123 if (debug)
124 ACE_DEBUG ((LM_DEBUG,
125 ACE_TEXT ("Reference count after remove_reference() is %d\n"),
126 reference_count));
128 return reference_count;
131 class Simple_Event_Handler : public ACE_Event_Handler
133 public:
135 Simple_Event_Handler (int notifies);
137 ~Simple_Event_Handler (void);
139 int handle_input (ACE_HANDLE);
141 int notifies_;
144 Simple_Event_Handler::Simple_Event_Handler (int notifies)
145 : notifies_ (notifies)
147 if (debug)
148 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Simple_Event_Handler()\n")));
151 Simple_Event_Handler::~Simple_Event_Handler (void)
153 if (debug)
154 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("~Simple_Event_Handler()\n")));
158 Simple_Event_Handler::handle_input (ACE_HANDLE)
160 if (debug)
161 ACE_DEBUG ((LM_DEBUG,
162 ACE_TEXT ("Simple_Event_Handler::handle_input()\n")));
164 this->notifies_--;
166 if (this->notifies_ == 0)
167 delete this;
169 return 0;
172 class Event_Loop_Thread : public ACE_Task_Base
174 public:
176 Event_Loop_Thread (ACE_Thread_Manager &thread_manager,
177 ACE_Reactor &reactor,
178 int extra_iterations_needed);
180 int svc (void);
182 ACE_Reactor &reactor_;
184 int extra_iterations_needed_;
187 Event_Loop_Thread::Event_Loop_Thread (ACE_Thread_Manager &thread_manager,
188 ACE_Reactor &reactor,
189 int extra_iterations_needed)
190 : ACE_Task_Base (&thread_manager),
191 reactor_ (reactor),
192 extra_iterations_needed_ (extra_iterations_needed)
197 Event_Loop_Thread::svc (void)
199 int counter = 0;
201 // Simply run the event loop.
202 this->reactor_.owner (ACE_Thread::self ());
204 while (1)
206 counter++;
208 if (debug)
209 ACE_DEBUG ((LM_DEBUG,
210 ACE_TEXT ("Event Loop iteration %d....\n"),
211 counter));
213 this->reactor_.handle_events ();
215 if (counter ==
216 iterations + this->extra_iterations_needed_)
217 break;
220 return 0;
223 void
224 notify (ACE_Reactor &reactor,
225 ACE_Event_Handler *event_handler,
226 int extra_iterations_needed)
228 ACE_Thread_Manager thread_manager;
230 // Create a thread to run the event loop.
231 Event_Loop_Thread event_loop_thread (thread_manager,
232 reactor,
233 extra_iterations_needed);
235 int result =
236 event_loop_thread.activate ();
237 ACE_TEST_ASSERT (result == 0);
239 for (int i = 0;
240 i < iterations;
241 ++i)
243 ACE_OS::sleep (ACE_Time_Value (0, 500 * 1000));
245 result = reactor.notify (event_handler,
246 ACE_Event_Handler::READ_MASK);
248 ACE_TEST_ASSERT (result == 0);
251 thread_manager.wait ();
254 template <class REACTOR_IMPLEMENTATION>
255 class test
257 public:
258 test (int extra_iterations_needed);
261 template <class REACTOR_IMPLEMENTATION>
262 test<REACTOR_IMPLEMENTATION>::test (int extra_iterations_needed)
264 if (test_empty_notify)
266 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\nTesting empty notifies...\n\n")));
268 REACTOR_IMPLEMENTATION impl;
269 ACE_Reactor reactor (&impl, 0);
271 notify (reactor,
273 extra_iterations_needed);
277 if (test_simple_notify)
279 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\nTesting simple notifies...\n\n")));
281 REACTOR_IMPLEMENTATION impl;
282 ACE_Reactor reactor (&impl, 0);
284 Simple_Event_Handler *simple_event_handler =
285 new Simple_Event_Handler (iterations);
287 notify (reactor,
288 simple_event_handler,
289 extra_iterations_needed);
292 if (test_reference_counted_notify)
294 ACE_DEBUG ((LM_DEBUG,
295 ACE_TEXT ("\n\nTesting reference counted notifies...\n\n")));
297 REACTOR_IMPLEMENTATION impl;
298 ACE_Reactor reactor (&impl, 0);
300 Reference_Counted_Event_Handler *reference_counted_event_handler =
301 new Reference_Counted_Event_Handler;
303 ACE_Event_Handler_var safe_event_handler (reference_counted_event_handler);
305 notify (reactor,
306 reference_counted_event_handler,
307 extra_iterations_needed);
311 static int
312 parse_args (int argc, ACE_TCHAR *argv[])
314 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:d:e:f:g:z:"));
316 int cc;
317 while ((cc = get_opt ()) != -1)
319 switch (cc)
321 case 'a':
322 test_select_reactor = ACE_OS::atoi (get_opt.opt_arg ());
323 break;
324 case 'b':
325 test_tp_reactor = ACE_OS::atoi (get_opt.opt_arg ());
326 break;
327 case 'c':
328 test_wfmo_reactor = ACE_OS::atoi (get_opt.opt_arg ());
329 break;
330 case 'd':
331 test_dev_poll_reactor = ACE_OS::atoi (get_opt.opt_arg ());
332 break;
333 case 'e':
334 test_empty_notify = ACE_OS::atoi (get_opt.opt_arg ());
335 break;
336 case 'f':
337 test_simple_notify = ACE_OS::atoi (get_opt.opt_arg ());
338 break;
339 case 'g':
340 test_reference_counted_notify = ACE_OS::atoi (get_opt.opt_arg ());
341 break;
342 case 'z':
343 debug = ACE_OS::atoi (get_opt.opt_arg ());
344 break;
345 default:
346 ACE_ERROR ((LM_ERROR,
347 ACE_TEXT ("\nusage: %s \n\n")
348 ACE_TEXT ("\t[-a test Select Reactor] (defaults to %d)\n")
349 ACE_TEXT ("\t[-b test TP Reactor] (defaults to %d)\n")
350 ACE_TEXT ("\t[-c test WFMO Reactor] (defaults to %d)\n")
351 ACE_TEXT ("\t[-d test Dev Poll Reactor] (defaults to %d)\n")
352 ACE_TEXT ("\t[-e test empty notify] (defaults to %d)\n")
353 ACE_TEXT ("\t[-f test simple notify] (defaults to %d)\n")
354 ACE_TEXT ("\t[-g test reference counted notify] (defaults to %d)\n")
355 ACE_TEXT ("\t[-z debug] (defaults to %d)\n")
356 ACE_TEXT ("\n"),
357 argv[0],
358 test_select_reactor,
359 test_tp_reactor,
360 test_wfmo_reactor,
361 test_dev_poll_reactor,
362 test_empty_notify,
363 test_simple_notify,
364 test_reference_counted_notify,
365 debug));
366 return -1;
370 return 0;
374 run_main (int argc, ACE_TCHAR *argv[])
376 ACE_START_TEST (ACE_TEXT ("MT_Reference_Counted_Notify_Test"));
378 // Validate options.
379 int result =
380 parse_args (argc, argv);
381 if (result != 0)
382 return result;
384 int extra_iterations_needed = 1;
385 int extra_iterations_not_needed = 0;
387 if (test_select_reactor)
389 ACE_DEBUG ((LM_DEBUG,
390 "\n\nTesting Select Reactor....\n\n"));
392 test<ACE_Select_Reactor> test (extra_iterations_not_needed);
393 ACE_UNUSED_ARG (test);
396 if (test_tp_reactor)
398 ACE_DEBUG ((LM_DEBUG,
399 "\n\nTesting TP Reactor....\n\n"));
401 test<ACE_TP_Reactor> test (extra_iterations_not_needed);
402 ACE_UNUSED_ARG (test);
405 #if defined (ACE_HAS_EVENT_POLL)
407 if (test_dev_poll_reactor)
409 ACE_DEBUG ((LM_DEBUG,
410 "\n\nTesting Dev Poll Reactor....\n\n"));
412 test<ACE_Dev_Poll_Reactor> test (extra_iterations_not_needed);
413 ACE_UNUSED_ARG (test);
416 #endif
418 #if defined (ACE_WIN32)
420 if (test_wfmo_reactor)
422 ACE_DEBUG ((LM_DEBUG,
423 "\n\nTesting WFMO Reactor....\n\n"));
425 test<ACE_WFMO_Reactor> test (extra_iterations_needed);
426 ACE_UNUSED_ARG (test);
429 #else /* ACE_WIN32 */
431 ACE_UNUSED_ARG (extra_iterations_needed);
433 #endif /* ACE_WIN32 */
435 ACE_END_TEST;
437 return 0;
440 #else /* ACE_HAS_THREADS */
443 run_main (int, ACE_TCHAR *[])
445 ACE_START_TEST (ACE_TEXT ("MT_Reference_Counted_Notify_Test"));
447 ACE_ERROR ((LM_INFO,
448 ACE_TEXT ("threads not supported on this platform\n")));
450 ACE_END_TEST;
452 return 0;
455 #endif /* ACE_HAS_THREADS */