diff options
Diffstat (limited to 'ACE/tests/NonBlocking_Conn_Test.cpp')
-rw-r--r-- | ACE/tests/NonBlocking_Conn_Test.cpp | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/ACE/tests/NonBlocking_Conn_Test.cpp b/ACE/tests/NonBlocking_Conn_Test.cpp new file mode 100644 index 00000000000..95db73ebc90 --- /dev/null +++ b/ACE/tests/NonBlocking_Conn_Test.cpp @@ -0,0 +1,363 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// NonBlocking_Conn_Test.cpp +// +// = DESCRIPTION +// This test checks for the proper working of the following: +// - blocking connections +// - blocking connections with timeouts +// - non-blocking connections +// - non-blocking connections without waiting for completions +// - non-blocking connections with timeouts +// +// = AUTHOR +// Irfan Pyarali <irfan@oomworks.com> +// +// ============================================================================ + +#include "test_config.h" +#include "NonBlocking_Conn_Test.h" +#include "ace/Connector.h" +#include "ace/SOCK_Connector.h" +#include "ace/Select_Reactor.h" +#include "ace/TP_Reactor.h" +#include "ace/WFMO_Reactor.h" +#include "ace/Get_Opt.h" + +static bool test_select_reactor = true; +static bool test_tp_reactor = true; +static bool test_wfmo_reactor = true; +static int result = 0; + +Svc_Handler::Svc_Handler (bool is_ref_counted) + : status_ (0), + completion_counter_ (0), + is_ref_counted_ (is_ref_counted) +{ + if (this->is_ref_counted_) + { + // Enable reference counting on the event handler. + this->reference_counting_policy ().value ( + ACE_Event_Handler::Reference_Counting_Policy::ENABLED); + } +} + +void +Svc_Handler::connection_status (Connection_Status &status, + int &completion_counter) +{ + this->status_ = &status; + this->completion_counter_ = &completion_counter; +} + +int +Svc_Handler::open (void *) +{ + *this->status_ = Svc_Handler::Conn_SUCCEEDED; + (*this->completion_counter_)++; + + ACE_TCHAR buf[BUFSIZ]; + ACE_INET_Addr raddr; + this->peer ().get_remote_addr (raddr); + raddr.addr_to_string (buf, sizeof buf); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Connection to %s is opened\n"), + buf)); + + return 0; +} + +int +Svc_Handler::handle_close (ACE_HANDLE handle, ACE_Reactor_Mask mask) +{ + *this->status_ = Svc_Handler::Conn_FAILED; + (*this->completion_counter_)++; + + // Only if there is no reference counting can call parent's + // handle_close() as it does plain 'delete this'. + if (!this->is_ref_counted_) + { + typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super; + + return super::handle_close (handle, mask); + } + + return 0; +} + +typedef ACE_Connector<Svc_Handler, ACE_SOCK_CONNECTOR> CONNECTOR; + +static const char* hosts[] = { + "www.russiantvguide.com:80", + "news.bbc.co.uk:80", + "www.cnn.com:80", + "www.waca.com.au:80", + "www.uganda.co.ug:80", + "www.cs.wustl.edu:80", + "www.dre.vanderbilt.edu:80", + "www.dhm.gov.np:80", + "www.msn.com:80", + "www.presidencymaldives.gov.mv:80" +}; + +static int number_of_connections = 0; +static bool with_ref_counting = false; + +void +test_connect (ACE_Reactor &reactor, + ACE_INET_Addr *addresses, + ACE_Synch_Options &synch_options, + Svc_Handler::Completion_Status complete_nonblocking_connections) +{ + CONNECTOR connector (&reactor); + + int i = 0; + + int completion_counter = 0; + Svc_Handler::Connection_Status *connection_status = + new Svc_Handler::Connection_Status[number_of_connections]; + + Svc_Handler **svc_handlers = + new Svc_Handler *[number_of_connections]; + + for (i = 0; i < number_of_connections; ++i) + { + svc_handlers[i] = + new Svc_Handler (with_ref_counting); + + svc_handlers[i]->connection_status (connection_status[i], + completion_counter); + } + + connector.connect_n (number_of_connections, + svc_handlers, + addresses, + 0, + synch_options); + + if (!synch_options[ACE_Synch_Options::USE_REACTOR]) + ACE_ASSERT (completion_counter == number_of_connections); + + if (complete_nonblocking_connections != Svc_Handler::Comp_NO) + { + while (completion_counter != number_of_connections) + { + connector.reactor ()->handle_events (); + } + } + + connector.close (); + + for (i = 0; i < number_of_connections; ++i) + { + ACE_TCHAR buffer[1024]; + addresses[i].addr_to_string (buffer, + sizeof buffer / sizeof (ACE_TCHAR), + 1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Connection to %s %s\n"), + buffer, + connection_status[i] == Svc_Handler::Conn_SUCCEEDED ? + ACE_TEXT("succeeded") : ACE_TEXT("failed"))); + + ACE_Event_Handler_var release_guard; + if (with_ref_counting) + { + release_guard.reset (svc_handlers[i]); + } + + if (connection_status[i] == Svc_Handler::Conn_SUCCEEDED) + { + svc_handlers[i]->close (); + } + } + + delete[] svc_handlers; + delete[] connection_status; +} + +void +test (ACE_Reactor_Impl *impl) +{ + size_t const nr_names = sizeof hosts / sizeof (char *); + ACE_INET_Addr *addresses = new ACE_INET_Addr[nr_names]; + number_of_connections = 0; + + for (size_t i = 0; i < nr_names; ++i) + { + if (addresses[number_of_connections].set (hosts[i]) == 0) + ++number_of_connections; + else + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("%p\n"), + ACE_TEXT_CHAR_TO_TCHAR (hosts[i]))); + } + + ACE_Reactor reactor (impl, 1); + + ACE_Synch_Options blocking_connect = + ACE_Synch_Options::defaults; + + ACE_DEBUG ((LM_DEBUG, + "Blocking connections...\n")); + + test_connect (reactor, + addresses, + blocking_connect, + Svc_Handler::Comp_IGNORE); + + blocking_connect.set (ACE_Synch_Options::USE_TIMEOUT, + ACE_Time_Value (0, 50 * 1000)); + + ACE_DEBUG ((LM_DEBUG, + "Blocking connections (with timeouts)...\n")); + + test_connect (reactor, + addresses, + blocking_connect, + Svc_Handler::Comp_IGNORE); + + ACE_Synch_Options nonblocking_connect + (ACE_Synch_Options::USE_REACTOR); + + ACE_DEBUG ((LM_DEBUG, + "Non-blocking connections...\n")); + + test_connect (reactor, + addresses, + nonblocking_connect, + Svc_Handler::Comp_YES); + + ACE_DEBUG ((LM_DEBUG, + "Non-blocking connections (without waiting for completions)...\n")); + + test_connect (reactor, + addresses, + nonblocking_connect, + Svc_Handler::Comp_NO); + + nonblocking_connect.set (ACE_Synch_Options::USE_REACTOR | + ACE_Synch_Options::USE_TIMEOUT, + ACE_Time_Value (0, 500 * 1000)); + + ACE_DEBUG ((LM_DEBUG, + "Non-blocking connections (with timeouts)...\n")); + + test_connect (reactor, + addresses, + nonblocking_connect, + Svc_Handler::Comp_YES); + + delete[] addresses; +} + +static int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:")); + + int cc; + while ((cc = get_opt ()) != -1) + { + switch (cc) + { + case 'a': + test_select_reactor = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'b': + test_tp_reactor = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'c': + test_wfmo_reactor = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case '?': + case 'u': + default: + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("\nusage: %s \n\n") + ACE_TEXT ("\t[-a test Select Reactor] (defaults to %d)\n") + ACE_TEXT ("\t[-b test TP Reactor] (defaults to %d)\n") + ACE_TEXT ("\t[-c test WFMO Reactor] (defaults to %d)\n") + ACE_TEXT ("\n"), + argv[0], + test_select_reactor, + test_tp_reactor, + test_wfmo_reactor)); + return -1; + } + } + + return 0; +} + +int +run_main (int argc, ACE_TCHAR *argv[]) +{ + ACE_START_TEST (ACE_TEXT ("NonBlocking_Conn_Test")); + + // Validate options. + result = parse_args (argc, argv); + if (result != 0) + return result; + + if (test_select_reactor) + { + ACE_DEBUG ((LM_DEBUG, + "Testing Select Reactor....\n")); + + with_ref_counting = false; + test (new ACE_Select_Reactor); + + ACE_DEBUG ((LM_DEBUG, + "Testing Select Reactor (ref counted)....\n")); + + with_ref_counting = true; + test (new ACE_Select_Reactor); + } + + if (test_tp_reactor) + { + ACE_DEBUG ((LM_DEBUG, + "Testing TP Reactor....\n")); + + with_ref_counting = false; + test (new ACE_TP_Reactor); + + ACE_DEBUG ((LM_DEBUG, + "Testing TP Reactor (ref counted)....\n")); + + with_ref_counting = true; + test (new ACE_TP_Reactor); + } + +#if defined (ACE_WIN32) + + if (test_wfmo_reactor) + { + ACE_DEBUG ((LM_DEBUG, + "Testing WFMO Reactor....\n")); + + with_ref_counting = false; + test (new ACE_WFMO_Reactor); + + ACE_DEBUG ((LM_DEBUG, + "Testing WFMO Reactor (ref counted)....\n")); + + with_ref_counting = true; + test (new ACE_WFMO_Reactor); + } + +#endif /* ACE_WIN32 */ + + ACE_END_TEST; + + return result; +} |