Use =default for skeleton copy constructor
[ACE_TAO.git] / ACE / examples / Reactor / WFMO_Reactor / Handle_Close.cpp
blob0b783827f96d74505d743e306c9cfc7f653aaa5d
1 //=============================================================================
2 /**
3 * @file Handle_Close.cpp
5 * This application tests whether handle_close gets called and if
6 * the correct masks are passed along. The handler should get
7 * handle_close called for all three masks (READ, WRITE, and
8 * EXCEPT).
10 * @author Irfan Pyarali
12 //=============================================================================
15 #include "ace/Get_Opt.h"
16 #include "ace/Reactor.h"
17 #include "ace/WFMO_Reactor.h"
18 #include "ace/Select_Reactor.h"
19 #include "ace/Pipe.h"
20 #include "ace/OS_main.h"
21 #include <memory>
23 // Use the WFMO_Reactor
24 static int opt_wfmo_reactor = 0;
26 // Use the Select_Reactor
27 static int opt_select_reactor = 0;
29 // Make pipe readable in main()
30 static int write_to_pipe_in_main = 0;
32 // Cancel reads
33 static int cancel_reads = 0;
35 // Write some data to the pipe. This will cause handle_input to get
36 // called.
37 void
38 write_to_pipe (ACE_Pipe &pipe)
40 const char *data = "hello";
41 size_t len = ACE_OS::strlen (data);
43 ssize_t result = ACE::send (pipe.write_handle (),
44 data,
45 len);
46 ACE_TEST_ASSERT ((size_t)result == len);
49 // Simple handler class
50 class Handler : public ACE_Event_Handler
52 public:
53 Handler (ACE_Pipe &pipe)
54 : pipe_ (pipe)
58 ~Handler ()
60 this->reactor (0);
63 ACE_HANDLE get_handle () const
65 return this->pipe_.read_handle ();
68 int handle_close (ACE_HANDLE,
69 ACE_Reactor_Mask close_mask)
71 ACE_DEBUG ((LM_DEBUG,
72 "Handler::handle_close called with mask = %d\n",
73 close_mask));
74 return 0;
77 int handle_input (ACE_HANDLE)
79 ACE_DEBUG ((LM_DEBUG, "Handler::handle_input\n"));
81 // Remove for reading
82 return -1;
85 int handle_output (ACE_HANDLE handle)
87 ACE_UNUSED_ARG (handle);
88 ACE_DEBUG ((LM_DEBUG, "Handler::handle_output\n"));
90 // Optionally cancel reads
91 if (cancel_reads)
93 int result = this->reactor ()->cancel_wakeup (this,
94 ACE_Event_Handler::READ_MASK);
95 ACE_TEST_ASSERT (result != -1);
98 // Write to the pipe; this causes handle_input to get called.
99 if (!write_to_pipe_in_main)
100 write_to_pipe (this->pipe_);
102 // Remove for writing
103 return -1;
106 protected:
107 ACE_Pipe &pipe_;
110 class Different_Handler : public ACE_Event_Handler
112 public:
113 Different_Handler (ACE_Pipe &pipe)
114 : pipe_ (pipe)
118 ~Different_Handler ()
120 this->reactor (0);
123 ACE_HANDLE get_handle () const
125 return this->pipe_.read_handle ();
128 int handle_close (ACE_HANDLE handle,
129 ACE_Reactor_Mask close_mask)
131 ACE_UNUSED_ARG (handle);
132 ACE_DEBUG ((LM_DEBUG,
133 "Different_Handler::handle_close called with mask = %d\n",
134 close_mask));
135 return 0;
138 int handle_input (ACE_HANDLE handle)
140 ACE_UNUSED_ARG (handle);
141 ACE_DEBUG ((LM_DEBUG, "Different_Handler::handle_input\n"));
143 // Remove for reading
144 int result = this->reactor ()->remove_handler (this,
145 ACE_Event_Handler::READ_MASK);
146 ACE_TEST_ASSERT (result == 0);
148 return 0;
151 int handle_output (ACE_HANDLE handle)
153 ACE_UNUSED_ARG (handle);
154 ACE_DEBUG ((LM_DEBUG, "Different_Handler::handle_output\n"));
156 // Add for reading
157 int result = this->reactor ()->mask_ops (this,
158 ACE_Event_Handler::READ_MASK,
159 ACE_Reactor::ADD_MASK);
160 ACE_TEST_ASSERT (result != -1);
162 ACE_Reactor_Mask old_masks =
163 ACE_Event_Handler::WRITE_MASK |
164 ACE_Event_Handler::EXCEPT_MASK;
166 ACE_TEST_ASSERT (old_masks ==
167 static_cast<ACE_Reactor_Mask> (result));
169 // Get new masks
170 result = this->reactor ()->mask_ops (this,
171 ACE_Event_Handler::NULL_MASK,
172 ACE_Reactor::GET_MASK);
173 ACE_TEST_ASSERT (result != -1);
175 ACE_Reactor_Mask current_masks =
176 ACE_Event_Handler::READ_MASK |
177 ACE_Event_Handler::WRITE_MASK |
178 ACE_Event_Handler::EXCEPT_MASK;
180 ACE_TEST_ASSERT (current_masks ==
181 static_cast<ACE_Reactor_Mask> (result));
183 // Remove for writing
184 ACE_Reactor_Mask mask = ACE_Event_Handler::WRITE_MASK | ACE_Event_Handler::DONT_CALL;
185 result = this->reactor ()->remove_handler (this,
186 mask);
187 ACE_TEST_ASSERT (result == 0);
189 // Write to the pipe; this causes handle_input to get called.
190 if (!write_to_pipe_in_main)
191 write_to_pipe (this->pipe_);
193 return 0;
196 protected:
197 ACE_Pipe &pipe_;
202 // Selection of which reactor should get created
204 ACE_Reactor *
205 create_reactor ()
207 ACE_Reactor_Impl *impl = 0;
209 if (opt_wfmo_reactor)
211 #if defined (ACE_WIN32)
212 ACE_NEW_RETURN (impl,
213 ACE_WFMO_Reactor,
215 #endif /* ACE_WIN32 */
217 else if (opt_select_reactor)
219 ACE_NEW_RETURN (impl,
220 ACE_Select_Reactor,
223 else
225 ACE_Reactor *singleton_reactor =
226 ACE_Reactor::instance ();
227 ACE_Reactor::instance (0);
228 return singleton_reactor;
231 ACE_Reactor *reactor = 0;
232 ACE_NEW_RETURN (reactor,
233 ACE_Reactor (impl,
237 return reactor;
241 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
243 int result = 0;
245 //FUZZ: disable check_for_lack_ACE_OS
246 // Parse args
247 ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("swmc"), 1);
249 for (int c; (c = getopt ()) != -1; )
250 //FUZZ: enable check_for_lack_ACE_OS
251 switch (c)
253 case 's':
254 opt_select_reactor = 1;
255 break;
256 case 'w':
257 opt_wfmo_reactor = 1;
258 break;
259 case 'm':
260 write_to_pipe_in_main = 1;
261 break;
262 case 'c':
263 cancel_reads = 1;
264 break;
267 // Create pipes
268 ACE_Pipe pipe1, pipe2;
270 result = pipe1.open ();
271 ACE_TEST_ASSERT (result == 0);
273 result = pipe2.open ();
274 ACE_TEST_ASSERT (result == 0);
276 // Create handlers
277 Handler handler (pipe1);
278 Different_Handler different_handler (pipe2);
280 // Manage memory automagically.
281 std::unique_ptr<ACE_Reactor> reactor (create_reactor ());
283 // Register handlers
284 ACE_Reactor_Mask handler_mask =
285 ACE_Event_Handler::READ_MASK |
286 ACE_Event_Handler::WRITE_MASK |
287 ACE_Event_Handler::EXCEPT_MASK;
289 ACE_Reactor_Mask different_handler_mask =
290 ACE_Event_Handler::WRITE_MASK |
291 ACE_Event_Handler::EXCEPT_MASK;
293 result = reactor->register_handler (&handler,
294 handler_mask);
295 ACE_TEST_ASSERT (result == 0);
297 result = reactor->register_handler (&different_handler,
298 different_handler_mask);
299 ACE_TEST_ASSERT (result == 0);
301 // Write to the pipe; this causes handle_input to get called.
302 if (write_to_pipe_in_main)
304 write_to_pipe (pipe1);
305 write_to_pipe (pipe2);
308 // Note that handle_output will get called automatically since the
309 // pipe is writable!
311 // Run for three seconds
312 ACE_Time_Value wait_time (3);
314 reactor->run_reactor_event_loop (wait_time);
316 ACE_DEBUG ((LM_DEBUG, "\nClosing down the application\n\n"));
318 return 0;