summaryrefslogtreecommitdiff
path: root/ACE/tests/Task_Test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/tests/Task_Test.cpp')
-rw-r--r--ACE/tests/Task_Test.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/ACE/tests/Task_Test.cpp b/ACE/tests/Task_Test.cpp
new file mode 100644
index 00000000000..24bb021e1bd
--- /dev/null
+++ b/ACE/tests/Task_Test.cpp
@@ -0,0 +1,159 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Task_Test.cpp
+//
+// = DESCRIPTION
+// This test program illustrates how the ACE barrier
+// synchronization mechanisms work in conjunction with the
+// <ACE_Task> and the <ACE_Thread_Manager>. This also illustrates
+// how the <ACE_Thread_Hook> mechanism works.
+//
+// = AUTHOR
+// Prashant Jain <pjain@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Task.h"
+#include "ace/Thread_Hook.h"
+
+ACE_RCSID(tests, Task_Test, "$Id$")
+
+#if defined (ACE_HAS_THREADS)
+#include "ace/Atomic_Op.h"
+#include "ace/Barrier.h"
+
+// Make sure that only one thread sees the "time to clean up" condition
+// in Barrier_Task::close()
+static ACE_Atomic_Op<ACE_Thread_Mutex, int> close_cleanups (0);
+
+class My_Thread_Hook : public ACE_Thread_Hook
+{
+public:
+ virtual ACE_THR_FUNC_RETURN start (ACE_THR_FUNC func,
+ void *arg);
+};
+
+class Barrier_Task : public ACE_Task<ACE_MT_SYNCH>
+{
+public:
+ Barrier_Task (ACE_Thread_Manager *thr_mgr,
+ int n_threads,
+ int n_iterations);
+
+ //FUZZ: disable check_for_lack_ACE_OS
+ virtual int close (u_long flags = 0);
+ //FUZZ: enable check_for_lack_ACE_OS
+
+ virtual int svc (void);
+ // Iterate <n_iterations> time printing off a message and "waiting"
+ // for all other threads to complete this iteration.
+
+private:
+ ACE_Barrier barrier_;
+ // Reference to the tester barrier. This controls each iteration of
+ // the tester function running in every thread.
+
+ int n_iterations_;
+ // Number of iterations to run.
+};
+
+ACE_THR_FUNC_RETURN
+My_Thread_Hook::start (ACE_THR_FUNC func,
+ void *arg)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%t) starting the thread!\n")));
+ return (func) (arg);
+}
+
+Barrier_Task::Barrier_Task (ACE_Thread_Manager *thr_mgr,
+ int n_threads,
+ int n_iterations)
+ : ACE_Task<ACE_MT_SYNCH> (thr_mgr),
+ barrier_ (n_threads),
+ n_iterations_ (n_iterations)
+{
+ // Create worker threads.
+ if (this->activate (THR_NEW_LWP, n_threads) == -1)
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("activate failed")));
+}
+
+// Check to see if it's time to clean up by examining last_thread().
+int
+Barrier_Task::close (u_long)
+{
+ if (ACE_OS::thr_equal (ACE_Thread::self (),
+ this->last_thread ()))
+ {
+ ++close_cleanups;
+ }
+ return 0;
+}
+
+// Iterate <n_iterations> time printing off a message and "waiting"
+// for all other threads to complete this iteration.
+int
+Barrier_Task::svc (void)
+{
+ for (int iterations = 1;
+ iterations <= this->n_iterations_;
+ iterations++)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%t) in iteration %d\n"),
+ iterations));
+
+ // Block until all other threads have waited, then continue.
+ this->barrier_.wait ();
+ }
+
+ // Note that the <ACE_Task::svc_run> method automatically removes us
+ // from the Thread_Manager when the thread exits.
+
+ return 0;
+}
+
+#endif /* ACE_HAS_THREADS */
+
+int
+run_main (int, ACE_TCHAR *[])
+{
+ ACE_START_TEST (ACE_TEXT ("Task_Test"));
+
+#if defined (ACE_HAS_THREADS)
+ // Set the thread hook!
+ ACE_Thread_Hook::thread_hook (new My_Thread_Hook);
+
+ int n_threads = ACE_MAX_THREADS;
+ int n_iterations = ACE_MAX_ITERATIONS;
+
+ Barrier_Task barrier_task (ACE_Thread_Manager::instance (),
+ n_threads,
+ n_iterations);
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ // Only one of the threads should see a cleanup...
+ if (close_cleanups != 1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%d threads saw cleanup indication; ")
+ ACE_TEXT ("should be 1\n"),
+ close_cleanups.value ()));
+
+ // Cleanup the thread hook so it doesn't leak.
+ delete ACE_Thread_Hook::thread_hook ();
+#else
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("threads not supported on this platform\n")));
+#endif /* ACE_HAS_THREADS */
+ ACE_END_TEST;
+ return 0;
+}