diff options
author | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-03-23 06:06:12 +0000 |
---|---|---|
committer | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-03-23 06:06:12 +0000 |
commit | 796e49174648b87a7eacd944003cbbaabb0d8379 (patch) | |
tree | 5e3b38d15580ce70f37435ff8c70249cef46ff23 | |
parent | 1df6e981cd9c404ba690a648493c3eefcb1a2fc8 (diff) | |
download | ATCD-796e49174648b87a7eacd944003cbbaabb0d8379.tar.gz |
*** empty log message ***
-rw-r--r-- | ChangeLog-98a | 31 | ||||
-rw-r--r-- | ace/Reactor.cpp | 51 | ||||
-rw-r--r-- | ace/Reactor.h | 10 | ||||
-rw-r--r-- | ace/WFMO_Reactor.cpp | 59 | ||||
-rw-r--r-- | examples/Reactor/ReactorEx/APC.DSP | 57 | ||||
-rw-r--r-- | examples/Reactor/ReactorEx/Abondoned.dsp | 57 | ||||
-rw-r--r-- | examples/Reactor/ReactorEx/reactorex.dsw | 24 | ||||
-rw-r--r-- | examples/Reactor/ReactorEx/test_abandoned.cpp | 121 | ||||
-rw-r--r-- | examples/Reactor/ReactorEx/test_apc.cpp | 100 | ||||
-rw-r--r-- | examples/Reactor/WFMO_Reactor/APC.DSP | 57 | ||||
-rw-r--r-- | examples/Reactor/WFMO_Reactor/Abondoned.dsp | 57 | ||||
-rw-r--r-- | examples/Reactor/WFMO_Reactor/reactorex.dsw | 24 | ||||
-rw-r--r-- | examples/Reactor/WFMO_Reactor/test_abandoned.cpp | 121 | ||||
-rw-r--r-- | examples/Reactor/WFMO_Reactor/test_apc.cpp | 100 |
14 files changed, 849 insertions, 20 deletions
diff --git a/ChangeLog-98a b/ChangeLog-98a index 961b2a5030d..1771a3aca5e 100644 --- a/ChangeLog-98a +++ b/ChangeLog-98a @@ -1,3 +1,34 @@ +Mon Mar 23 00:03:37 1998 Irfan Pyarali <irfan@cs.wustl.edu> + + * examples/Reactor/ReactorEx/test_abandoned.cpp: Tests the + WFMO_Reactor's ability to handle abandoned mutexes. + + * examples/Reactor/ReactorEx/test_apc.cpp: Tests the + WFMO_Reactor's ability to handle regular APC notifications. + +Sun Mar 22 23:47:00 1998 Irfan Pyarali <irfan@cs.wustl.edu> + + * ace/WFMO_Reactor.cpp: Added code to the Reactor to make it more + resilient when the wait() function returns WAIT_IO_COMPLETION + and WAIT_ABANDONED. + + ok_to_wait: Keep waiting if wait() returns WAIT_IO_COMPLETION. + + dispatch: Return <handlers_dispatched> if wait() returns + WAIT_IO_COMPLETION. + + dispatch_handles: Added code to correctly handle WAIT_ABANDONED + and to correctly figure out the index of the handler to be + dispatched. + + Thanks to Beskrovny Evgeny (evgeny_beskrovny@icomverse.com) of + Comverse Network Systems for pointing out the problem with + WAIT_IO_COMPLETION. + + * ace/Reactor.cpp (run_alertable_event_loop): Added new function + that runs the Reactor using alertable_handle_events() instead of + handle_events(). + Sat Mar 21 19:58:42 1998 Nanbor Wang <nanbor@cs.wustl.edu> * ace/OS.i (flock_destroy): lock->lockname_ should be cast to diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp index 624884bdebe..78f8940ae23 100644 --- a/ace/Reactor.cpp +++ b/ace/Reactor.cpp @@ -158,6 +158,57 @@ ACE_Reactor::run_event_loop (ACE_Time_Value &tv) return 0; } +// Run the event loop until the <ACE_Reactor::alertable_handle_events> method +// returns -1 or the <end_event_loop> method is invoked. + +int +ACE_Reactor::run_alertable_event_loop (void) +{ + ACE_TRACE ("ACE_Reactor::run_event_loop"); + + while (ACE_Reactor::end_event_loop_ == 0) + { + int result = ACE_Reactor::instance ()->alertable_handle_events (); + +#if !defined (ACE_HAS_WINCE) + if (ACE_Service_Config::reconfig_occurred ()) + ACE_Service_Config::reconfigure (); + else +#endif /* !ACE_HAS_WINCE */ + + if (result == -1) + return -1; + } + /* NOTREACHED */ + return 0; +} + +// Run the event loop until the <ACE_Reactor::alertable_handle_events> +// method returns -1, the <end_event_loop> method +// is invoked, or the <ACE_Time_Value> expires. + +int +ACE_Reactor::run_alertable_event_loop (ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Reactor::run_event_loop"); + + while (ACE_Reactor::end_event_loop_ == 0) + { + int result = ACE_Reactor::instance ()->alertable_handle_events (tv); + +#if !defined (ACE_HAS_WINCE) + if (ACE_Service_Config::reconfig_occurred ()) + ACE_Service_Config::reconfigure (); + else +#endif /* !ACE_HAS_WINCE */ + if (result <= 0) + return result; + } + + /* NOTREACHED */ + return 0; +} + void ACE_Reactor::reset_event_loop (void) { diff --git a/ace/Reactor.h b/ace/Reactor.h index 4bc581fd35b..527f52a2e46 100644 --- a/ace/Reactor.h +++ b/ace/Reactor.h @@ -67,11 +67,15 @@ public: // = Reactor event loop management methods. static int run_event_loop (void); - // Run the event loop until the <ACE_Reactor::handle_events> method - // returns -1 or the <end_event_loop> method is invoked. + static int run_alertable_event_loop (void); + // Run the event loop until the + // <ACE_Reactor::handle_events/ACE_Reactor::alertable_handle_events> + // method returns -1 or the <end_event_loop> method is invoked. static int run_event_loop (ACE_Time_Value &tv); - // Run the event loop until the <ACE_Reactor::handle_events> method + static int run_alertable_event_loop (ACE_Time_Value &tv); + // Run the event loop until the + // <ACE_Reactor::handle_events/ACE_Reactor::alertable_handle_events> // returns -1, the <end_event_loop> method is invoked, or the // <ACE_Time_Value> expires. diff --git a/ace/WFMO_Reactor.cpp b/ace/WFMO_Reactor.cpp index 0ede7bfae7a..49dd2562504 100644 --- a/ace/WFMO_Reactor.cpp +++ b/ace/WFMO_Reactor.cpp @@ -1205,11 +1205,17 @@ ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, int timeout = max_wait_time == 0 ? INFINITE : max_wait_time->msec (); // Atomically wait for both the <lock_> and <ok_to_wait_> event - int result = ::WaitForMultipleObjectsEx (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), + int result = 0; + while (1) + { + result = ::WaitForMultipleObjectsEx (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), this->atomic_wait_array_, TRUE, timeout, alertable); + if (result != WAIT_IO_COMPLETION) + break; + } switch (result) { @@ -1293,13 +1299,17 @@ ACE_WFMO_Reactor::dispatch (int wait_status) case WAIT_FAILED: // Failure. errno = ::GetLastError (); return -1; + case WAIT_TIMEOUT: // Timeout. errno = ETIME; return handlers_dispatched; - case WAIT_ABANDONED_0: - // We'll let dispatch worry about abandoned mutes. + + case WAIT_IO_COMPLETION: // APC. + return handlers_dispatched; + default: // Dispatch. - handlers_dispatched += this->dispatch_handles (wait_status - WAIT_OBJECT_0); + // We'll let dispatch worry about abandoned mutes. + handlers_dispatched += this->dispatch_handles (wait_status); return handlers_dispatched; } } @@ -1308,23 +1318,46 @@ ACE_WFMO_Reactor::dispatch (int wait_status) // <handles_[max_handlep1_]>, polling through our handle set looking // for active handles. int -ACE_WFMO_Reactor::dispatch_handles (size_t index) +ACE_WFMO_Reactor::dispatch_handles (size_t wait_status) { + // dispatch_index is the absolute index. Only += is used to + // increment it. + int dispatch_index = 0; + + // Cache this value, this is the absolute value. + size_t max_handlep1 = this->handler_rep_.max_handlep1 (); + + // nCount starts off at <max_handlep1>, this is a transient count of + // handles last waited on. + size_t nCount = max_handlep1; + for (int number_of_handlers_dispatched = 1; ; number_of_handlers_dispatched++) { - size_t max_handlep1 = this->handler_rep_.max_handlep1 (); + if (wait_status >= WAIT_OBJECT_0 && + wait_status <= (WAIT_OBJECT_0 + nCount)) + dispatch_index += wait_status - WAIT_OBJECT_0; + else + // Otherwise, a handle was abandoned. + dispatch_index += wait_status - WAIT_ABANDONED_0; - if (this->dispatch_handler (index++, max_handlep1) == -1) + // Dispatch handler + if (this->dispatch_handler (dispatch_index, max_handlep1) == -1) return -1; + + // Increment index + dispatch_index++; // We're done. - if (index >= max_handlep1) + if (dispatch_index >= max_handlep1) return number_of_handlers_dispatched; + // Readjust nCount + nCount -= dispatch_index; + // Check the remaining handles - DWORD wait_status = this->poll_remaining_handles (index); + wait_status = this->poll_remaining_handles (dispatch_index); switch (wait_status) { case WAIT_FAILED: // Failure. @@ -1333,14 +1366,6 @@ ACE_WFMO_Reactor::dispatch_handles (size_t index) case WAIT_TIMEOUT: // There are no more handles ready, we can return. return number_of_handlers_dispatched; - default: // Dispatch. - // Check if a handle successfully became signaled. - if (wait_status >= WAIT_OBJECT_0 && - wait_status <= (WAIT_OBJECT_0 + max_handlep1 - index)) - index += wait_status - WAIT_OBJECT_0; - else - // Otherwise, a handle was abandoned. - index += wait_status - WAIT_ABANDONED_0; } } } diff --git a/examples/Reactor/ReactorEx/APC.DSP b/examples/Reactor/ReactorEx/APC.DSP new file mode 100644 index 00000000000..8162d0eff95 --- /dev/null +++ b/examples/Reactor/ReactorEx/APC.DSP @@ -0,0 +1,57 @@ +# Microsoft Developer Studio Project File - Name="APC" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=APC - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "APC.MAK". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "APC.MAK" CFG="APC - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "APC - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "APC___Wi" +# PROP BASE Intermediate_Dir "APC___Wi" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Target + +# Name "APC - Win32 Debug" +# Begin Source File + +SOURCE=.\test_apc.cpp +# End Source File +# End Target +# End Project diff --git a/examples/Reactor/ReactorEx/Abondoned.dsp b/examples/Reactor/ReactorEx/Abondoned.dsp new file mode 100644 index 00000000000..15f006d0687 --- /dev/null +++ b/examples/Reactor/ReactorEx/Abondoned.dsp @@ -0,0 +1,57 @@ +# Microsoft Developer Studio Project File - Name="Abondoned" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Abondoned - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Abondoned.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Abondoned.mak" CFG="Abondoned - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Abondoned - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Abondone"
+# PROP BASE Intermediate_Dir "Abondone"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# Begin Target
+
+# Name "Abondoned - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\test_abandoned.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/examples/Reactor/ReactorEx/reactorex.dsw b/examples/Reactor/ReactorEx/reactorex.dsw index 9fe25164e69..84f1b28fe69 100644 --- a/examples/Reactor/ReactorEx/reactorex.dsw +++ b/examples/Reactor/ReactorEx/reactorex.dsw @@ -3,6 +3,30 @@ Microsoft Developer Studio Workspace File, Format Version 5.00 ###############################################################################
+Project: "APC"=.\APC.DSP - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "Abondoned"=.\Abondoned.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "Console_Input"=.\Console_Input.dsp - Package Owner=<4>
Package=<5>
diff --git a/examples/Reactor/ReactorEx/test_abandoned.cpp b/examples/Reactor/ReactorEx/test_abandoned.cpp new file mode 100644 index 00000000000..79eaef0377a --- /dev/null +++ b/examples/Reactor/ReactorEx/test_abandoned.cpp @@ -0,0 +1,121 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// test_abandoned.cpp +// +// = DESCRIPTION +// +// Tests the WFMO_Reactor's ability to handle abandoned mutexes. +// +// = AUTHOR +// +// Irfan Pyarali +// +// ============================================================================ + +#include "ace/Reactor.h" +#include "ace/Synch.h" +#include "ace/Thread_Manager.h" + +static int abandon = 1; + +void *worker (void *); + +class Event_Handler : public ACE_Event_Handler +{ +public: + int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + int handle_timeout (const ACE_Time_Value &tv, + const void *arg = 0); + + ACE_Auto_Event handle_; + ACE_Process_Mutex *mutex_; + int iterations_; +}; + +int +Event_Handler::handle_signal (int signum, siginfo_t *s, ucontext_t *) +{ + char *reason = 0; + + HANDLE handle = s->si_handle_; + if (handle == this->handle_.handle ()) + { + reason = "event"; + ACE_ASSERT (ACE_Reactor::instance ()->register_handler (this, + this->mutex_->lock ().proc_mutex_) == 0); + } + else + { + ACE_ASSERT (ACE_Reactor::instance ()->remove_handler (this->mutex_->lock ().proc_mutex_, + ACE_Event_Handler::DONT_CALL) == 0); + delete this->mutex_; + reason = "mutex"; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) handle_signal for %s\n", reason)); + + return 0; +} + +int +Event_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) timeout occured @ %T, iterations left %d\n", + --this->iterations_)); + + if (this->iterations_ == 0) + ACE_Reactor::end_event_loop (); + + else + { + this->mutex_ = new ACE_Process_Mutex; + ACE_ASSERT (ACE_Thread_Manager::instance ()->spawn (&worker, + this) != -1); + } + + return 0; +} + +Event_Handler event_handler; + +void * +worker (void *data) +{ + Event_Handler *handler = (Event_Handler *) data; + + handler->handle_.signal (); + handler->mutex_->acquire (); + + if (!abandon) + handler->mutex_->release (); + + return 0; +} + +int +main (void) +{ + event_handler.iterations_ = 5; + ACE_ASSERT (ACE_Reactor::instance ()->register_handler (&event_handler, + event_handler.handle_.handle ()) == 0); + + ACE_Time_Value timeout (2); + ACE_ASSERT (ACE_Reactor::instance ()->schedule_timer (&event_handler, + 0, + timeout, + timeout) != -1); + + ACE_Reactor::run_event_loop (); + + return 0; +} + diff --git a/examples/Reactor/ReactorEx/test_apc.cpp b/examples/Reactor/ReactorEx/test_apc.cpp new file mode 100644 index 00000000000..00a1f4a9b1c --- /dev/null +++ b/examples/Reactor/ReactorEx/test_apc.cpp @@ -0,0 +1,100 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// test_apc.cpp +// +// = DESCRIPTION +// +// Tests the WFMO_Reactor's ability to handle regular APC +// notifications. +// +// = AUTHOR +// +// Irfan Pyarali +// +// ============================================================================ + +#include "ace/Reactor.h" + +void queue_apc (void); + +class Event_Handler : public ACE_Event_Handler +{ +public: + int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + int handle_timeout (const ACE_Time_Value &tv, + const void *arg = 0); + + ACE_Auto_Event handle_; + int iterations_; +}; + +int +Event_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, + "handling signal: %d iterations left\n", + --this->iterations_)); + + if (this->iterations_ == 0) + ACE_Reactor::end_event_loop (); + + return 0; +} + +int +Event_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) timeout occured @ %T\n")); + + queue_apc (); + + return 0; +} + +Event_Handler event_handler; + +void WINAPI +apc_callback (DWORD) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) apc occured @ %T\n")); + + event_handler.handle_.signal (); +} + +void +queue_apc (void) +{ + DWORD result = ::QueueUserAPC (&apc_callback, // pointer to APC function + ::GetCurrentThread (), // handle to the thread + 0 // argument for the APC function + ); + if (result == FALSE) + ACE_OS::exit (-1); +} + +int +main (void) +{ + event_handler.iterations_ = 5; + ACE_ASSERT (ACE_Reactor::instance ()->register_handler (&event_handler, + event_handler.handle_.handle ()) == 0); + + ACE_Time_Value timeout (2); + ACE_ASSERT (ACE_Reactor::instance ()->schedule_timer (&event_handler, + 0, + timeout, + timeout) != -1); + + ACE_Reactor::run_alertable_event_loop (); + + return 0; +} + diff --git a/examples/Reactor/WFMO_Reactor/APC.DSP b/examples/Reactor/WFMO_Reactor/APC.DSP new file mode 100644 index 00000000000..8162d0eff95 --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/APC.DSP @@ -0,0 +1,57 @@ +# Microsoft Developer Studio Project File - Name="APC" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=APC - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "APC.MAK". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "APC.MAK" CFG="APC - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "APC - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "APC___Wi" +# PROP BASE Intermediate_Dir "APC___Wi" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Target + +# Name "APC - Win32 Debug" +# Begin Source File + +SOURCE=.\test_apc.cpp +# End Source File +# End Target +# End Project diff --git a/examples/Reactor/WFMO_Reactor/Abondoned.dsp b/examples/Reactor/WFMO_Reactor/Abondoned.dsp new file mode 100644 index 00000000000..15f006d0687 --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/Abondoned.dsp @@ -0,0 +1,57 @@ +# Microsoft Developer Studio Project File - Name="Abondoned" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Abondoned - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Abondoned.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Abondoned.mak" CFG="Abondoned - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Abondoned - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Abondone"
+# PROP BASE Intermediate_Dir "Abondone"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# Begin Target
+
+# Name "Abondoned - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\test_abandoned.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/examples/Reactor/WFMO_Reactor/reactorex.dsw b/examples/Reactor/WFMO_Reactor/reactorex.dsw index 9fe25164e69..84f1b28fe69 100644 --- a/examples/Reactor/WFMO_Reactor/reactorex.dsw +++ b/examples/Reactor/WFMO_Reactor/reactorex.dsw @@ -3,6 +3,30 @@ Microsoft Developer Studio Workspace File, Format Version 5.00 ###############################################################################
+Project: "APC"=.\APC.DSP - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "Abondoned"=.\Abondoned.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "Console_Input"=.\Console_Input.dsp - Package Owner=<4>
Package=<5>
diff --git a/examples/Reactor/WFMO_Reactor/test_abandoned.cpp b/examples/Reactor/WFMO_Reactor/test_abandoned.cpp new file mode 100644 index 00000000000..79eaef0377a --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/test_abandoned.cpp @@ -0,0 +1,121 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// test_abandoned.cpp +// +// = DESCRIPTION +// +// Tests the WFMO_Reactor's ability to handle abandoned mutexes. +// +// = AUTHOR +// +// Irfan Pyarali +// +// ============================================================================ + +#include "ace/Reactor.h" +#include "ace/Synch.h" +#include "ace/Thread_Manager.h" + +static int abandon = 1; + +void *worker (void *); + +class Event_Handler : public ACE_Event_Handler +{ +public: + int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + int handle_timeout (const ACE_Time_Value &tv, + const void *arg = 0); + + ACE_Auto_Event handle_; + ACE_Process_Mutex *mutex_; + int iterations_; +}; + +int +Event_Handler::handle_signal (int signum, siginfo_t *s, ucontext_t *) +{ + char *reason = 0; + + HANDLE handle = s->si_handle_; + if (handle == this->handle_.handle ()) + { + reason = "event"; + ACE_ASSERT (ACE_Reactor::instance ()->register_handler (this, + this->mutex_->lock ().proc_mutex_) == 0); + } + else + { + ACE_ASSERT (ACE_Reactor::instance ()->remove_handler (this->mutex_->lock ().proc_mutex_, + ACE_Event_Handler::DONT_CALL) == 0); + delete this->mutex_; + reason = "mutex"; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) handle_signal for %s\n", reason)); + + return 0; +} + +int +Event_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) timeout occured @ %T, iterations left %d\n", + --this->iterations_)); + + if (this->iterations_ == 0) + ACE_Reactor::end_event_loop (); + + else + { + this->mutex_ = new ACE_Process_Mutex; + ACE_ASSERT (ACE_Thread_Manager::instance ()->spawn (&worker, + this) != -1); + } + + return 0; +} + +Event_Handler event_handler; + +void * +worker (void *data) +{ + Event_Handler *handler = (Event_Handler *) data; + + handler->handle_.signal (); + handler->mutex_->acquire (); + + if (!abandon) + handler->mutex_->release (); + + return 0; +} + +int +main (void) +{ + event_handler.iterations_ = 5; + ACE_ASSERT (ACE_Reactor::instance ()->register_handler (&event_handler, + event_handler.handle_.handle ()) == 0); + + ACE_Time_Value timeout (2); + ACE_ASSERT (ACE_Reactor::instance ()->schedule_timer (&event_handler, + 0, + timeout, + timeout) != -1); + + ACE_Reactor::run_event_loop (); + + return 0; +} + diff --git a/examples/Reactor/WFMO_Reactor/test_apc.cpp b/examples/Reactor/WFMO_Reactor/test_apc.cpp new file mode 100644 index 00000000000..00a1f4a9b1c --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/test_apc.cpp @@ -0,0 +1,100 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// test_apc.cpp +// +// = DESCRIPTION +// +// Tests the WFMO_Reactor's ability to handle regular APC +// notifications. +// +// = AUTHOR +// +// Irfan Pyarali +// +// ============================================================================ + +#include "ace/Reactor.h" + +void queue_apc (void); + +class Event_Handler : public ACE_Event_Handler +{ +public: + int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + int handle_timeout (const ACE_Time_Value &tv, + const void *arg = 0); + + ACE_Auto_Event handle_; + int iterations_; +}; + +int +Event_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, + "handling signal: %d iterations left\n", + --this->iterations_)); + + if (this->iterations_ == 0) + ACE_Reactor::end_event_loop (); + + return 0; +} + +int +Event_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) timeout occured @ %T\n")); + + queue_apc (); + + return 0; +} + +Event_Handler event_handler; + +void WINAPI +apc_callback (DWORD) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) apc occured @ %T\n")); + + event_handler.handle_.signal (); +} + +void +queue_apc (void) +{ + DWORD result = ::QueueUserAPC (&apc_callback, // pointer to APC function + ::GetCurrentThread (), // handle to the thread + 0 // argument for the APC function + ); + if (result == FALSE) + ACE_OS::exit (-1); +} + +int +main (void) +{ + event_handler.iterations_ = 5; + ACE_ASSERT (ACE_Reactor::instance ()->register_handler (&event_handler, + event_handler.handle_.handle ()) == 0); + + ACE_Time_Value timeout (2); + ACE_ASSERT (ACE_Reactor::instance ()->schedule_timer (&event_handler, + 0, + timeout, + timeout) != -1); + + ACE_Reactor::run_alertable_event_loop (); + + return 0; +} + |