summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-23 06:06:12 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-23 06:06:12 +0000
commit796e49174648b87a7eacd944003cbbaabb0d8379 (patch)
tree5e3b38d15580ce70f37435ff8c70249cef46ff23
parent1df6e981cd9c404ba690a648493c3eefcb1a2fc8 (diff)
downloadATCD-796e49174648b87a7eacd944003cbbaabb0d8379.tar.gz
*** empty log message ***
-rw-r--r--ChangeLog-98a31
-rw-r--r--ace/Reactor.cpp51
-rw-r--r--ace/Reactor.h10
-rw-r--r--ace/WFMO_Reactor.cpp59
-rw-r--r--examples/Reactor/ReactorEx/APC.DSP57
-rw-r--r--examples/Reactor/ReactorEx/Abondoned.dsp57
-rw-r--r--examples/Reactor/ReactorEx/reactorex.dsw24
-rw-r--r--examples/Reactor/ReactorEx/test_abandoned.cpp121
-rw-r--r--examples/Reactor/ReactorEx/test_apc.cpp100
-rw-r--r--examples/Reactor/WFMO_Reactor/APC.DSP57
-rw-r--r--examples/Reactor/WFMO_Reactor/Abondoned.dsp57
-rw-r--r--examples/Reactor/WFMO_Reactor/reactorex.dsw24
-rw-r--r--examples/Reactor/WFMO_Reactor/test_abandoned.cpp121
-rw-r--r--examples/Reactor/WFMO_Reactor/test_apc.cpp100
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;
+}
+