diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1996-11-17 19:55:21 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1996-11-17 19:55:21 +0000 |
commit | 8a0c00861bffa7450a5f0e85c0610c3278f66945 (patch) | |
tree | f06de49d2d57a8cea0bb20129c6079f8ce1eb7a5 /examples | |
parent | cdaa50473d4305fca20da3227099dcb1de31c1b8 (diff) | |
download | ATCD-8a0c00861bffa7450a5f0e85c0610c3278f66945.tar.gz |
Jammer!
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Threads/Makefile | 3 | ||||
-rw-r--r-- | examples/Threads/test_tss1.cpp | 155 | ||||
-rw-r--r-- | examples/Threads/test_tss2.cpp | 253 |
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 */ |