summaryrefslogtreecommitdiff
path: root/ACE/tests/Reactor_Notify_Test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/tests/Reactor_Notify_Test.cpp')
-rw-r--r--ACE/tests/Reactor_Notify_Test.cpp581
1 files changed, 0 insertions, 581 deletions
diff --git a/ACE/tests/Reactor_Notify_Test.cpp b/ACE/tests/Reactor_Notify_Test.cpp
deleted file mode 100644
index 15adcd8eab6..00000000000
--- a/ACE/tests/Reactor_Notify_Test.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-// $Id$
-
-// ============================================================================
-//
-// = LIBRARY
-// tests
-//
-// = FILENAME
-// Reactor_Notify_Test.cpp
-//
-// = DESCRIPTION
-// This is a test that illustrates how the <ACE_Reactor>'s
-// <notify> method works under various <max_notify_iterations>
-// settings. It also tests that the <disable_notify_pipe> option
-// works correctly. Moreover, if the $ACE_ROOT/ace/config.h file
-// has the ACE_HAS_REACTOR_NOTIFICATION_QUEUE option enabled this
-// test will also exercise this feature.
-//
-// = AUTHOR
-// Douglas C. Schmidt <schmidt@cs.wustl.edu>
-//
-// ============================================================================
-
-#include "test_config.h"
-#include "ace/OS_NS_unistd.h"
-#include "ace/Synch_Traits.h"
-#include "ace/Task.h"
-#include "ace/Pipe.h"
-#include "ace/Auto_Ptr.h"
-#include "ace/Reactor.h"
-#include "ace/Select_Reactor.h"
-#include "ace/Thread_Semaphore.h"
-
-ACE_RCSID(tests, Reactor_Notify_Test, "$Id$")
-
-#if defined (ACE_HAS_THREADS)
-
-static const time_t LONG_TIMEOUT = 10;
-static const time_t SHORT_TIMEOUT = 2;
-
-// A class to run a quiet event loop in one thread, and a plain notify()
-// from the main thread to make sure a simple notify will wake up a quiet
-// reactor.
-class Quiet_Notify_Tester : public ACE_Task<ACE_NULL_SYNCH>
-{
-public:
- Quiet_Notify_Tester (void) : result_ (0) {}
- ~Quiet_Notify_Tester (void) { this->wait (); }
-
- //FUZZ: disable check_for_lack_ACE_OS
- virtual int open (void * = 0);
- // Start the reactor event thread.
-
- // Run the reactor event loop.
- virtual int svc (void);
-
- // Return the test result, 0 ok, -1 fail
- int result (void) const { return this->result_; }
-
-private:
- ACE_Reactor r_;
- int result_;
-};
-
-int
-Quiet_Notify_Tester::open (void *)
-{
- this->reactor (&this->r_);
- return this->activate ();
-}
-
-int
-Quiet_Notify_Tester::svc (void)
-{
- // Count on the main thread doing a notify in less than LONG_TIMEOUT
- // seconds. If we don't get it, report a failure.
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Starting quiet event loop\n")));
- this->r_.owner (ACE_Thread::self ());
- ACE_Time_Value tmo (LONG_TIMEOUT);
- int status = this->r_.handle_events (&tmo);
- time_t remain = tmo.sec ();
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) event loop status %d, %: secs remain\n"),
- status, remain));
- if (remain == 0)
- {
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("(%t) Notify did not wake quiet event loop\n")));
- this->result_ = -1;
- }
- else
- {
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Notify woke quiet event loop\n")));
- }
- return 0;
-}
-
-static int
-run_quiet_notify_test (void)
-{
- ACE_DEBUG ((LM_DEBUG, "(%t) Starting quiet notify test\n"));
- Quiet_Notify_Tester t;
- if (t.open () == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_TEXT ("%p\n"),
- ACE_TEXT ("Quiet notify activate")),
- -1);
- // Now sleep a bit, then do a simple, reactor wake-up
- ACE_OS::sleep (SHORT_TIMEOUT);
- t.reactor ()->notify ();
- t.wait ();
- ACE_DEBUG ((LM_DEBUG, "(%t) Quiet notify test done\n"));
- return t.result ();
-}
-
-
-class Supplier_Task : public ACE_Task<ACE_MT_SYNCH>
-{
-public:
- Supplier_Task (int disable_notify_pipe,
- const ACE_Time_Value &tv);
- // Constructor.
-
- ~Supplier_Task (void);
- // Destructor.
-
- //FUZZ: disable check_for_lack_ACE_OS
- virtual int open (void * = 0);
- // Make this an Active Object.
-
- virtual int close (u_long);
- // Close down the supplier.
- //FUZZ: enable check_for_lack_ACE_OS
-
- virtual int svc (void);
- // Generates events and sends them to the <Reactor>'s <notify>
- // method.
-
- virtual int handle_exception (ACE_HANDLE);
- // Releases the <waiter_> semaphore when called by the <Reactor>'s
- // notify handler.
-
- virtual int handle_output (ACE_HANDLE);
- // Called every time through the main <ACE_Reactor> event loop to
- // illustrate the difference between "limited" and "unlimited"
- // notification.
-
- void release (void);
- // Release the <waiter_>.
-
-private:
- int perform_notifications (int notifications);
- // Perform the notifications.
-
- ACE_Thread_Semaphore waiter_;
- // Used to hand-shake between the <Supplier_Task> and the
- // <Reactor>'s notify mechanism.
-
- ACE_Pipe pipe_;
- // We use this pipe just to get a handle that is always "active,"
- // i.e., the <ACE_Reactor> will always dispatch its <handle_output>
- // method.
-
- int disable_notify_pipe_;
- // Keeps track of whether the notification pipe in the <ACE_Reactor>
- // has been diabled or not.
-
- int long_timeout_;
- // Keeps track of whether we're running with a <LONG_TIMEOUT>, which
- // is used for the ACE_HAS_REACTOR_NOTIFICATION_QUEUE portion of
- // this test.
-};
-
-void
-Supplier_Task::release (void)
-{
- this->waiter_.release ();
-}
-
-Supplier_Task::Supplier_Task (int disable_notify_pipe,
- const ACE_Time_Value &tv)
- : waiter_ ((unsigned int) 0), // Make semaphore "locked" by default.
- disable_notify_pipe_ (disable_notify_pipe),
- long_timeout_ (tv.sec () == LONG_TIMEOUT)
-{
-}
-
-int
-Supplier_Task::open (void *)
-{
- // Create the pipe.
- int result;
-
- result = this->pipe_.open ();
- ACE_ASSERT (result != -1);
-
- // Register the pipe's write handle with the <Reactor> for writing.
- // This should mean that it's always "active."
- if (long_timeout_ == 0)
- {
- result = ACE_Reactor::instance ()->register_handler
- (this->pipe_.write_handle (),
- this,
- ACE_Event_Handler::WRITE_MASK);
- ACE_ASSERT (result != -1);
- }
-
- // Make this an Active Object.
- result = this->activate (THR_BOUND | THR_DETACHED);
- ACE_ASSERT (result != -1);
- return 0;
-}
-
-int
-Supplier_Task::close (u_long)
-{
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) Supplier_Task::close\n")));
-
- int result;
-
- if (long_timeout_ == 0)
- {
- result = ACE_Reactor::instance ()->remove_handler
- (this->pipe_.write_handle (),
- ACE_Event_Handler::WRITE_MASK);
- ACE_ASSERT (result != -1);
- }
- else
- {
- // Wait to be told to shutdown by the main thread.
-
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) waiting to be shutdown by main thread\n")));
- result = this->waiter_.acquire ();
- ACE_ASSERT (result != -1);
- }
- return 0;
-}
-
-Supplier_Task::~Supplier_Task (void)
-{
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) ~Supplier_Task\n")));
- this->pipe_.close ();
-}
-
-int
-Supplier_Task::perform_notifications (int notifications)
-{
- ACE_Reactor::instance ()->max_notify_iterations (notifications);
-
- size_t iterations = ACE_MAX_ITERATIONS;
-
- if (this->long_timeout_)
- {
- iterations *= (iterations * iterations * 2);
-#if defined (ACE_VXWORKS)
- // scale down otherwise the test won'y finish in time
- iterations /= 4;
-#endif
- }
-
- for (size_t i = 0; i < iterations; i++)
- {
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) notifying reactor on iteration %d\n"),
- i));
-
- int result;
-
- // Notify the Reactor, which will call <handle_exception>.
- result = ACE_Reactor::instance ()->notify (this);
- if (result == -1)
- {
- if (errno == ETIME)
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) %p\n"),
- ACE_TEXT ("notify")));
- else
- ACE_ASSERT (result != -1);
- }
-
- // Wait for our <handle_exception> method to release the
- // semaphore.
- if (this->long_timeout_ == 0
- && this->disable_notify_pipe_ == 0)
- {
- result = this->waiter_.acquire ();
- ACE_ASSERT (result != -1);
- }
- }
-
- return 0;
-}
-
-int
-Supplier_Task::svc (void)
-{
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) **** starting unlimited notifications test\n")));
-
- // Allow an unlimited number of iterations per
- // <ACE_Reactor::notify>.
- this->perform_notifications (-1);
-
- if (this->long_timeout_ == 0)
- {
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) **** starting limited notifications test\n")));
-
- // Only allow 1 iteration per <ACE_Reactor::notify>
- this->perform_notifications (1);
-
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) **** exiting thread test\n")));
- }
- return 0;
-}
-
-int
-Supplier_Task::handle_exception (ACE_HANDLE handle)
-{
- ACE_ASSERT (handle == ACE_INVALID_HANDLE);
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) handle_exception\n")));
-
- this->waiter_.release ();
- return 0;
-}
-
-int
-Supplier_Task::handle_output (ACE_HANDLE handle)
-{
- ACE_ASSERT (handle == this->pipe_.write_handle ());
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) handle_output\n")));
-
- // This function is called by the main thread, believe it or not :-)
- // That's because the pipe's write handle is always active. Thus,
- // we can give the <Supplier_Task> a chance to run in its own
- // thread.
- ACE_OS::thr_yield ();
-
- return 0;
-}
-
-static int
-run_test (int disable_notify_pipe,
- const ACE_Time_Value &tv)
-{
- // Create special reactors with the appropriate flags enabled.
-
- ACE_Select_Reactor *reactor_impl = 0;
- if (disable_notify_pipe)
- ACE_NEW_RETURN (reactor_impl,
- ACE_Select_Reactor (0, 0, 1),
- -1);
- else
- ACE_NEW_RETURN (reactor_impl,
- ACE_Select_Reactor,
- -1);
-
- ACE_Reactor *reactor;
- ACE_NEW_RETURN (reactor,
- ACE_Reactor (reactor_impl, 1), // Delete implementation
- -1);
-
- // Make sure this stuff gets cleaned up when this function exits.
- auto_ptr<ACE_Reactor> r (reactor);
-
- // Set the Singleton Reactor.
- ACE_Reactor *orig_reactor = ACE_Reactor::instance (reactor);
- ACE_ASSERT (ACE_LOG_MSG->op_status () != -1);
- ACE_ASSERT (ACE_Reactor::instance () == reactor);
-
- Supplier_Task task (disable_notify_pipe,
- tv);
- ACE_ASSERT (ACE_LOG_MSG->op_status () != -1);
-
- int result;
-
- result = task.open ();
- ACE_ASSERT (result != -1);
-
- if (tv.sec () == LONG_TIMEOUT)
- // Sleep for a while so that the <ACE_Reactor>'s notification
- // buffers will fill up!
- ACE_OS::sleep (tv);
-
- int shutdown = 0;
-
- // Run the event loop that handles the <handle_output> and
- // <handle_exception> notifications.
- for (int iteration = 1;
- shutdown == 0;
- iteration++)
- {
- ACE_Time_Value timeout (tv);
-
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) starting handle_events() on iteration %d")
- ACE_TEXT (" with time-out = %d seconds\n"),
- iteration,
- timeout.sec ()));
-
- // Use a timeout to inform the Reactor when to shutdown.
- switch (ACE_Reactor::instance ()->handle_events (timeout))
- {
- case -1:
- if (! disable_notify_pipe)
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("(%t) %p\n"),
- ACE_TEXT ("reactor")));
- shutdown = 1;
- break;
- /* NOTREACHED */
- case 0:
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) handle_events timed out\n")));
- shutdown = 1;
- break;
- /* NOTREACHED */
- default:
- break;
- /* NOTREACHED */
- }
- }
-
- if (tv.sec () == LONG_TIMEOUT)
- {
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) releasing supplier task thread\n")));
- task.release ();
- }
- ACE_Reactor::instance (orig_reactor);
- return 0;
-}
-
-#endif /* ACE_HAS_THREADS */
-
-class Purged_Notify : public ACE_Event_Handler
-{
- // = TITLE
- // <run_notify_purge_test> tests the reactor's
- // purge_pending_notifications function. It does 2 notifications,
- // and explicitly cancels one, and deletes the other's event
- // handler, which should cause it to be cancelled as well.
-
- virtual int handle_exception (ACE_HANDLE = ACE_INVALID_HANDLE)
- {
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_TEXT ("Got a notify that should have been purged!\n")),
- 0);
- }
-};
-
-static int
-run_notify_purge_test (void)
-{
- int status;
- ACE_Reactor *r = ACE_Reactor::instance ();
- {
- Purged_Notify n1;
- Purged_Notify *n2;
-
- ACE_NEW_RETURN (n2, Purged_Notify, -1);
- auto_ptr<Purged_Notify> ap (n2);
-
- // First test:
- // Notify EXCEPT, and purge ALL
- r->notify (&n1); // the mask is EXCEPT_MASK
-
- status = r->purge_pending_notifications (&n1);
- if (status == -1 && errno == ENOTSUP)
- return 0; // Select Reactor w/o ACE_HAS_REACTOR_NOTIFICATION_QUEUE
- if (status != 1)
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("Purged %d notifies; expected 1\n"),
- status));
- // Second test:
- // Notify READ twice, and WRITE once, and purge READ and WRITE - should purge 3 times.
- r->notify (&n1, ACE_Event_Handler::READ_MASK);
- r->notify (&n1, ACE_Event_Handler::READ_MASK);
- r->notify (&n1, ACE_Event_Handler::WRITE_MASK);
- status = r->purge_pending_notifications
- (&n1, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::WRITE_MASK);
- if (status != 3)
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("Purged %d notifies; expected 3\n"),
- status));
- // Third test:
- // Notify READ on 2 handlers, and purge READ|WRITE on all handlers. Should purge 2
- r->notify (&n1, ACE_Event_Handler::READ_MASK);
- r->notify (n2, ACE_Event_Handler::READ_MASK);
- status = r->purge_pending_notifications
- (0, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::WRITE_MASK);
- if (status != 2)
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("Purged %d notifies; expected 2\n"),
- status));
- // Forth test:
- // Notify EXCEPT and WRITE, purge READ. Should not purge
- r->notify (&n1); // the mask is EXCEPT_MASK
- r->notify (&n1, ACE_Event_Handler::WRITE_MASK);
- status = r->purge_pending_notifications
- (&n1, ACE_Event_Handler::READ_MASK);
- if (status != 0)
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("Purged %d notifies; expected 0\n"),
- status));
- // Fifth test:
- r->notify (n2);
-
- // The destructor of the event handler no longer removes the
- // notifications. It is the application's responsability to do
- // so.
- r->purge_pending_notifications(n2,
- ACE_Event_Handler::ALL_EVENTS_MASK);
- r->purge_pending_notifications(&n1,
- ACE_Event_Handler::ALL_EVENTS_MASK);
- }
-
- ACE_Time_Value t (1);
- status = r->handle_events (t); // Should be nothing to do, and time out
- return status < 0 ? 1 : 0; // Return 0 for all ok, else error
-}
-
-
-int
-run_main (int, ACE_TCHAR *[])
-{
- ACE_START_TEST (ACE_TEXT ("Reactor_Notify_Test"));
-
- int test_result = 0; // Innocent until proven guilty
-
- if (0 == run_notify_purge_test ())
- {
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("purge_pending_notifications test OK\n")));
- }
- else
- {
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("purge_pending_notifications test FAIL\n")));
- test_result = 1;
- }
-
-#if defined (ACE_HAS_THREADS)
- if (0 != run_quiet_notify_test ())
- test_result = 1;
-
- ACE_Time_Value timeout (SHORT_TIMEOUT);
-
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) running tests with notify pipe enabled")
- ACE_TEXT (" and time-out = %d seconds\n"),
- timeout.sec ()));
- run_test (0, timeout);
-
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) running tests with notify pipe disabled")
- ACE_TEXT (" and time-out = %d seconds\n"),
- timeout.sec ()));
- run_test (1, timeout);
-
- timeout.set (LONG_TIMEOUT, 0);
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%t) running tests with reactor notification ")
- ACE_TEXT ("pipe enabled\n")
- ACE_TEXT (" and time-out = %d seconds\n"),
- timeout.sec ()));
- run_test (0, timeout);
-
-#else
- ACE_ERROR ((LM_INFO,
- ACE_TEXT ("threads not supported on this platform\n")));
-#endif /* ACE_HAS_THREADS */
- ACE_END_TEST;
- return test_result;
-}