summaryrefslogtreecommitdiff
path: root/ACE/examples/Reactor/Proactor/test_multiple_loops.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/Reactor/Proactor/test_multiple_loops.cpp')
-rw-r--r--ACE/examples/Reactor/Proactor/test_multiple_loops.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/ACE/examples/Reactor/Proactor/test_multiple_loops.cpp b/ACE/examples/Reactor/Proactor/test_multiple_loops.cpp
new file mode 100644
index 00000000000..ac4228ab641
--- /dev/null
+++ b/ACE/examples/Reactor/Proactor/test_multiple_loops.cpp
@@ -0,0 +1,140 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// examples
+//
+// = FILENAME
+// test_multiple_loops.cpp
+//
+// = DESCRIPTION
+//
+// This example application shows how to write programs that
+// combine the Proactor and Reactor event loops. This is possible
+// only on WIN32 platform.
+//
+// = AUTHOR
+// Irfan Pyarali
+//
+// ============================================================================
+
+#include "ace/Task.h"
+#include "ace/Proactor.h"
+#include "ace/WIN32_Proactor.h"
+#include "ace/Atomic_Op.h"
+#include "ace/OS_NS_unistd.h"
+
+ACE_RCSID(Proactor, test_multiple_loops, "$Id$")
+
+#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
+
+class Timeout_Handler : public ACE_Handler, public ACE_Event_Handler
+{
+ // = TITLE
+ // Generic timeout handler.
+
+public:
+ Timeout_Handler (void)
+ {
+ }
+
+ // This is called by the Proactor. This is declared in ACE_Handler.
+ virtual void handle_time_out (const ACE_Time_Value &tv,
+ const void *arg)
+ {
+ // Print out when timeouts occur.
+ ACE_DEBUG ((LM_DEBUG, "(%t) %d timeout occurred for %s @ %d.\n",
+ ++count_,
+ (char *) arg,
+ tv.sec ()));
+
+ // Since there is only one thread that can do the timeouts in
+ // Reactor, lets keep the handle_timeout short for that
+ // thread.
+ if (ACE_OS::strcmp ((char *) arg, "Proactor") == 0)
+ // Sleep for a while
+ ACE_OS::sleep (1);
+ }
+
+ // This method is declared in ACE_Event_Handler.
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+ {
+ this->handle_time_out (tv, arg);
+ return 0;
+ }
+
+private:
+ ACE_Atomic_Op <ACE_Thread_Mutex, int> count_;
+};
+
+class Worker : public ACE_Task <ACE_NULL_SYNCH>
+{
+public:
+
+ // Thread fuction.
+ int svc (void)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%t) Worker started\n"));
+
+ // Handle events for 13 seconds.
+ ACE_Time_Value run_time (13);
+
+ // Try to become the owner
+ ACE_Reactor::instance ()->owner (ACE_Thread::self ());
+
+ if (ACE_Reactor::run_event_loop (run_time) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "Worker::svc"), -1);
+ else
+ ACE_DEBUG ((LM_DEBUG, "(%t) work complete\n"));
+
+ return 0;
+ }
+};
+
+int
+ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ Timeout_Handler handler;
+ ACE_WIN32_Proactor win32_proactor (0, 1);
+ ACE_Proactor proactor (&win32_proactor, 0, 0);
+
+ ACE_Reactor::instance ()->register_handler (proactor.implementation ());
+
+ // Register a 2 second timer.
+ ACE_Time_Value foo_tv (2);
+ if (proactor.schedule_timer (handler,
+ (void *) "Proactor",
+ ACE_Time_Value::zero,
+ foo_tv) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "schedule_timer"), -1);
+
+ // Register a 3 second timer.
+ ACE_Time_Value bar_tv (3);
+ if (ACE_Reactor::instance ()->schedule_timer (&handler,
+ (void *) "Reactor",
+ ACE_Time_Value::zero,
+ bar_tv) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "schedule_timer"), -1);
+
+ Worker worker;
+
+ if (worker.activate (THR_NEW_LWP, 10) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "main"), -1);
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ // Remove from reactor
+ ACE_Reactor::instance ()->remove_handler (&proactor,
+ ACE_Event_Handler::DONT_CALL);
+
+ return 0;
+}
+#else
+int
+main (int, char *[])
+{
+ return 0;
+}
+#endif /* ACE_WIN32 && !ACE_HAS_WINCE */