Make x.0.10 publicly available
[ACE_TAO.git] / ACE / tests / NonBlocking_Conn_Test.cpp
blob8c1019093b76f215faff8155a306818a7d62e528
2 //=============================================================================
3 /**
4 * @file NonBlocking_Conn_Test.cpp
6 * This test checks for the proper working of the following:
7 * - blocking connections
8 * - blocking connections with timeouts
9 * - non-blocking connections
10 * - non-blocking connections without waiting for completions
11 * - non-blocking connections with timeouts
13 * @author Irfan Pyarali <irfan@oomworks.com>
15 //=============================================================================
18 #include "test_config.h"
19 #include "NonBlocking_Conn_Test.h"
20 #include "ace/Connector.h"
21 #include "ace/SOCK_Connector.h"
22 #include "ace/Select_Reactor.h"
23 #include "ace/TP_Reactor.h"
24 #include "ace/WFMO_Reactor.h"
25 #include "ace/Get_Opt.h"
27 static bool test_select_reactor = true;
28 static bool test_tp_reactor = true;
29 static bool test_wfmo_reactor = true;
30 static int result = 0;
32 Svc_Handler::Svc_Handler (bool is_ref_counted)
33 : status_ (0),
34 completion_counter_ (0),
35 is_ref_counted_ (is_ref_counted)
37 if (this->is_ref_counted_)
39 // Enable reference counting on the event handler.
40 this->reference_counting_policy ().value (
41 ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
45 void
46 Svc_Handler::connection_status (Connection_Status &status,
47 int &completion_counter)
49 this->status_ = &status;
50 this->completion_counter_ = &completion_counter;
53 int
54 Svc_Handler::open (void *)
56 *this->status_ = Svc_Handler::Conn_SUCCEEDED;
57 (*this->completion_counter_)++;
59 ACE_TCHAR buf[BUFSIZ];
60 ACE_INET_Addr raddr;
61 this->peer ().get_remote_addr (raddr);
62 raddr.addr_to_string (buf, sizeof buf);
64 ACE_DEBUG ((LM_DEBUG,
65 ACE_TEXT ("Connection to %s is opened\n"),
66 buf));
68 return 0;
71 int
72 Svc_Handler::handle_close (ACE_HANDLE handle, ACE_Reactor_Mask mask)
74 *this->status_ = Svc_Handler::Conn_FAILED;
75 (*this->completion_counter_)++;
77 // Only if there is no reference counting can call parent's
78 // handle_close() as it does plain 'delete this'.
79 if (!this->is_ref_counted_)
81 using super = ACE_Svc_Handler<ACE_SOCK_Stream, ACE_NULL_SYNCH>;
83 return super::handle_close (handle, mask);
86 return 0;
89 using CONNECTOR = ACE_Connector<Svc_Handler, ACE_SOCK_Connector>;
91 static const char* hosts[] = {
92 "www.russiantvguide.com:80",
93 "news.bbc.co.uk:80",
94 "www.cnn.com:80",
95 "www.waca.com.au:80",
96 "www.uganda.co.ug:80",
97 "cse.wustl.edu:80",
98 "www.dre.vanderbilt.edu:80",
99 "www.msn.com:80",
100 "www.presidencymaldives.gov.mv:80"
103 static int number_of_connections = 0;
104 static bool with_ref_counting = false;
106 void
107 test_connect (ACE_Reactor &reactor,
108 ACE_INET_Addr *addresses,
109 ACE_Synch_Options &synch_options,
110 Svc_Handler::Completion_Status complete_nonblocking_connections)
112 CONNECTOR connector (&reactor);
114 int i = 0;
116 int completion_counter = 0;
117 Svc_Handler::Connection_Status *connection_status =
118 new Svc_Handler::Connection_Status[number_of_connections];
120 Svc_Handler **svc_handlers =
121 new Svc_Handler *[number_of_connections];
123 for (i = 0; i < number_of_connections; ++i)
125 svc_handlers[i] =
126 new Svc_Handler (with_ref_counting);
128 svc_handlers[i]->connection_status (connection_status[i],
129 completion_counter);
132 connector.connect_n (number_of_connections,
133 svc_handlers,
134 addresses,
136 synch_options);
138 if (!synch_options[ACE_Synch_Options::USE_REACTOR])
139 ACE_TEST_ASSERT (completion_counter == number_of_connections);
141 if (complete_nonblocking_connections != Svc_Handler::Comp_NO)
143 while (completion_counter != number_of_connections)
145 connector.reactor ()->handle_events ();
149 connector.close ();
151 for (i = 0; i < number_of_connections; ++i)
153 ACE_TCHAR buffer[1024];
154 addresses[i].addr_to_string (buffer,
155 sizeof buffer / sizeof (ACE_TCHAR),
158 ACE_DEBUG ((LM_DEBUG,
159 ACE_TEXT ("Connection to %s %s\n"),
160 buffer,
161 connection_status[i] == Svc_Handler::Conn_SUCCEEDED ?
162 ACE_TEXT("succeeded") : ACE_TEXT("failed")));
164 ACE_Event_Handler_var release_guard;
165 if (with_ref_counting)
167 release_guard.reset (svc_handlers[i]);
170 if (connection_status[i] == Svc_Handler::Conn_SUCCEEDED)
172 svc_handlers[i]->close ();
176 delete[] svc_handlers;
177 delete[] connection_status;
180 void
181 test (ACE_Reactor_Impl *impl)
183 size_t const nr_names = sizeof hosts / sizeof (char *);
184 ACE_INET_Addr *addresses = new ACE_INET_Addr[nr_names];
185 number_of_connections = 0;
187 for (size_t i = 0; i < nr_names; ++i)
189 if (addresses[number_of_connections].set (hosts[i]) == 0)
190 ++number_of_connections;
191 else
192 ACE_DEBUG ((LM_INFO,
193 ACE_TEXT ("%p\n"),
194 ACE_TEXT_CHAR_TO_TCHAR (hosts[i])));
197 ACE_Reactor reactor (impl, 1);
199 ACE_Synch_Options blocking_connect =
200 ACE_Synch_Options::defaults;
202 ACE_DEBUG ((LM_DEBUG,
203 "Blocking connections...\n"));
205 test_connect (reactor,
206 addresses,
207 blocking_connect,
208 Svc_Handler::Comp_IGNORE);
210 blocking_connect.set (ACE_Synch_Options::USE_TIMEOUT,
211 ACE_Time_Value (0, 50 * 1000));
213 ACE_DEBUG ((LM_DEBUG,
214 "Blocking connections (with timeouts)...\n"));
216 test_connect (reactor,
217 addresses,
218 blocking_connect,
219 Svc_Handler::Comp_IGNORE);
221 ACE_Synch_Options nonblocking_connect
222 (ACE_Synch_Options::USE_REACTOR);
224 ACE_DEBUG ((LM_DEBUG,
225 "Non-blocking connections...\n"));
227 test_connect (reactor,
228 addresses,
229 nonblocking_connect,
230 Svc_Handler::Comp_YES);
232 ACE_DEBUG ((LM_DEBUG,
233 "Non-blocking connections (without waiting for completions)...\n"));
235 test_connect (reactor,
236 addresses,
237 nonblocking_connect,
238 Svc_Handler::Comp_NO);
240 nonblocking_connect.set (ACE_Synch_Options::USE_REACTOR |
241 ACE_Synch_Options::USE_TIMEOUT,
242 ACE_Time_Value (0, 500 * 1000));
244 ACE_DEBUG ((LM_DEBUG,
245 "Non-blocking connections (with timeouts)...\n"));
247 test_connect (reactor,
248 addresses,
249 nonblocking_connect,
250 Svc_Handler::Comp_YES);
252 delete[] addresses;
255 static int
256 parse_args (int argc, ACE_TCHAR *argv[])
258 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:"));
260 int cc;
261 while ((cc = get_opt ()) != -1)
263 switch (cc)
265 case 'a':
266 test_select_reactor = ACE_OS::atoi (get_opt.opt_arg ());
267 break;
268 case 'b':
269 test_tp_reactor = ACE_OS::atoi (get_opt.opt_arg ());
270 break;
271 case 'c':
272 test_wfmo_reactor = ACE_OS::atoi (get_opt.opt_arg ());
273 break;
274 case '?':
275 case 'u':
276 default:
277 ACE_ERROR ((LM_ERROR,
278 ACE_TEXT ("\nusage: %s \n\n")
279 ACE_TEXT ("\t[-a test Select Reactor] (defaults to %d)\n")
280 ACE_TEXT ("\t[-b test TP Reactor] (defaults to %d)\n")
281 ACE_TEXT ("\t[-c test WFMO Reactor] (defaults to %d)\n")
282 ACE_TEXT ("\n"),
283 argv[0],
284 test_select_reactor,
285 test_tp_reactor,
286 test_wfmo_reactor));
287 return -1;
291 return 0;
295 run_main (int argc, ACE_TCHAR *argv[])
297 ACE_START_TEST (ACE_TEXT ("NonBlocking_Conn_Test"));
299 // Validate options.
300 result = parse_args (argc, argv);
301 if (result != 0)
302 return result;
304 if (test_select_reactor)
306 ACE_DEBUG ((LM_DEBUG,
307 "Testing Select Reactor....\n"));
309 with_ref_counting = false;
310 test (new ACE_Select_Reactor);
312 ACE_DEBUG ((LM_DEBUG,
313 "Testing Select Reactor (ref counted)....\n"));
315 with_ref_counting = true;
316 test (new ACE_Select_Reactor);
319 if (test_tp_reactor)
321 ACE_DEBUG ((LM_DEBUG,
322 "Testing TP Reactor....\n"));
324 with_ref_counting = false;
325 test (new ACE_TP_Reactor);
327 ACE_DEBUG ((LM_DEBUG,
328 "Testing TP Reactor (ref counted)....\n"));
330 with_ref_counting = true;
331 test (new ACE_TP_Reactor);
334 #if defined (ACE_WIN32)
336 if (test_wfmo_reactor)
338 ACE_DEBUG ((LM_DEBUG,
339 "Testing WFMO Reactor....\n"));
341 with_ref_counting = false;
342 test (new ACE_WFMO_Reactor);
344 ACE_DEBUG ((LM_DEBUG,
345 "Testing WFMO Reactor (ref counted)....\n"));
347 with_ref_counting = true;
348 test (new ACE_WFMO_Reactor);
351 #endif /* ACE_WIN32 */
353 ACE_END_TEST;
355 return result;