diff options
Diffstat (limited to 'ACE/examples/Reactor/WFMO_Reactor/Handle_Close.cpp')
-rw-r--r-- | ACE/examples/Reactor/WFMO_Reactor/Handle_Close.cpp | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/ACE/examples/Reactor/WFMO_Reactor/Handle_Close.cpp b/ACE/examples/Reactor/WFMO_Reactor/Handle_Close.cpp new file mode 100644 index 00000000000..9eb6d7c727a --- /dev/null +++ b/ACE/examples/Reactor/WFMO_Reactor/Handle_Close.cpp @@ -0,0 +1,333 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// Handle_Close.cpp +// +// = DESCRIPTION +// +// This application tests whether handle_close gets called and if +// the correct masks are passed along. The handler should get +// handle_close called for all three masks (READ, WRITE, and +// EXCEPT). +// +// = AUTHOR +// Irfan Pyarali +// +// ============================================================================ + +#include "ace/Get_Opt.h" +#include "ace/Reactor.h" +#include "ace/WFMO_Reactor.h" +#include "ace/Select_Reactor.h" +#include "ace/Auto_Ptr.h" +#include "ace/Pipe.h" +#include "ace/OS_main.h" + +ACE_RCSID(WFMO_Reactor, Handle_Close, "$Id: ") + +// Use the WFMO_Reactor +static int opt_wfmo_reactor = 0; + +// Use the Select_Reactor +static int opt_select_reactor = 0; + +// Make pipe readable in main() +static int write_to_pipe_in_main = 0; + +// Cancel reads +static int cancel_reads = 0; + +// Write some data to the pipe. This will cause handle_input to get +// called. +void +write_to_pipe (ACE_Pipe &pipe) +{ + char *data = "hello"; + size_t len = ACE_OS::strlen (data); + + ssize_t result = ACE::send (pipe.write_handle (), + data, + len); + ACE_ASSERT ((size_t)result == len); + ACE_UNUSED_ARG (result); +} + +// Simple handler class +class Handler : public ACE_Event_Handler +{ +public: + Handler (ACE_Pipe &pipe) + : pipe_ (pipe) + { + } + + ~Handler (void) + { + this->reactor (0); + } + + ACE_HANDLE get_handle (void) const + { + return this->pipe_.read_handle (); + } + + int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask) + { + ACE_UNUSED_ARG (handle); + ACE_DEBUG ((LM_DEBUG, + "Handler::handle_close called with mask = %d\n", + close_mask)); + return 0; + } + + int handle_input (ACE_HANDLE handle) + { + ACE_UNUSED_ARG (handle); + ACE_DEBUG ((LM_DEBUG, "Handler::handle_input\n")); + + // Remove for reading + return -1; + } + + int handle_output (ACE_HANDLE handle) + { + ACE_UNUSED_ARG (handle); + ACE_DEBUG ((LM_DEBUG, "Handler::handle_output\n")); + + // Optionally cancel reads + if (cancel_reads) + { + int result = this->reactor ()->cancel_wakeup (this, + ACE_Event_Handler::READ_MASK); + ACE_ASSERT (result != -1); + ACE_UNUSED_ARG (result); + } + + // Write to the pipe; this causes handle_input to get called. + if (!write_to_pipe_in_main) + write_to_pipe (this->pipe_); + + // Remove for writing + return -1; + } + +protected: + ACE_Pipe &pipe_; +}; + +class Different_Handler : public ACE_Event_Handler +{ +public: + + Different_Handler (ACE_Pipe &pipe) + : pipe_ (pipe) + { + } + + ~Different_Handler (void) + { + this->reactor (0); + } + + ACE_HANDLE get_handle (void) const + { + return this->pipe_.read_handle (); + } + + int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask) + { + ACE_UNUSED_ARG (handle); + ACE_DEBUG ((LM_DEBUG, + "Different_Handler::handle_close called with mask = %d\n", + close_mask)); + return 0; + } + + int handle_input (ACE_HANDLE handle) + { + ACE_UNUSED_ARG (handle); + ACE_DEBUG ((LM_DEBUG, "Different_Handler::handle_input\n")); + + // Remove for reading + int result = this->reactor ()->remove_handler (this, + ACE_Event_Handler::READ_MASK); + ACE_ASSERT (result == 0); + ACE_UNUSED_ARG (result); + + return 0; + } + + int handle_output (ACE_HANDLE handle) + { + ACE_UNUSED_ARG (handle); + ACE_DEBUG ((LM_DEBUG, "Different_Handler::handle_output\n")); + + // Add for reading + int result = this->reactor ()->mask_ops (this, + ACE_Event_Handler::READ_MASK, + ACE_Reactor::ADD_MASK); + ACE_ASSERT (result != -1); + + ACE_Reactor_Mask old_masks = + ACE_Event_Handler::WRITE_MASK | + ACE_Event_Handler::EXCEPT_MASK; + + ACE_ASSERT (old_masks == + static_cast<ACE_Reactor_Mask> (result)); + ACE_UNUSED_ARG (old_masks); + + // Get new masks + result = this->reactor ()->mask_ops (this, + ACE_Event_Handler::NULL_MASK, + ACE_Reactor::GET_MASK); + ACE_ASSERT (result != -1); + + ACE_Reactor_Mask current_masks = + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::WRITE_MASK | + ACE_Event_Handler::EXCEPT_MASK; + + ACE_ASSERT (current_masks == + static_cast<ACE_Reactor_Mask> (result)); + ACE_UNUSED_ARG (current_masks); + + // Remove for writing + ACE_Reactor_Mask mask = ACE_Event_Handler::WRITE_MASK | ACE_Event_Handler::DONT_CALL; + result = this->reactor ()->remove_handler (this, + mask); + ACE_ASSERT (result == 0); + + // Write to the pipe; this causes handle_input to get called. + if (!write_to_pipe_in_main) + write_to_pipe (this->pipe_); + + return 0; + } + +protected: + ACE_Pipe &pipe_; +}; + + +// +// Selection of which reactor should get created +// +ACE_Reactor * +create_reactor (void) +{ + ACE_Reactor_Impl *impl = 0; + + if (opt_wfmo_reactor) + { +#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) + ACE_NEW_RETURN (impl, + ACE_WFMO_Reactor, + 0); +#endif /* ACE_WIN32 */ + } + else if (opt_select_reactor) + { + ACE_NEW_RETURN (impl, + ACE_Select_Reactor, + 0); + } + else + { + ACE_Reactor *singleton_reactor = + ACE_Reactor::instance (); + ACE_Reactor::instance (0); + return singleton_reactor; + } + + ACE_Reactor *reactor = 0; + ACE_NEW_RETURN (reactor, + ACE_Reactor (impl, + 1), + 0); + + return reactor; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + int result = 0; + + // Parse args + ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("swmc"), 1); + for (int c; (c = getopt ()) != -1; ) + switch (c) + { + case 's': + opt_select_reactor = 1; + break; + case 'w': + opt_wfmo_reactor = 1; + break; + case 'm': + write_to_pipe_in_main = 1; + break; + case 'c': + cancel_reads = 1; + break; + } + + // Create pipes + ACE_Pipe pipe1, pipe2; + + result = pipe1.open (); + ACE_ASSERT (result == 0); + + result = pipe2.open (); + ACE_ASSERT (result == 0); + + // Create handlers + Handler handler (pipe1); + Different_Handler different_handler (pipe2); + + // Manage memory automagically. + auto_ptr<ACE_Reactor> reactor (create_reactor ()); + + // Register handlers + ACE_Reactor_Mask handler_mask = + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::WRITE_MASK | + ACE_Event_Handler::EXCEPT_MASK; + + ACE_Reactor_Mask different_handler_mask = + ACE_Event_Handler::WRITE_MASK | + ACE_Event_Handler::EXCEPT_MASK; + + result = reactor->register_handler (&handler, + handler_mask); + ACE_ASSERT (result == 0); + + result = reactor->register_handler (&different_handler, + different_handler_mask); + ACE_ASSERT (result == 0); + + // Write to the pipe; this causes handle_input to get called. + if (write_to_pipe_in_main) + { + write_to_pipe (pipe1); + write_to_pipe (pipe2); + } + + // Note that handle_output will get called automatically since the + // pipe is writable! + + // Run for three seconds + ACE_Time_Value time (3); + reactor->run_reactor_event_loop (time); + + ACE_DEBUG ((LM_DEBUG, "\nClosing down the application\n\n")); + + return 0; +} |