diff options
-rw-r--r-- | ACE/ChangeLog | 27 | ||||
-rw-r--r-- | ACE/ace/Connector.cpp | 29 | ||||
-rw-r--r-- | ACE/ace/Connector.h | 6 | ||||
-rw-r--r-- | ACE/ace/Strategies_T.cpp | 4 | ||||
-rw-r--r-- | ACE/tests/MT_NonBlocking_Connect_Test.cpp | 406 | ||||
-rw-r--r-- | ACE/tests/NonBlocking_Conn_Test.cpp | 85 | ||||
-rw-r--r-- | ACE/tests/NonBlocking_Conn_Test.h | 14 | ||||
-rw-r--r-- | ACE/tests/Process_Strategy_Test.cpp | 14 | ||||
-rw-r--r-- | ACE/tests/run_test.lst | 1 | ||||
-rw-r--r-- | ACE/tests/tests.mpc | 9 |
10 files changed, 556 insertions, 39 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog index 1887c1a3a1f..96b4d79fde9 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,30 @@ +Wed Mar 17 11:58:10 UTC 2010 Vladimir Zykov <vladimir.zykov@prismtech.com> + + Committed the changes that I had to revert before x.7.7. + + * ace/Strategies_T.cpp: + Changed the code so that close() is called in case of failure + instead of destroy(). + + * ace/Connector.cpp: + * ace/Connector.h: + Changed the fix for bug#3731. Now NBCH adds a reference in + constructor and removes it in destructor if the SVC_HANDLER that + it owns is reference counted. This is a cleaner solution than the + one used before. + + * tests/NonBlocking_Conn_Test.h: + * tests/Process_Strategy_Test.cpp: + * tests/NonBlocking_Conn_Test.cpp: + Extended NonBlocking_Conn_Test and changed Process_Strategy_Test + because of the change in Strategies_T.cpp. + + * tests/MT_NonBlocking_Connect_Test.cpp: + * tests/tests.mpc: + * tests/run_test.lst: + Added a new test. This can be a reproducer for the bug#3731 which + currently doesn't have its own test. + Wed Mar 17 08:57:30 UTC 2010 Vladimir Zykov <vladimir.zykov@prismtech.com> * ace/Service_Gestalt.h: diff --git a/ACE/ace/Connector.cpp b/ACE/ace/Connector.cpp index db184ac1253..867fc572384 100644 --- a/ACE/ace/Connector.cpp +++ b/ACE/ace/Connector.cpp @@ -24,6 +24,7 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler long id) : connector_ (connector) , svc_handler_ (sh) + , cleanup_svc_handler_ (0) , timer_id_ (id) { ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler"); @@ -31,8 +32,25 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler this->reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED); - if (this->svc_handler_ != 0) - this->svc_handler_->add_reference (); + if (this->svc_handler_ != 0 && + this->svc_handler_->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED) + { + // If SVC_HANDLER is reference counted then NBCH holds a reference + // in cleanup_svc_handle_ which is both a pointer to SVC_HANDLER + // and a flag that triggers remove_reference in NBCH destructor. + this->cleanup_svc_handler_ = sh; + this->cleanup_svc_handler_->add_reference (); + } +} + +template <class SVC_HANDLER> +ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::~ACE_NonBlocking_Connect_Handler (void) +{ + if (this->cleanup_svc_handler_) + { + this->cleanup_svc_handler_->remove_reference (); + } } template <class SVC_HANDLER> SVC_HANDLER * @@ -132,9 +150,6 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout svc_handler->handle_close (svc_handler->get_handle (), ACE_Event_Handler::TIMER_MASK); - if (svc_handler != 0) - svc_handler->remove_reference (); - return retval; } @@ -153,8 +168,6 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE) if (svc_handler != 0) { svc_handler->close (NORMAL_CLOSE_OPERATION); - - svc_handler->remove_reference (); } return retval; @@ -174,8 +187,6 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle) if (svc_handler != 0) { connector.initialize_svc_handler (handle, svc_handler); - - svc_handler->remove_reference (); } return retval; diff --git a/ACE/ace/Connector.h b/ACE/ace/Connector.h index 4ba8c7ce3dd..5d77ae430e4 100644 --- a/ACE/ace/Connector.h +++ b/ACE/ace/Connector.h @@ -67,6 +67,9 @@ public: SVC_HANDLER *, long timer_id); + /// Destructor. + ~ACE_NonBlocking_Connect_Handler (void); + /// Close up and return underlying SVC_HANDLER through @c sh. /** * If the return value is true the close was performed succesfully, @@ -127,6 +130,9 @@ private: /// Associated SVC_HANDLER. SVC_HANDLER *svc_handler_; + /// Same as svc_handler_ if svc_handler_ is reference counted. + SVC_HANDLER *cleanup_svc_handler_; + /// Associated timer id. long timer_id_; }; diff --git a/ACE/ace/Strategies_T.cpp b/ACE/ace/Strategies_T.cpp index 6aaef5eb2cc..4addb7d3774 100644 --- a/ACE/ace/Strategies_T.cpp +++ b/ACE/ace/Strategies_T.cpp @@ -439,7 +439,7 @@ ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handle case -1: { ACE_Errno_Guard error (errno); - svc_handler->destroy (); + svc_handler->close (); } ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), @@ -462,7 +462,7 @@ ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handle default: // In parent process. // We need to close down the <SVC_HANDLER> here because it's // running in the child. - svc_handler->destroy (); + svc_handler->close (); return 0; } } diff --git a/ACE/tests/MT_NonBlocking_Connect_Test.cpp b/ACE/tests/MT_NonBlocking_Connect_Test.cpp new file mode 100644 index 00000000000..7fcf1337277 --- /dev/null +++ b/ACE/tests/MT_NonBlocking_Connect_Test.cpp @@ -0,0 +1,406 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// MT_NonBlocking_Connect_Test.cpp +// +// = DESCRIPTION +// +// This test makes non-blocking connects from multiple threads. Things are +// complicated by the fact that after the connection is attempted reactor's +// handle_events() is called and this leads to possible connection +// completion in the other thread. This is similar to what TAO does for +// oneway with SYNC_NONE sync scope policy. +// The following reactors are tested: Select, TP, WFMO, and Dev Poll +// (if enabled). +// +// = AUTHOR +// Vladimir Zykov <vladimir.zykov@prismtech.com> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Reactor.h" +#include "ace/Select_Reactor.h" +#include "ace/TP_Reactor.h" +#include "ace/WFMO_Reactor.h" +#include "ace/Dev_Poll_Reactor.h" +#include "ace/Svc_Handler.h" +#include "ace/SOCK_Stream.h" +#include "ace/Get_Opt.h" +#include "ace/Task.h" +#include "ace/Connector.h" +#include "ace/SOCK_Connector.h" +#include "ace/Thread_Mutex.h" + +ACE_RCSID(tests, + MT_NonBlocking_Connect_Test, + "$Id$") + +#if defined (ACE_HAS_THREADS) + +static int test_select_reactor = 1; +static int test_tp_reactor = 1; +static int test_wfmo_reactor = 1; +static int test_dev_poll_reactor = 1; +static int number_of_threads = 10; +static int debug = 0; +static int result = 0; + +static const ACE_TCHAR* hosts[] = { + ACE_TEXT ("www.russiantvguide.com:80"), + ACE_TEXT ("news.bbc.co.uk:80"), + ACE_TEXT ("www.cnn.com:80"), + ACE_TEXT ("www.waca.com.au:80"), + ACE_TEXT ("www.uganda.co.ug:80"), + ACE_TEXT ("www.cs.wustl.edu:80"), + ACE_TEXT ("www.dre.vanderbilt.edu:80"), + ACE_TEXT ("www.dhm.gov.np:80"), + ACE_TEXT ("www.msn.com:80"), + ACE_TEXT ("www.presidencymaldives.gov.mv:80") +}; + +class Svc_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> +{ +public: + Svc_Handler (void) + { + ACE_TEST_ASSERT (0); + } + + Svc_Handler (ACE_Thread_Manager *); + + int open (void *); + + int close (u_long flags); + + bool connected_; +}; + +Svc_Handler::Svc_Handler (ACE_Thread_Manager *) + : connected_ (false) +{ + this->reference_counting_policy ().value ( + ACE_Event_Handler::Reference_Counting_Policy::ENABLED); +} + +int +Svc_Handler::open (void *) +{ + this->connected_ = true; + return 0; +} + +int +Svc_Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, + "%t close connection on handle %d.\n", + this->get_handle ())); + return 0; +} + +template<class SVC_HANDLER> +class Concurrency_Strategy : + public ACE_Concurrency_Strategy<SVC_HANDLER> +{ +public: + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, void *arg); +}; + +template<class SVC_HANDLER> int +Concurrency_Strategy<SVC_HANDLER>:: + activate_svc_handler (SVC_HANDLER *svc_handler, void *arg) +{ + // Every fourth connection fails. + static long count = 0; + if (++count % 4 == 0) + { + ACE_DEBUG ((LM_DEBUG, + "%t connection on handle %d has artificially failed.\n", + svc_handler->get_handle ())); + return -1; + } + else + { + return ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler ( + svc_handler, arg); + } +} + +typedef ACE_Creation_Strategy<Svc_Handler> CREATION_STRATEGY; +typedef ACE_Connect_Strategy<Svc_Handler, + ACE_SOCK_CONNECTOR> CONNECT_STRATEGY; +typedef Concurrency_Strategy<Svc_Handler> CONCURRENCY_STRATEGY; +typedef ACE_Strategy_Connector<Svc_Handler, + ACE_SOCK_CONNECTOR> BASE_CONNECTOR; + +class Connect_Thread : public ACE_Task_Base +{ +public: + Connect_Thread (ACE_Thread_Manager &thread_manager, + ACE_Reactor &reactor, + ACE_Thread_Mutex &reactor_lock) + : ACE_Task_Base (&thread_manager) + , reactor_ (reactor) + , reactor_lock_ (reactor_lock) + , threads_ (number_of_threads) + { + // Open the connector. + this->base_connector_.open (&this->reactor_, + &this->cns_, &this->cts_, &this->cys_); + } + + int svc (void); + +private: + ACE_Reactor &reactor_; + ACE_Thread_Mutex &reactor_lock_; + + CREATION_STRATEGY cns_; + CONNECT_STRATEGY cts_; + CONCURRENCY_STRATEGY cys_; + BASE_CONNECTOR base_connector_; + + ACE_Atomic_Op<ACE_Thread_Mutex, long> threads_; +}; + +int +Connect_Thread::svc (void) +{ + size_t const nr_names = sizeof hosts / sizeof (char *); + ACE_INET_Addr *addresses = new ACE_INET_Addr[nr_names]; + + for (size_t i = 0; i < nr_names; ++i) + { + if (addresses[i].set (hosts[i]) != 0) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("%p\n"), + hosts[i])); + } + } + + ACE_INET_Addr local_addr; + ACE_Synch_Options synch_options (ACE_Synch_Options::USE_REACTOR); + + for (size_t i = 0; i < nr_names; ++i) + { + ACE_INET_Addr &remote_addr = addresses[i]; + + ACE_DEBUG ((LM_DEBUG, + "%t connecting to %s...\n", + hosts[i])); + + // Create a new handler. It's what begin_connection() in TAO does. + Svc_Handler *svc_handler = 0; + result = this->base_connector_.connect (svc_handler, + remote_addr, + synch_options, + local_addr); + ACE_Event_Handler_var release_guard (svc_handler); + + // Complete connection. It's what complete_connection() in TAO does. + // Not exactly but for the test it's enough. + while (this->reactor_.work_pending ()) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, + this->reactor_lock_, -1); + + if (this->reactor_.work_pending ()) + { + ACE_DEBUG ((LM_DEBUG, + "%t waiting for connection to %s...\n", + hosts[i])); + + this->reactor_.owner (ACE_Thread::self ()); + + this->reactor_.handle_events (); + } + } + + if (svc_handler->connected_) + { + this->reactor_.register_handler (svc_handler, + ACE_Event_Handler::READ_MASK); + + ACE_DEBUG ((LM_DEBUG, + "%t connection for %s completed on handle %d.\n", + hosts[i], + svc_handler->get_handle ())); + // We are connected successfully. Close the connection. + this->reactor_.remove_handler (svc_handler->get_handle (), + ACE_Event_Handler::ALL_EVENTS_MASK | + ACE_Event_Handler::DONT_CALL); + } + else + { + // Connection didn't succeed. svc_handler will be deleted when + // we go out of the scope of this loop. + ACE_DEBUG ((LM_DEBUG, + "%t connection for %s did not complete.\n", + hosts[i])); + } + } + + if (--this->threads_ == 0) + { + // Close the connector. + this->base_connector_.close (); + } + + delete[] addresses; + + return 0; +} + +void +test (ACE_Reactor_Impl *reactor_impl) +{ + ACE_Reactor reactor (reactor_impl, true); + + ACE_Thread_Mutex reactor_lock; + ACE_Thread_Manager thread_manager; + + ACE_DEBUG ((LM_DEBUG, + "Starting %d connection threads...\n", + number_of_threads)); + + Connect_Thread connect_thread (thread_manager, reactor, reactor_lock); + result = connect_thread.activate (THR_NEW_LWP|THR_JOINABLE, + number_of_threads); + ACE_TEST_ASSERT (result == 0); + + // Wait for threads to exit. + result = thread_manager.wait (); + ACE_TEST_ASSERT (result == 0); +} + +static int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:d:f:g:k:lm:n:o:uz:")); + + 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 'd': + test_dev_poll_reactor = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'f': + number_of_threads = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'z': + debug = ACE_OS::atoi (get_opt.opt_arg ()); + break; + 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 ("\t[-d test Dev Poll Reactor] (defaults to %d)\n") + ACE_TEXT ("\t[-f number of threads] (defaults to %d)\n") + ACE_TEXT ("\t[-z debug] (defaults to %d)\n") + ACE_TEXT ("\n"), + argv[0], + test_select_reactor, + test_tp_reactor, + test_wfmo_reactor, + test_dev_poll_reactor, + number_of_threads, + debug)); + return -1; + } + } + + return 0; +} + +int +run_main (int argc, ACE_TCHAR *argv[]) +{ + ACE_START_TEST (ACE_TEXT ("MT_NonBlocking_Connect_Test")); + + // Validate options. + result = parse_args (argc, argv); + if (result != 0) + return result; + + if (test_select_reactor) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n\n(%t) Testing Select Reactor....\n\n"))); + + test (new ACE_Select_Reactor); + } + + if (test_tp_reactor) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n\n(%t) Testing TP Reactor....\n\n"))); + + test (new ACE_TP_Reactor); + } + +#if defined (ACE_HAS_EVENT_POLL) + + if (test_dev_poll_reactor) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n\n(%t) Testing Dev Poll Reactor....\n\n"))); + + test (new ACE_Dev_Poll_Reactor); + } + +#endif + +#if defined (ACE_WIN32) + + if (test_wfmo_reactor) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n\n(%t) Testing WFMO Reactor....\n\n"))); + + test (new ACE_WFMO_Reactor); + } + +#endif /* ACE_WIN32 */ + + ACE_END_TEST; + + return result; +} + +#else /* ACE_HAS_THREADS */ + +int +run_main (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("MT_NonBlocking_Connect_Test")); + + ACE_ERROR ((LM_INFO, + ACE_TEXT ("threads not supported on this platform\n"))); + + ACE_END_TEST; + + return result; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/tests/NonBlocking_Conn_Test.cpp b/ACE/tests/NonBlocking_Conn_Test.cpp index 7ca7df557a2..3161dea906a 100644 --- a/ACE/tests/NonBlocking_Conn_Test.cpp +++ b/ACE/tests/NonBlocking_Conn_Test.cpp @@ -35,10 +35,17 @@ static bool test_tp_reactor = true; static bool test_wfmo_reactor = true; static int result = 0; -Svc_Handler::Svc_Handler (void) +Svc_Handler::Svc_Handler (bool is_ref_counted) : status_ (0), - completion_counter_ (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 @@ -52,7 +59,7 @@ Svc_Handler::connection_status (Connection_Status &status, int Svc_Handler::open (void *) { - *this->status_ = SUCCEEDED; + *this->status_ = Svc_Handler::Conn_SUCCEEDED; (*this->completion_counter_)++; return 0; @@ -61,18 +68,26 @@ Svc_Handler::open (void *) int Svc_Handler::handle_close (ACE_HANDLE handle, ACE_Reactor_Mask mask) { - *this->status_ = FAILED; + *this->status_ = Svc_Handler::Conn_FAILED; (*this->completion_counter_)++; - return ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::handle_close (handle, - mask); + // 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", - "www.pakarmy.gov.pk:80", + "news.bbc.co.uk:80", "www.cnn.com:80", "www.waca.com.au:80", "www.uganda.co.ug:80", @@ -80,15 +95,17 @@ static const char* hosts[] = { "www.dre.vanderbilt.edu:80", "www.dhm.gov.np:80", "www.msn.com:80", - "www.presidencymaldives.gov.mv: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, - int complete_nonblocking_connections) + Svc_Handler::Completion_Status complete_nonblocking_connections) { CONNECTOR connector (&reactor); @@ -104,7 +121,7 @@ test_connect (ACE_Reactor &reactor, for (i = 0; i < number_of_connections; ++i) { svc_handlers[i] = - new Svc_Handler; + new Svc_Handler (with_ref_counting); svc_handlers[i]->connection_status (connection_status[i], completion_counter); @@ -119,7 +136,7 @@ test_connect (ACE_Reactor &reactor, if (!synch_options[ACE_Synch_Options::USE_REACTOR]) ACE_ASSERT (completion_counter == number_of_connections); - if (complete_nonblocking_connections) + if (complete_nonblocking_connections != Svc_Handler::Comp_NO) { while (completion_counter != number_of_connections) { @@ -139,10 +156,16 @@ test_connect (ACE_Reactor &reactor, ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Connection to %s %s\n"), buffer, - connection_status[i] == Svc_Handler::SUCCEEDED ? + connection_status[i] == Svc_Handler::Conn_SUCCEEDED ? ACE_TEXT("succeeded") : ACE_TEXT("failed"))); - if (connection_status[i] == Svc_Handler::SUCCEEDED) + 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 (); } @@ -171,10 +194,6 @@ test (ACE_Reactor_Impl *impl) ACE_Reactor reactor (impl, 1); - int complete_nonblocking_connections = 1; - int dont_wait_for_nonblocking_connections = 0; - int ignored = 99; - ACE_Synch_Options blocking_connect = ACE_Synch_Options::defaults; @@ -184,7 +203,7 @@ test (ACE_Reactor_Impl *impl) test_connect (reactor, addresses, blocking_connect, - ignored); + Svc_Handler::Comp_IGNORE); blocking_connect.set (ACE_Synch_Options::USE_TIMEOUT, ACE_Time_Value (0, 50 * 1000)); @@ -195,7 +214,7 @@ test (ACE_Reactor_Impl *impl) test_connect (reactor, addresses, blocking_connect, - ignored); + Svc_Handler::Comp_IGNORE); ACE_Synch_Options nonblocking_connect (ACE_Synch_Options::USE_REACTOR); @@ -206,7 +225,7 @@ test (ACE_Reactor_Impl *impl) test_connect (reactor, addresses, nonblocking_connect, - complete_nonblocking_connections); + Svc_Handler::Comp_YES); ACE_DEBUG ((LM_DEBUG, "Non-blocking connections (without waiting for completions)...\n")); @@ -214,7 +233,7 @@ test (ACE_Reactor_Impl *impl) test_connect (reactor, addresses, nonblocking_connect, - dont_wait_for_nonblocking_connections); + Svc_Handler::Comp_NO); nonblocking_connect.set (ACE_Synch_Options::USE_REACTOR | ACE_Synch_Options::USE_TIMEOUT, @@ -226,7 +245,7 @@ test (ACE_Reactor_Impl *impl) test_connect (reactor, addresses, nonblocking_connect, - complete_nonblocking_connections); + Svc_Handler::Comp_YES); delete[] addresses; } @@ -285,6 +304,13 @@ run_main (int argc, ACE_TCHAR *argv[]) 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); } @@ -293,6 +319,13 @@ run_main (int argc, ACE_TCHAR *argv[]) 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); } @@ -303,6 +336,13 @@ run_main (int argc, ACE_TCHAR *argv[]) 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); } @@ -312,4 +352,3 @@ run_main (int argc, ACE_TCHAR *argv[]) return result; } - diff --git a/ACE/tests/NonBlocking_Conn_Test.h b/ACE/tests/NonBlocking_Conn_Test.h index 77746238226..dc52f3fe694 100644 --- a/ACE/tests/NonBlocking_Conn_Test.h +++ b/ACE/tests/NonBlocking_Conn_Test.h @@ -33,11 +33,18 @@ public: enum Connection_Status { - SUCCEEDED, - FAILED + Conn_SUCCEEDED, + Conn_FAILED }; - Svc_Handler (void); + enum Completion_Status + { + Comp_YES, + Comp_NO, + Comp_IGNORE + }; + + Svc_Handler (bool is_ref_counted = false); void connection_status (Connection_Status &status, int &completion_counter); @@ -49,6 +56,7 @@ public: Connection_Status *status_; int *completion_counter_; + bool is_ref_counted_; }; #endif /* NONBLOCKING_CONN_TEST_H */ diff --git a/ACE/tests/Process_Strategy_Test.cpp b/ACE/tests/Process_Strategy_Test.cpp index a4f0d3123ba..74cbf0bfe12 100644 --- a/ACE/tests/Process_Strategy_Test.cpp +++ b/ACE/tests/Process_Strategy_Test.cpp @@ -441,8 +441,18 @@ int Counting_Service::handle_close (ACE_HANDLE, ACE_Reactor_Mask) { - // Done with another connection. - connection_completed (); + // Count completed connections here only when the test is not in + // "process-per-connection" mode. In general, this should not be + // done here. Proper place for this is activate_svc_handler() but + // since only "process-per-connection" hooks into that function in + // other modes it's done here. The later creates a problem in + // "process-per-connection" mode since it calculates the same + // connection twice and as a result it cannot finalize gracefully. + if (OPTIONS::instance ()->concurrency_type () != Options::PROCESS) + { + // Done with another connection. + connection_completed (); + } // Call down to base class return ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::handle_close (); diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst index 9b94dbf38d5..1381a8dd0e7 100644 --- a/ACE/tests/run_test.lst +++ b/ACE/tests/run_test.lst @@ -114,6 +114,7 @@ Logging_Strategy_Test: !LynxOS !STATIC !ST Manual_Event_Test MEM_Stream_Test: !VxWorks !nsk !ACE_FOR_TAO !PHARLAP !QNX !LynxOS MM_Shared_Memory_Test: !Unicos !VxWorks !nsk !ACE_FOR_TAO +MT_NonBlocking_Connect_Test: !ST MT_Reactor_Timer_Test MT_Reactor_Upcall_Test: !nsk MT_Reference_Counted_Event_Handler_Test: !OpenVMS_IA64Crash diff --git a/ACE/tests/tests.mpc b/ACE/tests/tests.mpc index d2eaafb48f0..032c6b53203 100644 --- a/ACE/tests/tests.mpc +++ b/ACE/tests/tests.mpc @@ -1630,6 +1630,15 @@ project(NonBlocking Conn Test) : acetest { } } +project(MT NonBlocking Connect Test) : acetest { + exename = MT_NonBlocking_Connect_Test + Source_Files { + MT_NonBlocking_Connect_Test.cpp + } + Header_Files { + } +} + project(Reference Counted Event Handler Test) : acetest { exename = Reference_Counted_Event_Handler_Test Source_Files { |