summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1996-11-17 19:55:21 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1996-11-17 19:55:21 +0000
commit8a0c00861bffa7450a5f0e85c0610c3278f66945 (patch)
treef06de49d2d57a8cea0bb20129c6079f8ce1eb7a5 /examples
parentcdaa50473d4305fca20da3227099dcb1de31c1b8 (diff)
downloadATCD-8a0c00861bffa7450a5f0e85c0610c3278f66945.tar.gz
Jammer!
Diffstat (limited to 'examples')
-rw-r--r--examples/Threads/Makefile3
-rw-r--r--examples/Threads/test_tss1.cpp155
-rw-r--r--examples/Threads/test_tss2.cpp253
3 files changed, 410 insertions, 1 deletions
diff --git a/examples/Threads/Makefile b/examples/Threads/Makefile
index f1c4c630a27..8f5f808ccaa 100644
--- a/examples/Threads/Makefile
+++ b/examples/Threads/Makefile
@@ -25,7 +25,8 @@ BIN = test_auto_event \
test_thread_manager \
test_thread_pool \
test_thread_specific \
- test_tss \
+ test_tss1 \
+ test_tss2 \
test_token
LSRC = $(addsuffix .cpp,$(BIN))
diff --git a/examples/Threads/test_tss1.cpp b/examples/Threads/test_tss1.cpp
new file mode 100644
index 00000000000..8f1d7c81528
--- /dev/null
+++ b/examples/Threads/test_tss1.cpp
@@ -0,0 +1,155 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// TSS_Test.cpp
+//
+// = DESCRIPTION
+// This program tests thread specific storage of data. The ACE_TSS
+// wrapper transparently ensures that the objects of this class
+// will be placed in thread-specific storage. All calls on
+// ACE_TSS::operator->() are delegated to the appropriate method
+// in the Errno class.
+//
+// = AUTHOR
+// Detlef Becker
+//
+// ============================================================================
+
+#include "ace/Service_Config.h"
+#include "ace/Synch.h"
+#include "ace/Log_Msg.h"
+#include "ace/Task.h"
+#include "test_config.h"
+
+static int iterations = 100;
+
+class Errno
+{
+public:
+ int error (void) { return this->errno_; }
+ void error (int i) { this->errno_ = i; }
+
+ int line (void) { return this->lineno_; }
+ void line (int l) { this->lineno_ = l; }
+
+ // Errno::flags_ is a static variable, so we've got to protect it
+ // with a mutex since it isn't kept in thread-specific storage.
+ int flags (void) {
+ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_Mon, Errno::lock_, -1));
+
+ return Errno::flags_;
+ }
+ int flags (int f)
+ {
+ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Errno::lock_, -1));
+
+ Errno::flags_ = f;
+ return 0;
+ }
+
+private:
+ // = errno_ and lineno_ will be thread-specific data so they don't
+ // need a lock.
+ int errno_;
+ int lineno_;
+
+ static int flags_;
+#if defined (ACE_HAS_THREADS)
+ // flags_ needs a lock.
+ static ACE_Thread_Mutex lock_;
+#endif /* ACE_HAS_THREADS */
+};
+
+// Static variables.
+ACE_MT (ACE_Thread_Mutex Errno::lock_);
+int Errno::flags_;
+
+// This is our thread-specific error handler...
+static ACE_TSS<Errno> TSS_Error;
+
+#if defined (ACE_HAS_THREADS)
+// Serializes output via cout.
+static ACE_Thread_Mutex lock;
+
+typedef ACE_TSS_Guard<ACE_Thread_Mutex> GUARD;
+#else
+// Serializes output via cout.
+static ACE_Null_Mutex lock;
+
+typedef ACE_Guard<ACE_Null_Mutex> GUARD;
+#endif /* ACE_HAS_THREADS */
+
+// Keeps track of whether Tester::close () has started.
+static int close_started = 0;
+
+template <ACE_SYNCH_1>
+class Tester: public ACE_Task<ACE_SYNCH_2>
+{
+public:
+ Tester (void) {}
+ ~Tester (void) {}
+
+ virtual int open (void *theArgs = 0);
+ virtual int close (u_long theArg = 0);
+ virtual int put (ACE_Message_Block *theMsgBlock,
+ ACE_Time_Value *theTimeVal = 0);
+ virtual int svc (void);
+};
+
+template <ACE_SYNCH_1>
+int Tester<ACE_SYNCH_2>::open (void *)
+{
+ this->activate ();
+ return 0;
+}
+
+template <ACE_SYNCH_1>
+int Tester<ACE_SYNCH_2>::close (u_long)
+{
+ ACE_DEBUG ((LM_DEBUG, close running\n!));
+ close_started = 1;
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "close: trying to log error code 7!"\n));
+ TSS_Error->error (7);
+ ACE_DEBUG ((LM_DEBUG, "close: logging succeeded!"\n));
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+Tester<ACE_SYNCH_2>::put (ACE_Message_Block *, ACE_Time_Value *)
+{
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+Tester<ACE_SYNCH_2>::svc (void)
+{
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ Tester<ACE_MT_SYNCH> tester;
+
+ tester.open ();
+
+ while (!close_started)
+ continue;
+
+ ACE_DEBUG ((LM_DEBUG, "main: trying to log error code 7!"\n));
+
+ TSS_Error->error (3);
+
+ ACE_DEBUG ((LM_DEBUG, "main: logging succeeded!"\n));
+ return 0;
+}
+
+#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION)
+template class ACE_TSS<Errno>;
+#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */
diff --git a/examples/Threads/test_tss2.cpp b/examples/Threads/test_tss2.cpp
new file mode 100644
index 00000000000..0cdbc7fe029
--- /dev/null
+++ b/examples/Threads/test_tss2.cpp
@@ -0,0 +1,253 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// TSS_Test.cpp
+//
+// = DESCRIPTION
+// This program tests thread specific storage of data. The ACE_TSS
+// wrapper transparently ensures that the objects of this class
+// will be placed in thread-specific storage. All calls on
+// ACE_TSS::operator->() are delegated to the appropriate method
+// in the Errno class.
+//
+// = AUTHOR
+// Prashant Jain and Doug Schmidt
+//
+// ============================================================================
+
+#include "ace/Task.h"
+#include "ace/Token.h"
+
+#if defined (ACE_HAS_THREADS)
+
+class TSS_Obj
+{
+public:
+
+ TSS_Obj (void);
+ ~TSS_Obj (void);
+
+private:
+ static int count_;
+ static ACE_Thread_Mutex lock_;
+};
+
+int TSS_Obj::count_ = 0;
+ACE_Thread_Mutex TSS_Obj::lock_;
+
+TSS_Obj::TSS_Obj (void)
+{
+ ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_);
+
+ count_++;
+ cout << "TO+ : " << count_ << endl;
+}
+
+TSS_Obj::~TSS_Obj (void)
+{
+ ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_);
+
+ count_--;
+ cout << "TO- : " << count_ << endl;
+}
+
+class Test_Task
+{
+public:
+
+ Test_Task (void);
+ ~Test_Task (void);
+
+ int open (void *arg);
+
+ static void* svc (void *arg);
+
+ static int wait_count_;
+ static int max_count_;
+
+private:
+ static int count_;
+};
+
+int Test_Task::count_ = 0;
+int Test_Task::wait_count_ = 0;
+int Test_Task::max_count_ = 0;
+int num_threads_ = 0;
+
+ACE_Token token;
+
+Test_Task::Test_Task (void)
+{
+ ACE_GUARD (ACE_Token, ace_mon, token);
+
+ count_++;
+ cout << "Test_Task+ : "
+ << count_ << " ("
+ << ACE_OS::thr_self ()
+ << ")" << endl;
+}
+
+Test_Task::~Test_Task (void)
+{
+ ACE_GUARD (ACE_Token, ace_mon, token);
+
+ count_--;
+ cout << "Test_Task- : "
+ << count_ << " ("
+ << ACE_OS::thr_self ()
+ << ")" << endl;
+
+ wait_count_--;
+}
+
+int Test_Task::open (void *arg)
+{
+
+ ACE_Thread::spawn (Test_Task::svc, arg);
+
+ return 0;
+}
+
+
+void *
+Test_Task::svc (void *arg)
+{
+ ACE_TSS<TSS_Obj> tss (new TSS_Obj);
+
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, 0);
+
+ wait_count_++;
+ max_count_++;
+ cout << "svc: waiting (" << ACE_OS::thr_self () << ")" << endl;
+ }
+
+ while (1)
+ {
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, 0);
+
+ if (max_count_ >= num_threads_)
+ break;
+ else
+ {
+ ace_mon.release ();
+ ACE_Thread::yield ();
+ ace_mon.acquire ();
+ }
+ }
+
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, 0);
+
+ cout << "svc: waiting (" << ACE_OS::thr_self () << ") finished" << endl;
+ }
+ }
+
+ delete (Test_Task *) arg;
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc != 2)
+ {
+ cout << "Missing parameters!" << endl;
+ return 1;
+ }
+
+ int num_Tasks = atoi (argv[1]);
+
+ num_threads_ = num_Tasks;
+
+ Test_Task **task_arr = (Test_Task**) new char[sizeof (Test_Task*) * num_Tasks];
+
+ while (1)
+ {
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1);
+
+ cout << "ReseTest_Tasking Test_Task::max_count_ from: "
+ << Test_Task::max_count_ << endl;
+
+ Test_Task::max_count_ = 0;
+ }
+
+ for (int i = 0; i < num_Tasks; i++)
+ {
+ task_arr[i] = new Test_Task;
+ task_arr[i]->open (task_arr[i]);
+ }
+
+ cout << "Waiting for first thread started..." << endl;
+
+ for (;;)
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1);
+
+ if (Test_Task::max_count_ != 0 )
+ {
+ ace_mon.release ();
+ ACE_Thread::yield ();
+ ace_mon.acquire ();
+ break;
+ }
+ ace_mon.release ();
+ ACE_Thread::yield ();
+ ace_mon.acquire ();
+ }
+
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1);
+
+ cout << "First thread started!" << endl
+ << "Waiting for all threads finished..." << endl;
+ }
+
+ for (;;)
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1);
+
+ if (!(Test_Task::max_count_ == num_threads_
+ && Test_Task::wait_count_ == 0))
+ {
+ ace_mon.release ();
+ ACE_Thread::yield ();
+ ace_mon.acquire ();
+ continue;
+ }
+
+ cout << "Test_Task::max_count_ = "
+ << Test_Task::max_count_
+ << " Test_Task::wait_count_ = "
+ << Test_Task::wait_count_
+ << endl;
+ break;
+ }
+
+ {
+ ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1);
+ cout << "All threads finished..." << endl;
+ }
+
+ ACE_OS::sleep (2);
+ }
+
+ return 0;
+}
+
+#else
+int
+main (int, char *[])
+{
+ ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n"));
+ return 0;
+}
+#endif /* ACE_HAS_THREADS */