Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / ACE / tests / Reactor_Dispatch_Order_Test.cpp
blob3046ae2294a3da4fbf5d7956bf0173d8bed4a789
2 //=============================================================================
3 /**
4 * @file Reactor_Dispatch_Order_Test.cpp
6 * This is a simple test that checks the order of dispatching of
7 * ACE Reactors. Order should be: timeout, output, and then input.
9 * @author Irfan Pyarali <irfan@cs.wustl.edu>
11 //=============================================================================
13 #include "test_config.h"
14 #include "ace/OS_NS_string.h"
15 #include "ace/Reactor.h"
16 #include "ace/Select_Reactor.h"
17 #include "ace/WFMO_Reactor.h"
18 #include "ace/Dev_Poll_Reactor.h"
19 #include "ace/Pipe.h"
20 #include "ace/ACE.h"
22 static const char *message = "Hello there! Hope you get this message";
24 class Handler : public ACE_Event_Handler
26 public:
27 Handler (ACE_Reactor &reactor);
29 ~Handler() override;
31 int handle_timeout (const ACE_Time_Value &tv,
32 const void *arg) override;
34 int handle_input (ACE_HANDLE fd) override;
36 int handle_output (ACE_HANDLE fd) override;
38 ACE_HANDLE get_handle () const override;
40 // We need to add MSG_OOB data transfer to this test to check the
41 // order of when <handle_exception> gets called. I tried with
42 // Windows 2000 but only one byte of the message came across as
43 // urgent data. The rest of the data was treated as normal! There
44 // was some explanation of Microsoft's TCP/IP deals with out-of-band
45 // data in "Out-of-Band Data and Push Bit in TCP/IP" in the MSDN
46 // library. However, I did not comprehend that well enough. If
47 // someone can make this work, please check the order of
48 // <handle_exception> getting called.
49 // int handle_exception (ACE_HANDLE fd);
51 ACE_Pipe pipe_;
53 int dispatch_order_;
54 bool ok_; // Constructed and initialized ok
57 Handler::Handler (ACE_Reactor &reactor)
58 : ACE_Event_Handler (&reactor),
59 dispatch_order_ (1),
60 ok_ (false)
62 // Create the pipe.
63 if (0 != this->pipe_.open ())
64 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("pipe")));
65 else
67 // Register for all events.
68 if (0 != this->reactor ()->register_handler
69 (this->pipe_.read_handle (),
70 this,
71 ACE_Event_Handler::READ_MASK | ACE_Event_Handler::WRITE_MASK))
72 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("register")));
73 else
74 this->ok_ = true;
79 Handler::~Handler ()
81 this->pipe_.close ();
85 ACE_HANDLE
86 Handler::get_handle () const
88 return this->pipe_.read_handle ();
91 int
92 Handler::handle_timeout (const ACE_Time_Value &,
93 const void *)
95 int const me = this->dispatch_order_++;
96 if (me != 1)
97 ACE_ERROR ((LM_ERROR,
98 ACE_TEXT ("handle_timeout should be #1; it's %d\n"),
99 me));
100 else
101 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Handler::handle_timeout\n")));
103 return 0;
107 Handler::handle_output (ACE_HANDLE)
109 int const me = this->dispatch_order_++;
110 if (me != 2)
111 ACE_ERROR ((LM_ERROR,
112 ACE_TEXT ("handle_output should be #2; it's %d\n"),
113 me));
114 else
115 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Handler::handle_output\n")));
117 #if defined (__OpenBSD__) || defined (ACE_VXWORKS)
118 // All that we need written has been written, so don't
119 // call handle_output again.
120 this->reactor ()->mask_ops (this->pipe_.read_handle (),
121 ACE_Event_Handler::WRITE_MASK,
122 ACE_Reactor::CLR_MASK);
123 #endif /* __OpenBSD__ || ACE_VXWORKS */
125 return 0;
129 Handler::handle_input (ACE_HANDLE fd)
131 int const me = this->dispatch_order_++;
132 if (me != 3)
133 ACE_ERROR ((LM_ERROR,
134 ACE_TEXT ("handle_input should be #3; it's %d\n"),
135 me));
137 char buffer[BUFSIZ];
138 ssize_t result = ACE::recv (fd, buffer, sizeof buffer);
139 if (result != ssize_t (ACE_OS::strlen (message)))
140 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Handler recv'd %b bytes; expected %B\n"),
141 result, ACE_OS::strlen (message)));
142 buffer[result] = '\0';
144 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Handler::handle_input: %C\n"), buffer));
146 if (ACE_OS::strcmp (buffer, message) != 0)
147 ACE_ERROR ((LM_ERROR,
148 ACE_TEXT ("Handler text mismatch; received \"%C\"; ")
149 ACE_TEXT ("expected \"%C\"\n"),
150 buffer, message));
152 this->reactor ()->end_reactor_event_loop ();
154 return 0;
157 static bool
158 test_reactor_dispatch_order (ACE_Reactor &reactor)
160 Handler handler (reactor);
161 if (!handler.ok_)
163 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error initializing test; abort.\n")));
164 return false;
167 bool ok_to_go = true;
169 // This should trigger a call to <handle_input>.
170 ssize_t result =
171 ACE::send_n (handler.pipe_.write_handle (),
172 message,
173 ACE_OS::strlen (message));
174 if (result != ssize_t (ACE_OS::strlen (message)))
176 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Handler sent %b bytes; should be %B\n"),
177 result, ACE_OS::strlen (message)));
178 ok_to_go = false;
181 // This should trigger a call to <handle_timeout>.
182 if (-1 == reactor.schedule_timer (&handler,
184 ACE_Time_Value (0)))
186 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("schedule_timer")));
187 ok_to_go = false;
190 // Suspend the handlers - only the timer should be dispatched
191 ACE_Time_Value tv (1);
192 reactor.suspend_handlers ();
193 if (0 != reactor.run_reactor_event_loop (tv))
195 ACE_ERROR ((LM_ERROR,
196 ACE_TEXT ("%p\n"),
197 ACE_TEXT ("run_reactor_event_loop")));
198 ok_to_go = false;
201 // only the timer should have fired
202 if (handler.dispatch_order_ != 2)
204 ACE_ERROR ((LM_ERROR,
205 ACE_TEXT ("Incorrect number fired %d; expected 2\n"),
206 handler.dispatch_order_));
207 ok_to_go = false;
210 // Reset the dispatch_order_ count and schedule another timer
211 handler.dispatch_order_ = 1;
212 if (-1 == reactor.schedule_timer (&handler,
214 ACE_Time_Value (0)))
216 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("schedule_timer")));
217 ok_to_go = false;
220 // Resume the handlers - things should work now
221 reactor.resume_handlers ();
223 if (ok_to_go)
225 if (0 != reactor.run_reactor_event_loop (tv))
227 ACE_ERROR ((LM_ERROR,
228 ACE_TEXT ("%p\n"),
229 ACE_TEXT ("run_reactor_event_loop 2")));
230 ok_to_go = false;
234 if (0 != reactor.remove_handler (handler.pipe_.read_handle (),
235 ACE_Event_Handler::ALL_EVENTS_MASK |
236 ACE_Event_Handler::DONT_CALL))
237 ACE_ERROR ((LM_ERROR,
238 ACE_TEXT ("%p\n"),
239 ACE_TEXT ("remover_handler pipe")));
241 if (handler.dispatch_order_ != 4)
243 ACE_ERROR ((LM_ERROR,
244 ACE_TEXT ("Incorrect number fired %d; expected 4\n"),
245 handler.dispatch_order_));
246 ok_to_go = false;
249 int nr_cancelled = reactor.cancel_timer (&handler);
250 if (nr_cancelled > 0)
251 ACE_ERROR ((LM_ERROR,
252 ACE_TEXT ("Finishing test with %d timers still scheduled\n"),
253 nr_cancelled));
254 return ok_to_go;
258 run_main (int, ACE_TCHAR *[])
260 ACE_START_TEST (ACE_TEXT ("Reactor_Dispatch_Order_Test"));
262 int result = 0;
263 ACE_Select_Reactor select_reactor_impl;
264 ACE_Reactor select_reactor (&select_reactor_impl);
265 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing ACE_Select_Reactor\n")));
266 if (!test_reactor_dispatch_order (select_reactor))
267 ++result;
269 // Winsock 2 things are needed for WFMO_Reactor.
270 #if defined (ACE_WIN32) && \
271 (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
273 ACE_WFMO_Reactor wfmo_reactor_impl;
274 ACE_Reactor wfmo_reactor (&wfmo_reactor_impl);
275 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing ACE_WFMO_Reactor\n")));
276 if (!test_reactor_dispatch_order (wfmo_reactor))
277 ++result;
279 #endif /* ACE_WIN32 && ACE_HAS_WINSOCK2 */
281 ACE_END_TEST;
282 return result;