Index: /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/Makefile
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/Makefile	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/Makefile	(revision 1017)
@@ -0,0 +1,44 @@
+#  Makefile for building JTC JThreads/C++ 
+#  Source code from Object Oriented Concepts  www.ooc.com
+#  R. Ansari      LAL-IN2P3/CNRS    
+
+CXX := g++
+ifdef EROSCXX
+  CXX := $(EROSCXX)
+endif
+
+SYSNOM = $(shell echo `uname`)
+SYSCOMPNOM = $(SYSNOM)-$(CXX)
+
+INC = $(JTCBASEREP)/Include
+LIB = $(JTCBASEREP)/$(SYSCOMPNOM)/Libs
+SLB = $(JTCBASEREP)/$(SYSCOMPNOM)/ShLibs
+
+SYSLIBS = -lpthread 
+ifeq ($(CXX),cxx)
+  CPPFLAGS   :=  -I$(INC) -pthread 
+endif
+
+all : hello clock diner conprod
+	echo 'hello clock diner conprod built'
+
+hello : hello.o
+	$(CXX) -o hello hello.o -L$(SLB) -lJTC $(SYSLIBS)
+hello.o : hello.cc
+	$(CXX) -I$(INC) -c -o hello.o hello.cc $(SYSLIBS) 
+
+diner : diner.o
+	$(CXX) -o diner diner.o -L$(SLB) -lJTC $(SYSLIBS) 
+diner.o : diner.cc
+	$(CXX) -I$(INC) -c -o diner.o diner.cc
+
+clock : clock.o
+	$(CXX) -o clock clock.o -L$(SLB) -lJTC $(SYSLIBS)
+clock.o : clock.cc
+	$(CXX) -I$(INC) -c -o clock.o clock.cc
+
+conprod : conprod.o
+	$(CXX) -o conprod conprod.o -L$(SLB) -lJTC $(SYSLIBS) 
+conprod.o : conprod.cc
+	$(CXX) -I$(INC) -c -o conprod.o conprod.cc
+
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/clock.cc
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/clock.cc	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/clock.cc	(revision 1017)
@@ -0,0 +1,152 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/JTC.h>
+
+#include <time.h>
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+//
+// This class will display the time every 100 milliseconds until
+// stopped.
+//
+class Clock : public JTCRunnable
+{
+    JTCThreadHandle timer_; // The thread that this class runs in.
+
+public:
+
+    //
+    // Constructor.
+    //
+    Clock()
+    {
+    }
+
+    //
+    // Display the current time.
+    //
+    void repaint()
+    {
+	time_t t = time(0);
+
+	//
+	// The more observant will note that ctime_r should be used
+	// under a multi-threaded environment (UNIX). However, for
+	// this test ctime can safely be used since it is known that
+	// only this thread will call the function.
+	//
+	cout << ctime(&t) << endl;
+    }
+
+    //
+    // Called when the thread is started.
+    //
+    void run()
+    {
+        //
+        // While the thread is non-zero continue.
+        //
+	while(timer_)
+	{
+            //
+            // Sleep for 100 milliseconds.
+            //
+            try
+            {
+                timer_ -> sleep(100);
+            }
+            catch(const JTCInterruptedException&)
+            {
+            }
+            //
+            // Repaint the time.
+            //
+	    repaint();
+	}
+    }
+
+    //
+    // Start the thread.
+    //
+    void start()
+    {
+	if(!timer_)
+	{
+            //
+            // Create a new thread with this as the Runnable
+            // argument.
+            //
+	    timer_ = new JTCThread(JTCRunnableHandle(this));
+            //
+            // Start the thread running.
+            //
+	    timer_ -> start();
+	}
+    }
+
+    //
+    // To stop the thread, mark the thread as invalid.
+    //
+    void stop()
+    {
+	timer_ = JTCThreadHandle();
+    }
+};
+
+#ifndef HAVE_NO_EXPLICIT_TEMPLATES
+template class JTCHandleT<Clock>;
+#else
+#  ifdef HAVE_PRAGMA_DEFINE
+#    pragma define(JTCHandleT<Clock>)
+#  endif
+#endif
+
+int
+main(int argc, char** argv)
+{
+    try
+    {
+        //
+        // A user of the JTC library must create an instance of this
+        // class to initialize the library.
+        //
+	JTCInitialize bootJTC(argc, argv);
+        //
+        // Create a new instance of the clock class.
+        //
+	JTCHandleT<Clock> c = new Clock();
+        //
+        // Start the clock thread running.
+        //
+	c -> start();
+        //
+        // Put the main thread to sleep for 5 seconds.
+        //
+	JTCThread::sleep(1000*5);
+        //
+        // Stop the clock thread.
+        //
+	c -> stop();
+        //
+        // The instance of the JTCInitialize class will ensure that
+        // this block is not exited until all threads terminate.
+        //
+    }
+    catch(const JTCException& e)
+    {
+	cerr << "JTCException: " << e.getMessage() << endl;
+    }
+
+    return 0;
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/conprod.cc
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/conprod.cc	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/conprod.cc	(revision 1017)
@@ -0,0 +1,262 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/JTC.h>
+
+#include <stdlib.h>
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+//
+// This example is a port of the CubbyHole example in the java tutorial.
+// See: http://java.sun.com/tutorial.
+//
+// This class acts as a cubby hole for producers and consumers.
+// A producer may not put another item in the cubby until a consumer
+// has retrieved the item.  A consumer may not retrieve an item
+// until a producer has placed a new item in the hole.
+//
+class CubbyHole
+{
+    bool available_; // Item available?
+    int value_; // If so, what is the value of the item?
+    int ref_; // Number of times the cubby hole is referenced.
+    JTCMonitor mon_; // Associated monitor.
+
+public:
+
+    //
+    // Constructor.
+    //
+    CubbyHole()
+	: available_(false), ref_(0)
+    {
+    }
+
+    //
+    // Increment reference count.
+    //
+    void reference()
+    {
+	++ref_;
+    }
+
+    //
+    // Decrement reference count.  Delete the cubby if the reference
+    // count drops to zero.
+    //
+    void dereference()
+    {
+	if(--ref_ == 0)
+	{
+	    delete this;
+	}
+    }
+
+    //
+    // Place a new item in the hole.  If the hole is currently
+    // occupied, then block until the hole is empty.
+    //
+    void put(int v, int client)
+    {
+	JTCSynchronized sync(mon_);
+
+        //
+        // Loop while the hole is filled.
+        //
+	while(available_)
+	{
+            //
+            // Wait to be notified.  The monitor is notified when
+            // the hole is filled, or emptied.
+            //
+	    try
+	    {
+		mon_.wait();
+	    }
+	    catch(const JTCInterruptedException&)
+	    {
+	    }
+	}
+        //
+        // The hole is now filled, with associated value.
+        // Wake any waiting consumers.
+        //
+	available_ = true;
+	value_ = v;
+	mon_.notifyAll();
+
+        //
+        // We put this display in here to avoid problems with
+        // corrupting the output stream.
+        //
+	cout << "Producer #" << client << " put: " << value_ << endl;
+    }
+
+    //
+    // Retrieve an element store in the cubby hole.  If no element
+    // is available for retrieval then wait.
+    //
+    int get(int client)
+    {
+	JTCSynchronized sync(mon_);
+        //
+        // While no element is available for retrieval wait.
+        //
+	while(!available_)
+	{
+	    try
+	    {
+		mon_.wait();
+	    }
+	    catch(const JTCInterruptedException&)
+	    {
+	    }
+	}
+        //
+        // Retrieve the element.  Mark the state as "no element available".
+        // Notify any waiting producers.
+        //
+	available_ = false;
+	mon_.notifyAll();
+        //
+        // Display the value while the monitor is still locked, since
+        // this will prevent corruption of the output stream.
+        //
+	cout << "Consumer #" << client << " get: " << value_ << endl;
+        
+	return value_;
+    }
+};
+
+//
+// This class represents a consumer thread.  This class is responsible
+// for retrieving elements from the cubby hole.
+//
+class Consumer : public JTCThread
+{
+    CubbyHole* cubby_; // Pointer to the cubby hole.
+    int number_; // The client number, for debugging.
+public:
+    //
+    // Constructor.
+    //
+    Consumer(CubbyHole* c, int which)
+	: JTCThread("consumer"), cubby_(c), number_(which)
+    {
+	cubby_ -> reference();
+    }
+
+    //
+    // Destructor.
+    //
+    virtual ~Consumer()
+    {
+	cubby_ -> dereference();
+    }
+
+    //
+    // This method is called when start is invoked on the thread.
+    //
+    virtual void run()
+    {
+        //
+        // Retrieve 10 numbers from the cubby hole.
+        //
+	for(int i = 0; i < 10; ++i)
+	{
+	    cubby_ -> get(number_);
+	}
+    }
+};
+
+//
+// This class represents the producer thread.  This thread places objects
+// in the cubbyhole for a consumer to retrieve.
+//
+class Producer : public JTCThread
+{
+    CubbyHole* cubby_; // The cubby hole object.
+    int number_; // The client number, for debugging.
+
+public:
+    //
+    // Constructor.
+    //
+    Producer(CubbyHole* c, int which)
+	: JTCThread("producer"), cubby_(c), number_(which)
+    {
+	cubby_ -> reference();
+    }
+
+    //
+    // Destructor.
+    //
+    virtual ~Producer()
+    {
+	cubby_ -> dereference();
+    }
+
+    //
+    // This method represents the main loop for this thread.
+    // It places 10 numbers in the cubby hole.
+    //
+    virtual void run()
+    {
+	for(int i = 0; i < 10; ++i)
+	{
+	    cubby_ -> put(i, number_);
+	}
+    }
+};
+
+int
+main(int argc, char** argv)
+{
+    try
+    {
+        //
+        // A user of the JTC library must create an instance of this
+        // class to initialize the library.
+        //
+	JTCInitialize bootJTC(argc, argv);
+
+        //
+        // Create an instance of the CubbyHole class.
+        //
+	CubbyHole* c = new CubbyHole;
+
+        //
+        // Create the producer and the consumer.
+        //
+	JTCThreadHandle producer = new Producer(c, 0);
+	JTCThreadHandle consumer = new Consumer(c, 1);
+
+        //
+        // Start the threads.
+        //
+	producer -> start();
+
+	consumer -> start();
+        //
+        // The instance of the JTCInitialize class will ensure that
+        // this block is not exited until all threads terminate.
+        //
+    }
+    catch(const JTCException& e)
+    {
+	cerr << "JTCException: " << e.getMessage() << endl;
+	return EXIT_FAILURE;
+    }
+
+    return EXIT_SUCCESS;
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/diner.cc
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/diner.cc	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/diner.cc	(revision 1017)
@@ -0,0 +1,345 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/JTC.h>
+
+#include <stdlib.h>
+
+#if defined(HAVE_STRSTREAM)
+#   include <strstream>
+#else
+#   if defined(HAVE_STRSTREA_H)
+#       include <strstrea.h>
+#   else
+#       include <strstream.h>
+#   endif
+#endif
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+//
+// This class ensures that the iostream class is only accessed by one
+// thread.  This stops corruption of the output stream.
+//
+class MTCout : public JTCMonitor
+{
+public:
+
+    void write(const char* buf)
+    {
+	JTCSynchronized sync(*this);
+	cout << buf << endl;
+    }
+};
+
+//
+// Global instance of the MTCout object.
+//
+MTCout mtCout;
+
+//
+// This class returns a random number.
+//
+class Random : public JTCMonitor
+{
+public:
+
+    int operator()()
+    {
+	JTCSynchronized sync(*this);
+	return rand();
+    }
+};
+
+//
+// Global instance of the random object.
+//
+Random genRandom;
+
+//
+// This class represents a chopstick.
+//
+class Chopstick : public JTCMonitor
+{
+};
+
+//
+// We have N_DINERS diners, and N_DINERS chopsticks.
+//
+#define N_DINERS 5
+Chopstick chopsticks[N_DINERS];
+
+//
+// A room.
+//
+class Room : public JTCMonitor
+{
+    int occupancy_; // Number of people in the room.
+    int maxOccupancy_; // Maximum number of people allowed in the room.
+public:
+    //
+    // Constructor.
+    //
+    Room(int maxOccupancy)
+        : occupancy_(0), maxOccupancy_(maxOccupancy)
+    {
+    }
+
+    //
+    // Add a person to the room.
+    //
+    void addPerson()
+    {
+        JTCSynchronized sync(*this);
+        ++occupancy_;
+        notifyAll();
+    }
+
+    //
+    // Remove a person from the room.
+    //
+    void removePerson()
+    {
+        JTCSynchronized sync(*this);
+        --occupancy_;
+        notifyAll();
+    }
+
+    //
+    // Wait for a place to become available.
+    //
+    void waitForPlace()
+    {
+        JTCSynchronized sync(*this);
+        while(occupancy_ == maxOccupancy_)
+        {
+            try
+            {
+                wait();
+            }
+            catch(const JTCInterruptedException&)
+            {
+            }
+        }
+    }
+
+    //
+    // Get the number of people in the room.
+    //
+    int numberPeople()
+    {
+        JTCSynchronized sync(*this);
+        return occupancy_;
+    }
+};
+
+Room room(N_DINERS);
+
+class Philosopher;
+
+//
+// Array of philosopher threads.
+//
+bool phillies[N_DINERS];
+
+//
+// This class represents a hungry philosopher.
+//
+class Philosopher : public JTCThread
+{
+    int id_; // The id of the philosopher.
+
+public:
+
+    //
+    // Constructor.
+    //
+    Philosopher(int id)
+	: id_(id)
+    {
+    }
+
+    //
+    // Mainline.  Grab left chopstick, grab right chopstick.  Eat food.
+    // Ponder life for a while.  Put down the chopsticks, and sleep for
+    // a while.  Repeat this cycle some random number of times.
+    // Then exit the room.
+    //
+    virtual void run()
+    {
+        //
+        // The variables l and r represent the index of the left and
+        // right chopsticks around the table.
+        //
+	int l = id_;
+	int r = l+1;
+	if(r == N_DINERS)
+	{
+	    r = 0;
+	}
+	if(l & 1)
+	{
+	    int t = l;
+	    l = r;
+	    r = t;
+	}
+	char buf[1024];
+	ostrstream os(buf, sizeof(buf));
+
+	os << "Philosopher #" << id_ << " has entered the room." <<ends;
+	mtCout.write(buf);
+	os.seekp(0);
+
+	int count = genRandom() % 10 + 1;
+	while(count--)
+	{
+	    {
+                //
+                // Grab left and right chopstick.
+                //
+		JTCSynchronized sync1(chopsticks[l]);
+		JTCSynchronized sync2(chopsticks[r]);
+
+                //
+                // Eat.
+                //
+		os << "Philosopher #" << id_ << " is eating." << ends;
+		mtCout.write(buf);
+		os.seekp(0);
+
+                //
+                // Ponder life.
+                //
+		JTCThread::sleep(genRandom()%2*1000 + genRandom()%1000);
+		os << "Philosopher #" << id_ << " is pondering life."<<ends;
+		mtCout.write(buf);
+		os.seekp(0);
+	    }
+            //
+            // Sleep for some period, before starting over.
+            //
+	    JTCThread::sleep(genRandom()%2*1000 + genRandom()%1000);
+	}
+
+        //
+        // Remove the philosopher from the room.
+        //
+        room.removePerson();
+
+        //
+        // Clear a spot in the array for the next philosopher.
+        //
+	phillies[id_] = false;
+
+	JTCSynchronized mtSync(mtCout);
+	os << "Philosopher #" << id_ << " has left the room. ("
+	   << room.numberPeople() << " left)." << ends;
+	mtCout.write(buf);
+	os.seekp(0);
+    }
+};
+
+int
+main(int argc, char** argv)
+{
+
+    try
+    {
+        //
+        // A user of the JTC library must create an instance of this
+        // class to initialize the library.
+        //
+        JTCInitialize bootJTC(argc, argv);
+
+	//
+	// Number of philosophers waiting to enter the room
+	// after the initial N_DINERS.
+	//
+	// Once all the diners have left the room the application
+	// will exit.
+	//
+	int nInQ = -1;
+	if (argc > 1)
+	{
+	    nInQ = atoi(argv[1]);
+	}
+
+        //
+        // Seed the random number generator.
+        //
+        srand(0);
+
+        int i;
+
+        //
+        // Add N_DINERS to the room.
+        //
+        for(i =0; i < N_DINERS; ++i)
+        {
+            room.addPerson();
+            phillies[i] = true;
+            JTCThreadHandle p = new Philosopher(i);
+            p -> start();
+        }
+
+        //
+        // Repeat forever.
+        //
+	while (nInQ > 0 || nInQ == -1)
+        {
+            //
+            // Wait for a place to open up in the room.
+            //
+            room.waitForPlace();
+            mtCout.write("main thread sleep.");
+
+            JTCThread::sleep(3);
+            mtCout.write("main thread wake.");
+
+            //
+            // Find the location of the philospher that left the room.
+            //
+            for(i =0; i < N_DINERS; ++i)
+                if(!phillies[i])
+		    break;
+
+            //
+            // Can't find the location?  This is an internal error of
+            // some sort.
+            //
+            if(i == N_DINERS)
+                abort();
+            //
+            // Create a new philosopher thread, add a person to the room.
+            //
+            room.addPerson();
+
+            phillies[i] = true;
+
+            JTCThreadHandle p = new Philosopher(i);
+            p -> start();
+
+	    if (nInQ != -1)
+	    {
+		--nInQ;
+	    }
+        }
+    }
+    catch(const JTCException& e)
+    {
+	cout << "Exception: " << e.getMessage() << endl;
+        return EXIT_FAILURE;
+    }
+    
+    return EXIT_SUCCESS;
+}
+
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/hello.cc
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/hello.cc	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/Examples/hello.cc	(revision 1017)
@@ -0,0 +1,57 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#include <JTC/JTC.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+//
+// This thread will display HelloWorld when started.
+//
+class HelloWorldThread : public JTCThread
+{
+public:
+    virtual void run()
+    {
+        cout << "hello world" << endl;
+    }
+};
+
+int
+main(int argc, char** argv)
+{
+    try
+    {
+        //
+        // A user of the JTC library must create an instance of this
+        // class to initialize the library.
+        //
+	JTCInitialize bootJTC(argc, argv);
+
+	//
+	// Create an instance of the HelloWorldThread object.
+	//
+	JTCThreadHandle t = new HelloWorldThread();
+
+	//
+	// Start the thread.
+	//
+	t -> start();
+    }
+    catch(const JTCException& e)
+    {
+	cerr << "JTCException: " << e.getMessage() << endl;
+	return EXIT_FAILURE;
+    }
+
+    return EXIT_SUCCESS;
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Cond.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Cond.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Cond.cpp	(revision 1017)
@@ -0,0 +1,356 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/Event.h>
+#include <JTC/Cond.h>
+#include <JTC/Handle.h>
+#include <JTC/HandleI.h>
+#include <JTC/Thread.h>
+#include <JTC/Monitor.h>
+#include <JTC/ThreadGroup.h>
+#include <JTC/Runnable.h>
+#include <JTC/Sync.h>
+
+#include <errno.h>
+
+#if defined(HAVE_POSIX_THREADS)
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+#ifndef WIN32
+//
+// This helper class is used to re-acquire the the recursive mutex.
+// It's in place to help with robustness in the event of
+// pthread_cancel.
+//
+class JTCCondHelper
+{
+    JTCRecursiveMutex& mut_;
+    int count_;
+
+public:
+
+    JTCCondHelper(JTCRecursiveMutex& m,
+		  int c)
+	: mut_(m), count_(c)
+    {
+    }
+
+    ~JTCCondHelper()
+    {
+	//       
+	// We need to acquire the mutex rationally... We unlock the
+	// mutexes critical section, and lock the mutex.  Restore
+	// saved information. NOTE: It's not correct to set the count
+	// and the owner of the mutex, the lock API method MUST be
+	// called.
+	//
+	pthread_mutex_unlock(&mut_.crit_);
+	mut_.lock(count_);
+    }
+};
+#endif
+
+// ----------------------------------------------------------------------
+// JTCCond private member implementation
+// ----------------------------------------------------------------------
+
+//
+// Wait for the condition variable to be signalled. The posix threads
+// and NT threads implementation are essentially the same, except that
+// the NT threads implementation uses an NT semaphore instead of a
+// native condition variable.
+//
+// A timeout value of -1 means wait forever. Otherwise, only wait for
+// timeout milliseconds.
+//
+void
+JTCCond::_wait(long timeout)
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    //
+    // The mutex is locked at this point. We need to acquire internal,
+    // save count. The cond_wait will unlock the mutexes critical
+    // section.
+    //
+    // To see that this code is correct, consider the following cases:
+    //
+    // - If no thread is currently attempting to lock the mutex then code
+    //   code is correct.
+    //
+    // - If another thread is attempting to unlock the mutex the
+    //   application is in error, since the thread calling wait owns the
+    //   mutex.
+    //
+    // - If thread B is attempting to lock the mutex, while thread A
+    //   is calling wait then the following cases need to be considered:
+    //
+    //   - Thread B obtains lock on internal first. The mutex count
+    //     will be 0, the owner will be nullThreadId. (set below)
+    //     Thread B unlocks internal. Thread A can now obtain it's lock
+    //     on internal. It locks internal, discovers count is 0,
+    //     increments count, sets owner, and attempts to lock
+    //     crit_. This lock cannot proceed until pthread_cond_wait below
+    //     is called.
+    //
+    //   - Thread A obtains lock on internal first. Count is non-zero,
+    //     and thread A does not own the mutex. Thread A attempts to
+    //     lock crit_, which blocks until pthread_cond_wait below is
+    //     called.
+    //
+    
+    int count;
+    {
+        JTCSynchronized guard(mutex_.internal_);
+        
+        //
+        // Save internal state information to be restored on method
+        // exit.
+        //
+        count = mutex_.count_;
+        mutex_.count_ = 0;
+        mutex_.owner_ = JTCThreadId();
+    }
+
+    //
+    // Calculate the timeout period.
+    //
+    struct timespec abstime;
+    if(timeout >= 0)
+    {
+	struct timeval tv;
+	gettimeofday(&tv, 0);
+                               //123456789 - 10^9
+	const long oneBillion = 1000000000;
+	abstime.tv_sec = tv.tv_sec + (timeout/1000);
+	abstime.tv_nsec = (tv.tv_usec * 1000) + ((timeout%1000) * 1000000);
+	if(abstime.tv_nsec > oneBillion)
+	{
+	    ++abstime.tv_sec;
+	    abstime.tv_nsec -= oneBillion;
+	}
+    }
+
+    try
+    {
+	JTCCondHelper unlock(mutex_, count);
+	
+	if(timeout < 0)
+	{
+	    JTC_SYSCALL_2(pthread_cond_wait, &cond_, &mutex_.crit_, < 0);
+	}
+	else
+	{
+		JTC_SYSCALL_3(pthread_cond_timedwait, &cond_, &mutex_.crit_,
+			      &abstime, < 0);
+	}
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	//
+	// EINTR is translated to InterruptedException.
+	//
+	if(e.getError() == EINTR)
+	    throw JTCInterruptedException();
+	//
+	// EAGAIN means that the wait time has passed.
+	//
+	else if (e.getError() == EAGAIN)
+	    return;
+	
+	//
+	// Rethrow caught exception.
+	//
+	throw;
+    }
+
+#endif
+#if defined(HAVE_WIN32_THREADS)
+
+    {
+	JTCSynchronized guard(waitersMutex_);
+	//
+	// mutex_ is locked on entry.
+	//
+	++waiters_;
+    }
+
+    int count;
+
+    if(timeout < 0)
+	timeout = INFINITE;
+
+    //
+    // Save state information.
+    //
+    {
+        JTCSynchronized guard(mutex_.internal_);
+
+        count = mutex_.count_;
+        mutex_.count_ = 0;
+        mutex_.owner_ = JTCThreadId();
+	LeaveCriticalSection(&mutex_.crit_);
+    }
+
+    try
+    {
+	JTC_SYSCALL_2(WaitForSingleObject, sema_, timeout, == WAIT_ABANDONED);
+    }
+    catch(const JTCSystemCallException&)
+    {
+        //
+        // Restore the mutex lock count times.
+        //
+	{
+	    JTCSynchronized guard(waitersMutex_);
+	    --waiters_;
+	}
+	mutex_.lock(count);
+	throw;
+    }
+
+    //
+    // Restore the mutex lock count times.
+    //
+    {
+	JTCSynchronized guard(waitersMutex_);
+	--waiters_;
+	if (waiters_ == 0 && haveBroadcast_)
+	    broadcastEvent_.post();
+    }
+    mutex_.lock(count);
+#endif
+}
+
+
+// ----------------------------------------------------------------------
+// JTCCond constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCCond::JTCCond(JTCRecursiveMutex& mut)
+    : mutex_(mut)
+{
+#if defined(HAVE_POSIX_THREADS)
+    JTC_SYSCALL_2(pthread_cond_init, &cond_, 0, != 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_cond_init, &cond_, pthread_condattr_default, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    haveBroadcast_ = false; 
+    waiters_ = 0;
+    JTC_SYSCALL_4(sema_ = CreateSemaphore, 0, 0, 0x7fffffff, 0, == INVALID_HANDLE_VALUE)
+#endif
+}
+
+JTCCond::~JTCCond()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_cond_destroy(&cond_);
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    CloseHandle(sema_);
+#endif
+}
+
+// ----------------------------------------------------------------------
+// JTCMonitor public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Wait to be signalled for timeout milliseconds.
+//
+void
+JTCCond::wait(long timeout)
+{
+    if(timeout < 0)
+	throw JTCIllegalArgumentException("timeout value is negative");
+    _wait(timeout);
+}
+
+//
+// Wait to be signalled.
+//
+void
+JTCCond::wait()
+{
+    _wait(-1);
+}
+
+//
+// Wake one waiting thread.
+//
+void
+JTCCond::signal()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_1(pthread_cond_signal,&cond_, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    bool haveWaiters;
+    {
+	JTCSynchronized guard(waitersMutex_);
+	haveWaiters = (waiters_ > 0);
+    }
+    if (haveWaiters)
+    {
+	JTC_SYSCALL_3(ReleaseSemaphore, sema_, 1, 0, == 0)
+    }
+#endif
+}
+
+//
+// Wake all waiting threads.
+//
+void
+JTCCond::broadcast()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_1(pthread_cond_broadcast,&cond_, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    bool haveWaiters;
+    int numWaiters;
+    {
+	JTCSynchronized guard(waitersMutex_);
+	haveWaiters = (waiters_ > 0);
+	numWaiters = waiters_;
+    }
+    if (haveWaiters)
+    {
+	//
+	// This is a broadcast event, so set the flag and reset
+	// the Event synchronization object.
+	//
+	haveBroadcast_ = true;
+	broadcastEvent_.reset();
+
+	//
+	// Release the semaphore waiters_ times.
+	//
+	JTC_SYSCALL_3(ReleaseSemaphore, sema_, numWaiters, 0, == 0)
+
+	//
+	// Wait for each thread to wake.
+	// After reset the haveBroadcast_ flag.
+	//
+	broadcastEvent_.wait();
+	haveBroadcast_ = false;
+    }
+#endif
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Event.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Event.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Event.cpp	(revision 1017)
@@ -0,0 +1,182 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/Event.h>
+#include <JTC/Cond.h>
+#include <JTC/Monitor.h>
+#include <JTC/Sync.h>
+#include <JTC/Exception.h>
+
+#include <errno.h>
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+//
+// This class encapsulates the functionality of a WIN32 event
+// semaphore.
+//
+
+// ----------------------------------------------------------------------
+// JTCEvent constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCEvent::JTCEvent()
+
+#ifndef WIN32
+    : posted_(false)
+#endif
+
+{
+#if defined(HAVE_POSIX_THREADS)
+    JTC_SYSCALL_2(pthread_cond_init, &cond_, 0, != 0)
+#endif
+
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_cond_init, &cond_, pthread_condattr_default, != 0)
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_4(event_ = CreateEvent, 0, 1, 0, 0, == INVALID_HANDLE_VALUE)
+#endif
+}
+
+JTCEvent::~JTCEvent()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_cond_destroy(&cond_);
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    CloseHandle(event_);
+#endif
+}
+
+// ----------------------------------------------------------------------
+// JTCEvent public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Set the state of the event object to signalled. Wake any waiting
+// threads.
+//
+void
+JTCEvent::post()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    JTCSynchronized sync(mut_);
+    posted_ = true;
+
+    //
+    // Wake up all waiters.
+    //
+    JTC_SYSCALL_1(pthread_cond_broadcast, &cond_, != 0)
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_1(SetEvent, event_, == 0)
+#endif
+}
+
+//
+// Wake any waiting threads.
+//
+void
+JTCEvent::pulse()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    JTCSynchronized sync(mut_);
+
+    posted_ = false;
+
+    //
+    // Wake up one waiter.
+    //
+    JTC_SYSCALL_1(pthread_cond_signal, &cond_, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_1(PulseEvent, event_, == 0)
+#endif
+}
+
+//
+// Wait for the event object to become signalled.
+//
+void
+JTCEvent::wait()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    //
+    // We want to lock the internal mutex. If we're not currently
+    // posted then wait on the condition variable. next unlock the
+    // internal mutex,
+    //
+    JTCSynchronized sync(mut_);
+    if(!posted_)
+    {
+	for(;;)
+	{
+	    try
+	    {
+		JTC_SYSCALL_2(pthread_cond_wait, &cond_, &mut_.lock_, < 0)
+	    }
+	    catch(const JTCSystemCallException& e)
+	    {
+		if(e.getError() == EINTR)
+		    continue;
+		throw;
+	    }
+	    break;
+	}
+    }
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_2(WaitForSingleObject,event_, INFINITE, != WAIT_OBJECT_0)
+#endif
+}
+
+//
+// Set the state of the event object to unsignalled.
+//
+void
+JTCEvent::reset()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    JTCSynchronized sync(mut_);
+    posted_ = false;
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_1(ResetEvent, event_, == 0)
+#endif
+}
+
+//
+// Determine if the event object is signalled.
+//
+bool
+JTCEvent::posted()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    JTCSynchronized sync(mut_);
+    return posted_;
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    long rc;
+    JTC_SYSCALL_2(rc = WaitForSingleObject, event_, 0, == WAIT_FAILED)
+    return rc != WAIT_TIMEOUT;
+#endif
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Cond.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Cond.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Cond.h	(revision 1017)
@@ -0,0 +1,73 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_COND_H
+#define JTC_COND_H
+
+//
+// This class acts like a pthreads condition variable. The difference
+// is that this implementation works with the recursive mutex
+// implementation in this library.
+//
+class JTCCond
+{
+    //
+    // Actual implementation of wait.
+    //
+    void _wait(long timeout);
+
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCCond(const JTCCond&);
+    void operator=(const JTCCond&);
+
+    JTCRecursiveMutex& mutex_; // Associated mutex.
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_cond_t cond_; // Pthread condition variable.
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    DWORD waiters_; // Number of waiters.
+    HANDLE sema_; // Handle to WIN32 sempahore object.
+    JTCMutex waitersMutex_;
+    JTCEvent broadcastEvent_;
+    bool haveBroadcast_;
+#endif
+
+public:
+
+    JTCCond(JTCRecursiveMutex& mut);
+    ~JTCCond();
+
+    //
+    // Wait for the condition variable to be signalled.
+    // The mutex has to be set.
+    //
+    void wait(long timeout);
+
+    //
+    // Wait for the condition variable to be signalled.
+    // The mutex has to be set.
+    //
+    void wait();
+
+    //
+    // Signal one waiting thread.
+    //
+    void signal();
+
+    //
+    // Signal all waiting threads.
+    //
+    void broadcast();
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Config.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Config.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Config.h	(revision 1017)
@@ -0,0 +1,166 @@
+/* include/JTC/Config.h.  Generated automatically by configure.  */
+/* include/JTC/Config.h.in.  Generated automatically from configure.in by autoheader.  */
+/***********************************************************************
+ *
+ * Copyright (c) 2000
+ * Object Oriented Concepts, Inc.
+ * Billerica, MA, USA
+ *
+ * All Rights Reserved
+ *
+ ***********************************************************************/
+
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if your c++ compiler doesn't know mutable. */
+/* #undef HAVE_NO_MUTABLE */
+
+/* Define if your c++ compiler doesn't have namespaces. */
+/* #undef HAVE_NO_NAMESPACE */
+
+/* Define if your c++ compiler supports iostream in namespace std. */
+/* #undef HAVE_STD_IOSTREAM */
+
+/* Define if your c++ compiler supports STL in namespace std. */
+#define HAVE_STD_STL 1
+
+/* Define if your c++ compiler can explicitly instanciate templates. */
+/* #undef HAVE_NO_EXPLICIT_TEMPLATES */
+
+/* Define if your c++ compiler does not have RTTI. */
+/* #undef HAVE_NO_RTTI */
+
+/* Define if your c++ compiler can't overload const type conversions. */
+/* #undef HAVE_NO_CONST_TYPE_CONVERSION_OVERLOAD */
+
+/* Define if your c++ compiler doesn't have typename. */
+/* #undef HAVE_NO_TYPENAME */
+
+/* Define if you don't have a prototype for gethostname(). */
+/* #undef HAVE_NO_GETHOSTNAME_PROTOTYPE */
+
+/* Define if there is no declaration for h_errno */
+/* #undef HAVE_NO_H_ERRNO_DECLARATION */
+
+/* Define if OS supports MIT threads. */
+/* #undef HAVE_MIT_THREADS */
+
+/* Define if OS supports FSU threads. */
+/* #undef HAVE_FSU_THREADS */
+
+/* Define if OS supports posix threads. */
+#define HAVE_POSIX_THREADS 1
+
+/* Define if OS supports DCE threads. */
+/* #undef HAVE_DCE_THREADS */
+
+/* Define if OS supports pthread_attr_setstacksize. */
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+
+/* Define if OS supports pthread_delay_np. */
+#define HAVE_PTHREAD_DELAY_NP 1
+
+/* Define if OS supports pthread_sched_yield. */
+#define HAVE_SCHED_YIELD 1
+
+/* Define if OS supports pthread_yield. */
+/* #undef HAVE_PTHREAD_YIELD */
+
+/* Define if JThreads/C++ has support for stop/suspend/resume. */
+#define HAVE_JTC_STOP 1
+
+/* The number of bytes in a bool.  */
+#define SIZEOF_BOOL 1
+
+/* The number of bytes in a char.  */
+#define SIZEOF_CHAR 1
+
+/* The number of bytes in a double.  */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in a float.  */
+#define SIZEOF_FLOAT 4
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 8
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* Define if you have the strcasecmp function.  */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strncasecmp function.  */
+#define HAVE_STRNCASECMP 1
+
+/* Define if you have the <bstring.h> header file.  */
+/* #undef HAVE_BSTRING_H */
+
+/* Define if you have the <exception> header file.  */
+#define HAVE_EXCEPTION 1
+
+/* Define if you have the <exception.h> header file.  */
+#define HAVE_EXCEPTION_H 1
+
+/* Define if you have the <fstream> header file.  */
+/* #undef HAVE_FSTREAM */
+
+/* Define if you have the <iostream> header file.  */
+/* #undef HAVE_IOSTREAM */
+
+/* Define if you have the <sched.h> header file.  */
+#define HAVE_SCHED_H 1
+
+/* Define if you have the <stddef.h> header file.  */
+#define HAVE_STDDEF_H 1
+
+/* Define if you have the <stdlib.h> header file.  */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <strings.h> header file.  */
+#define HAVE_STRINGS_H 1
+
+/* Define if you have the <strstream> header file.  */
+/* #undef HAVE_STRSTREAM */
+
+/* Define if you have the <sys/sched.h> header file.  */
+/* #undef HAVE_SYS_SCHED_H */
+
+/* Define if you have the <sys/select.h> header file.  */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/time.h> header file.  */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/types.h> header file.  */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <terminate.h> header file.  */
+/* #undef HAVE_TERMINATE_H */
+
+/* Define if you have the <termio.h> header file.  */
+#define HAVE_TERMIO_H 1
+
+/* Define if you have the <termios.h> header file.  */
+#define HAVE_TERMIOS_H 1
+
+/* Define if you have the <unexpected.h> header file.  */
+/* #undef HAVE_UNEXPECTED_H */
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the malloc library (-lmalloc).  */
+/* #undef HAVE_LIBMALLOC */
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Config.h.in
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Config.h.in	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Config.h.in	(revision 1017)
@@ -0,0 +1,165 @@
+/* include/JTC/Config.h.in.  Generated automatically from configure.in by autoheader.  */
+/***********************************************************************
+ *
+ * Copyright (c) 2000
+ * Object Oriented Concepts, Inc.
+ * Billerica, MA, USA
+ *
+ * All Rights Reserved
+ *
+ ***********************************************************************/
+
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define if your c++ compiler doesn't know mutable. */
+#undef HAVE_NO_MUTABLE
+
+/* Define if your c++ compiler doesn't have namespaces. */
+#undef HAVE_NO_NAMESPACE
+
+/* Define if your c++ compiler supports iostream in namespace std. */
+#undef HAVE_STD_IOSTREAM
+
+/* Define if your c++ compiler supports STL in namespace std. */
+#undef HAVE_STD_STL
+
+/* Define if your c++ compiler can explicitly instanciate templates. */
+#undef HAVE_NO_EXPLICIT_TEMPLATES
+
+/* Define if your c++ compiler does not have RTTI. */
+#undef HAVE_NO_RTTI
+
+/* Define if your c++ compiler can't overload const type conversions. */
+#undef HAVE_NO_CONST_TYPE_CONVERSION_OVERLOAD
+
+/* Define if your c++ compiler doesn't have typename. */
+#undef HAVE_NO_TYPENAME
+
+/* Define if you don't have a prototype for gethostname(). */
+#undef HAVE_NO_GETHOSTNAME_PROTOTYPE
+
+/* Define if there is no declaration for h_errno */
+#undef HAVE_NO_H_ERRNO_DECLARATION
+
+/* Define if OS supports MIT threads. */
+#undef HAVE_MIT_THREADS
+
+/* Define if OS supports FSU threads. */
+#undef HAVE_FSU_THREADS
+
+/* Define if OS supports posix threads. */
+#undef HAVE_POSIX_THREADS
+
+/* Define if OS supports DCE threads. */
+#undef HAVE_DCE_THREADS
+
+/* Define if OS supports pthread_attr_setstacksize. */
+#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+
+/* Define if OS supports pthread_delay_np. */
+#undef HAVE_PTHREAD_DELAY_NP
+
+/* Define if OS supports pthread_sched_yield. */
+#undef HAVE_SCHED_YIELD
+
+/* Define if OS supports pthread_yield. */
+#undef HAVE_PTHREAD_YIELD
+
+/* Define if JThreads/C++ has support for stop/suspend/resume. */
+#undef HAVE_JTC_STOP
+
+/* The number of bytes in a bool.  */
+#undef SIZEOF_BOOL
+
+/* The number of bytes in a char.  */
+#undef SIZEOF_CHAR
+
+/* The number of bytes in a double.  */
+#undef SIZEOF_DOUBLE
+
+/* The number of bytes in a float.  */
+#undef SIZEOF_FLOAT
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strncasecmp function.  */
+#undef HAVE_STRNCASECMP
+
+/* Define if you have the <bstring.h> header file.  */
+#undef HAVE_BSTRING_H
+
+/* Define if you have the <exception> header file.  */
+#undef HAVE_EXCEPTION
+
+/* Define if you have the <exception.h> header file.  */
+#undef HAVE_EXCEPTION_H
+
+/* Define if you have the <fstream> header file.  */
+#undef HAVE_FSTREAM
+
+/* Define if you have the <iostream> header file.  */
+#undef HAVE_IOSTREAM
+
+/* Define if you have the <sched.h> header file.  */
+#undef HAVE_SCHED_H
+
+/* Define if you have the <stddef.h> header file.  */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdlib.h> header file.  */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <strings.h> header file.  */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <strstream> header file.  */
+#undef HAVE_STRSTREAM
+
+/* Define if you have the <sys/sched.h> header file.  */
+#undef HAVE_SYS_SCHED_H
+
+/* Define if you have the <sys/select.h> header file.  */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file.  */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <terminate.h> header file.  */
+#undef HAVE_TERMINATE_H
+
+/* Define if you have the <termio.h> header file.  */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file.  */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <unexpected.h> header file.  */
+#undef HAVE_UNEXPECTED_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the malloc library (-lmalloc).  */
+#undef HAVE_LIBMALLOC
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Event.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Event.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Event.h	(revision 1017)
@@ -0,0 +1,69 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_EVENT_H
+#define JTC_EVENT_H
+
+//
+// This is an internal class to JTC. Do not directly use. This class
+// acts like an event object under WIN32. This is a synchronization
+// object that allows one thread to notify another that an event has
+// occurred.
+//
+class JTCEvent
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCEvent(const JTCEvent&);
+    void operator=(const JTCEvent&);
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_cond_t cond_; // Associated condition variable.
+    JTCMutex mut_; // Condition variables mutex.
+    bool posted_; // State flag for signalled/unsignalled.
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    HANDLE event_; // Handle to event object.
+#endif
+
+public:
+
+    JTCEvent();
+    ~JTCEvent();
+
+    //
+    // Set the event to `signaled'.
+    //
+    void post();
+
+    //
+    // Set the state to `signaled', Release any waiting threads,
+    //
+    void pulse();
+
+    //
+    // Suspend the calling thread until the event is `signaled'.
+    //
+    void wait();
+
+    //
+    // Set the state to `unsignaled'.
+    //
+    void reset();
+
+    //
+    // Return true if the event is `signaled', false otherwise.
+    //
+    bool posted();
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Exception.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Exception.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Exception.h	(revision 1017)
@@ -0,0 +1,200 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_EXCEPTION_H
+#define JTC_EXCEPTION_H
+
+//
+// Exception hierarchy for JTC.
+//
+// JTCThreadDeath
+//
+// JTCException
+//   |
+//   +-- JTCInterruptedException
+//   |
+//   +-- JTCIllegalThreadStateException
+//   |
+//   +-- JTCIllegalArgumentException
+//   |
+//   +-- JTCSystemCallException
+//   |
+//   +-- JTCOutOfMemoryError
+//   |
+//   +-- JTCIllegalMonitorStateException
+//   |
+//   +-- JTCUnknownThreadException
+//
+
+#include <string.h>
+
+class JTCThreadDeath
+{
+};
+
+class JTCException
+{
+    char* note_;
+    int error_;
+
+public:
+
+    JTCException(const char* note = "", long error = 0)
+	: error_(error)
+    {
+	note_ = new char[strlen(note) + 1];
+	strcpy(note_, note);
+    }
+
+    JTCException(const JTCException& e)
+	: error_(e.error_)
+    {
+	note_ = new char[strlen(e.note_) +1];
+	strcpy(note_, e.note_);
+    }
+
+    JTCException& operator=(const JTCException& e)
+    {
+	if(this != &e)
+	{
+	    error_ = e.error_;
+	    note_ = new char[strlen(e.note_) +1];
+	    strcpy(note_, e.note_);
+	}
+	return *this;
+    }
+
+    virtual ~JTCException()
+    {
+	delete[] note_;
+    }
+
+    long getError() const
+    {
+	return error_;
+    }
+
+    virtual const char* getType() const
+    {
+	return "JTCException";
+    }
+
+    const char* getMessage() const
+    {
+	return note_;
+    }
+};
+
+inline JTC_STD(ostream)&
+operator<<(JTC_STD(ostream)& os, const JTCException& e)
+{
+    os << e.getType() << ": " << e.getMessage();
+    return os;
+}
+
+
+class JTCInterruptedException : public JTCException
+{
+public:
+
+    JTCInterruptedException() {}
+    JTCInterruptedException(const char* note)
+	: JTCException(note) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCInterruptedException";
+    }
+};
+
+class JTCIllegalThreadStateException : public JTCException
+{
+public:
+
+    JTCIllegalThreadStateException() {}
+    JTCIllegalThreadStateException(const char* note)
+	: JTCException(note) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCIllegalThreadStateException";
+    }
+};
+
+class JTCIllegalMonitorStateException : public JTCException
+{
+public:
+
+    JTCIllegalMonitorStateException() { }
+    JTCIllegalMonitorStateException(const char* note)
+	: JTCException(note) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCIllegalMonitorStateException";
+    }
+};
+
+class JTCIllegalArgumentException : public JTCException
+{
+public:
+
+    JTCIllegalArgumentException() { }
+    JTCIllegalArgumentException(const char* note)
+	: JTCException(note) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCIllegalArgumentException";
+    }
+};
+
+class JTCSystemCallException : public JTCException
+{
+public:
+
+    JTCSystemCallException(const char* note, long error)
+	: JTCException(note, error) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCSystemCallException";
+    }
+};
+
+class JTCOutOfMemoryError : public JTCException
+{
+public:
+
+    JTCOutOfMemoryError() { }
+    JTCOutOfMemoryError(const char* note)
+	: JTCException(note) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCOutOfMemoryError";
+    }
+};
+
+class JTCUnknownThreadException : public JTCException
+{
+public:
+
+    JTCUnknownThreadException() { }
+    JTCUnknownThreadException(const char* note)
+	: JTCException(note) { }
+
+    virtual const char* getType() const
+    {
+	return "JTCUnknownThreadException";
+    }
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Handle.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Handle.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Handle.h	(revision 1017)
@@ -0,0 +1,104 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_HANDLE_H
+#define JTC_HANDLE_H
+
+//
+// Provide some handy typedefs.
+//
+template <class T> class JTCHandleT;
+
+class JTCThread;
+typedef JTCHandleT<JTCThread> JTCThreadHandle;
+
+class JTCThreadGroup;
+typedef JTCHandleT<JTCThreadGroup> JTCThreadGroupHandle;
+
+class JTCRunnable;
+typedef JTCHandleT<JTCRunnable> JTCRunnableHandle;
+
+//
+// JTCRefCount class. This is a base class to be used in conjunction
+// with the JTCHandleT class.
+//
+class JTCRefCount
+{
+public:
+    int _jtc_refCount_;
+    JTCMutex refMutex_;
+    
+    JTCRefCount()
+        : _jtc_refCount_(0)
+    {
+    }
+
+    virtual ~JTCRefCount()
+    {
+    }
+};
+
+//
+// This class is a handle to a reference counted object. This ensures
+// that the object is deleted when it is no longer referenced.
+//
+template <class T>
+class JTCHandleT
+{
+    T* tg_; // Referenced object
+
+public:
+
+    //
+    // Constructors.
+    //
+    JTCHandleT(T* tg = 0);
+    JTCHandleT(const JTCHandleT<T>& rhs);
+
+    //
+    // Destructor. Deletes object when reference count drops to
+    // zero.
+    //
+    ~JTCHandleT();
+
+    //
+    // Assignment operator.
+    //
+    JTCHandleT<T>& operator=(const JTCHandleT<T>& rhs);
+
+    //
+    // Equality and inequality.
+    //
+    bool operator==(const JTCHandleT<T>& rhs) const
+    { return tg_ == rhs.tg_; }
+    bool operator!=(const JTCHandleT<T>& rhs) const
+    { return tg_ != rhs.tg_; }
+
+    //
+    // Logical not operator. Are we referring to a valid Thread?
+    //
+    bool operator!() const { return tg_ == 0; }
+    operator bool() const { return tg_ != 0; }
+    
+    //
+    // Make access to the Thread intuitive.
+    //
+    T* operator->() const { return tg_; }
+    T* get() const { return tg_; }
+    T& operator*() { return *tg_; }
+
+    void _jtc_deref();
+};
+
+#if defined(HAVE_NO_EXPLICIT_TEMPLATES) && !defined(HAVE_PRAGMA_DEFINE)
+#   include "JTC/HandleI.h"
+#endif
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/HandleI.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/HandleI.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/HandleI.h	(revision 1017)
@@ -0,0 +1,112 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_HANDLE_I_H
+#define JTC_HANDLE_I_H
+
+// ----------------------------------------------------------------------
+// JTCHandleT constructors and destructor
+// ----------------------------------------------------------------------
+
+template <class T>
+JTCHandleT<T>::JTCHandleT(T* tg)
+    : tg_(tg)
+{
+    if(tg_ != 0)
+    {
+	tg_ -> refMutex_.lock();
+	++tg_ -> _jtc_refCount_; // Boost reference count.
+	tg_ -> refMutex_.unlock();
+    }
+}
+
+template <class T>
+JTCHandleT<T>::~JTCHandleT()
+{
+    bool deleteIt = false;
+    {
+        if(tg_ != 0)
+        {
+	    tg_ -> refMutex_.lock();
+            if(--tg_ -> _jtc_refCount_ == 0)
+                deleteIt = true;
+	    tg_ -> refMutex_.unlock();
+        }
+    }
+    if(deleteIt)
+        delete tg_;
+}
+
+// ----------------------------------------------------------------------
+// JTCHandle public member implementation
+// ----------------------------------------------------------------------
+template <class T>
+JTCHandleT<T>::JTCHandleT(const JTCHandleT<T>& rhs)
+    : tg_(rhs.tg_)
+{
+    if(tg_ != 0)
+    {
+	tg_ -> refMutex_.lock();
+	++tg_ -> _jtc_refCount_; // Boost reference count.
+	tg_ -> refMutex_.unlock();
+    }
+}
+
+
+template <class T>
+JTCHandleT<T>&
+JTCHandleT<T>::operator=(const JTCHandleT<T>& rhs)
+{
+    bool deleteIt = false;
+    {
+        if(tg_ == rhs.tg_)
+            return *this;
+        
+        if(tg_ != 0)
+        {
+	    tg_ -> refMutex_.lock();
+            if(--tg_ -> _jtc_refCount_ == 0) // Time to clean out object?
+                deleteIt = true;
+	    tg_ -> refMutex_.unlock();
+        }
+    }
+    if(deleteIt)
+        delete tg_;
+        
+    tg_ = rhs.tg_; // Copy in RHS contents.
+    if(tg_ != 0)
+    {
+	tg_ -> refMutex_.lock();
+	++tg_ -> _jtc_refCount_; // Boost reference count.
+	tg_ -> refMutex_.unlock();
+    }
+
+    return *this;
+}
+
+template <class T> void
+JTCHandleT<T>::_jtc_deref()
+{
+    if (tg_ != 0)
+    {
+        bool deleteIt = false;
+        {
+	    tg_ -> refMutex_.lock();
+            if (--tg_ -> _jtc_refCount_ == 0)
+                deleteIt = true;
+	    tg_ -> refMutex_.unlock();
+        }
+        if(deleteIt)
+            delete tg_;
+        tg_ = 0;
+    }
+}
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/JTC.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/JTC.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/JTC.h	(revision 1017)
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_JTC_H
+#define JTC_JTC_H
+
+#include <JTC/Types.h>
+#include <JTC/Exception.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/Handle.h>
+#include <JTC/HandleI.h>
+#include <JTC/Event.h>
+#include <JTC/Cond.h>
+#include <JTC/Mutex.h>
+#include <JTC/Monitor.h>
+#include <JTC/MonitorT.h>
+#include <JTC/ThreadGroup.h>
+#include <JTC/Runnable.h>
+#include <JTC/Thread.h>
+#include <JTC/TSS.h>
+#include <JTC/Sync.h>
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Makefile.mak
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Makefile.mak	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Makefile.mak	(revision 1017)
@@ -0,0 +1,24 @@
+# **********************************************************************
+#
+# Copyright (c) 2000
+# Object Oriented Concepts, Inc.
+# Billerica, MA, USA
+#
+# All Rights Reserved
+#
+# **********************************************************************
+
+top_srcdir	= ..\..
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+install::
+	@if not exist $(includedir)\JTC \
+	    @echo "Creating $(includedir)\JTC..." & \
+	    mkdir $(includedir)\JTC
+
+	@for %i in ( *.h ) do \
+	    @echo Installing %i & \
+	    copy %i $(includedir)\JTC\%i
+
+install_min:: install
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Monitor.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Monitor.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Monitor.h	(revision 1017)
@@ -0,0 +1,87 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_MONITOR_H
+#define JTC_MONITOR_H
+
+//
+// A monitor is used to ensure that only one thread can have access to
+// the internals of an object at one time. Use the class
+// JTCSynchronized to automatically lock and unlock a monitor.
+//
+// The JTCMonitor class also provides an efficient way of notification
+// and suspension of threads. The wait method waits for a notification
+// by another thread. A thread may notify a waiting object with the
+// notify call. A thread may notify all waiting objects with the
+// notifyAll call.
+//
+class JTCMonitor
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCMonitor(const JTCMonitor&);
+    void operator=(const JTCMonitor&);
+
+    friend class JTCSynchronized;
+
+    //
+    // Validate that the monitor is locked by the calling thread.
+    //
+    void validateMutexOwner(const char*) const;
+
+    //
+    // Lock the monitors mutex. If internal is set the do not check
+    // the threads exit status.
+    //
+    void lock(bool) const;
+
+    //
+    // Unlock the monitors mutex.
+    //
+    void unlock() const;
+
+    JTCRecursiveMutex monMutex_; // Monitors mutex.
+    JTCCond monCond_; // Monitors condition variable.
+
+#ifdef HAVE_JTC_STOP
+    //
+    // Was the mutex aquired by an internal JTC method?
+    //
+    bool internalLock_;
+#endif
+
+public:
+
+    JTCMonitor();
+    virtual ~JTCMonitor();
+
+    //
+    // Wait for notification.
+    //
+    void wait();
+
+    //
+    // Wait for notification, or timeout milliseconds.
+    //
+    void wait(long);
+	
+    //
+    // Wake one waiting object.
+    //
+    void notify();
+
+    //
+    // Wake all waiting objects.
+    //
+    void notifyAll();
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/MonitorT.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/MonitorT.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/MonitorT.h	(revision 1017)
@@ -0,0 +1,54 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_MONITOR_TEMPL_H_
+#define JTC_MONITOR_TEMPL_H_
+
+#include <JTC/Monitor.h>
+
+template <class T>
+class JTCMonitorT : public JTCMonitor
+{
+    T& obj_;
+
+public:
+
+    JTCMonitorT(T& obj)
+	: obj_(obj)
+    {
+    }
+
+    T& operator*()
+    {
+	return obj_;
+    }
+
+    const T& operator*() const
+    {
+	return obj_;
+    }
+
+    T* operator->()
+    {
+	return &obj_;
+    }
+
+    const T* operator->() const
+    {
+	return &obj_;
+    }
+
+    T& get()
+    {
+	return obj_;
+    }
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Mutex.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Mutex.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Mutex.h	(revision 1017)
@@ -0,0 +1,168 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_MUTEX_H
+#define JTC_MUTEX_H
+
+//
+// This class can be used to establish a critical section. Call the
+// lock method to lock the mutex, and the unlock Method to unlock the
+// mutex. If the mutex is currently locked the thread will be
+// suspended until the mutex becomes unlocked.
+//
+class JTCMutex
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCMutex(const JTCMutex&);
+    void operator=(const JTCMutex&);
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_mutex_t lock_; // Pthread mutex.
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    CRITICAL_SECTION crit_; // WIN32 critical section.
+#endif
+
+    friend class JTCEvent;
+
+public:
+
+    JTCMutex()
+    {
+#if defined(HAVE_POSIX_THREADS)
+        JTC_SYSCALL_2(pthread_mutex_init, &lock_, 0, != 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+        JTC_SYSCALL_2(pthread_mutex_init, &lock_, pthread_mutexattr_default,
+		      != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+        InitializeCriticalSection(&crit_);
+#endif
+    }
+    ~JTCMutex()
+    {
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+        pthread_mutex_destroy(&lock_);
+#endif
+#if defined(HAVE_WIN32_THREADS)
+        DeleteCriticalSection(&crit_);
+#endif
+    }
+
+    //
+    // Lock the mutex.
+    //
+    void lock() const
+    {
+#if defined(HAVE_WIN32_THREADS)
+#endif
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+	//
+	// The optimizer for GCC 2.95.1 is broken. The following
+	// three lines of code "fix" the problem.
+	//
+	volatile int i = 1;
+	if (i == 0) 
+	    ++i;
+#endif
+        pthread_mutex_t* lock = &((JTCMutex*)this) -> lock_;
+        JTC_SYSCALL_1(pthread_mutex_lock, lock, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+	CRITICAL_SECTION* crit = &((JTCMutex*)this) -> crit_;
+        EnterCriticalSection(crit);
+#endif
+    }
+
+
+    //
+    // Unlock the mutex.
+    //
+    void unlock() const
+    {
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+        pthread_mutex_t* lock = &((JTCMutex*)this) -> lock_;
+        JTC_SYSCALL_1(pthread_mutex_unlock, lock, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+	CRITICAL_SECTION* crit = &((JTCMutex*)this) -> crit_;
+        LeaveCriticalSection(crit);
+#endif
+
+    }
+};
+
+//
+// Unlike the JTCMutex class this mutex can be locked recursively.
+// That is it can be locked by a thread that already has the mutex
+// locked.
+//
+class JTCRecursiveMutex
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCRecursiveMutex(const JTCRecursiveMutex&);
+    void operator=(const JTCRecursiveMutex&);
+
+    //
+    // Internal non-const operations since mutable isn't supported
+    // on some compilers.
+    //
+    void lockI(int count);
+    void unlockI();
+
+    //
+    // Lock the mutex count times.
+    //
+    void lock(int count) const;
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_mutex_t crit_; // Pthreads mutex.
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    CRITICAL_SECTION crit_; // WIN32 critical section.
+#endif
+    JTCMutex internal_; // Internal mutex.
+ 
+    int count_; // Number of times the mutex has been aquired.
+    JTCThreadId owner_; // Current owner of the mutex.
+
+    friend class JTCCondHelper;
+    friend class JTCCond;
+
+public:
+
+    JTCRecursiveMutex();
+    ~JTCRecursiveMutex();
+
+    //
+    // Lock the mutex.
+    //
+    void lock() const;
+    
+    //
+    // Unlock the mutex.
+    //
+    void unlock() const;
+
+    //
+    // Get the thread id of the owning thread.
+    //
+    JTCThreadId _JTC_getId() const;
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Runnable.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Runnable.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Runnable.h	(revision 1017)
@@ -0,0 +1,20 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_RUNNABLE_H
+#define JTC_RUNNABLE_H
+
+class JTCRunnable : public virtual JTCRefCount
+{
+public:
+    virtual void run() = 0;
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Sync.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Sync.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Sync.h	(revision 1017)
@@ -0,0 +1,96 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_SYNC_H
+#define JTC_SYNC_H
+
+//
+// This class is used to lock and unlock a monitor.
+//
+class JTCSynchronized
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCSynchronized(const JTCSynchronized&);
+    void operator=(const JTCSynchronized&);
+
+    const JTCMonitor* mon_; // Associated monitor.
+    const JTCMutex* mut_; // Associated mutex.
+    const JTCRecursiveMutex* nrmut_; // Associated recursive mutex.
+
+    enum
+    {
+	LOCKED_MONITOR,
+	LOCKED_MUTEX,
+	LOCKED_RECURSIVE_MUTEX
+    }
+    lockType_; // The lock type
+
+public:
+
+    JTCSynchronized(const JTCMonitor& mon);
+    JTCSynchronized(const JTCMonitor& mon, bool internal);
+    JTCSynchronized(const JTCMutex& m);
+    JTCSynchronized(const JTCRecursiveMutex& m);
+    ~JTCSynchronized();
+};
+
+//
+// Inlining the methods causes problems with CC 7.1 under SGI
+//
+#if !defined(__sgi)
+inline
+JTCSynchronized::JTCSynchronized(const JTCMonitor& mon)
+    : mon_(&mon), lockType_(LOCKED_MONITOR)
+{
+    mon_ -> lock(false);
+}
+
+inline
+JTCSynchronized::JTCSynchronized(const JTCMonitor& mon, bool internal)
+    : mon_(&mon), lockType_(LOCKED_MONITOR)
+{
+    mon_ -> lock(internal);
+}
+
+inline
+JTCSynchronized::JTCSynchronized(const JTCMutex& m)
+    : mut_(&m), lockType_(LOCKED_MUTEX)
+{
+    mut_ -> lock();
+}
+
+inline
+JTCSynchronized::JTCSynchronized(const JTCRecursiveMutex& m)
+    : nrmut_(&m), lockType_(LOCKED_RECURSIVE_MUTEX)
+{
+    nrmut_ -> lock();
+}
+
+inline
+JTCSynchronized::~JTCSynchronized()
+{
+    switch(lockType_)
+    {
+    case LOCKED_MONITOR:
+	mon_ -> unlock();
+	break;
+    case LOCKED_MUTEX:
+	mut_ -> unlock();
+	break;
+    case LOCKED_RECURSIVE_MUTEX:
+	nrmut_ -> unlock();
+	break;
+    }
+}
+#endif
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Syscall.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Syscall.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Syscall.h	(revision 1017)
@@ -0,0 +1,174 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_SYSCALL_H
+#define JTC_SYSCALL_H
+
+#if defined(HAVE_STRSTREAM)
+#   include <strstream>
+#else
+#   if defined(HAVE_STRSTREA_H)
+#       include <strstrea.h>
+#   else
+#       include <strstream.h>
+#   endif
+#endif
+
+#include <JTC/Exception.h>
+
+#define JTC_THROW_EXCEPTION(CODE,MSG) \
+{ \
+    long error = CODE; \
+    char msg[ 512 ]; \
+    msg[sizeof(msg)-1] = '\0'; \
+    JTC_STD(ostrstream) stream(msg, sizeof(msg)-1); \
+    stream << MSG << " == " << error << " [" << __FILE__ \
+           << ':' << __LINE__ << ']' << JTC_STD(ends); \
+    throw JTCSystemCallException(msg, error); \
+}
+
+#define JTC_CAT_WNL(ARG) \
+  "                " << (ARG) << ", // " << #ARG << "\n"
+
+#define JTC_CAT(ARG) \
+  "                " << (ARG) << "  // " << #ARG
+
+#define JTC_FMT_ARG_0 \
+  " ()"
+
+#define JTC_FMT_ARG_1(A1) \
+  "\n                (\n" << JTC_CAT(A1) << "\n                )"
+
+#define JTC_FMT_ARG_2(A1,A2) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT(A2) \
+  << "\n                )"
+
+#define JTC_FMT_ARG_3(A1,A2,A3) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT(A3) << "\n                )"
+
+#define JTC_FMT_ARG_4(A1,A2,A3,A4) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT_WNL(A3) << JTC_CAT(A4) << "\n                )"
+
+#define JTC_FMT_ARG_5(A1,A2,A3,A4,A5) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT_WNL(A3) << JTC_CAT_WNL(A4) << JTC_CAT(A5) << "\n                )"
+
+#define JTC_FMT_ARG_6(A1,A2,A3,A4,A5,A6) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT_WNL(A3) << JTC_CAT_WNL(A4) << JTC_CAT_WNL(A5) << JTC_CAT(A6) \
+  << "\n                )"
+
+#define JTC_FMT_ARG_7(A1,A2,A3,A4,A5,A6,A7) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT_WNL(A3) << JTC_CAT_WNL(A4) << JTC_CAT_WNL(A5) << JTC_CAT_WNL(A6) \
+  << JTC_CAT(A7) << "\n                )"
+
+#define JTC_FMT_ARG_8(A1,A2,A3,A4,A5,A6,A7,A8) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT_WNL(A3) << JTC_CAT_WNL(A4) << JTC_CAT_WNL(A5) << JTC_CAT_WNL(A6) \
+  << JTC_CAT_WNL(A7) << JTC_CAT(A8) << "\n                )"
+
+#define JTC_FMT_ARG_9(A1,A2,A3,A4,A5,A6,A7,A8,A9) \
+  "\n                (\n" << JTC_CAT_WNL(A1) << JTC_CAT_WNL(A2) \
+  << JTC_CAT_WNL(A3) << JTC_CAT_WNL(A4) << JTC_CAT_WNL(A5) << JTC_CAT_WNL(A6) \
+  << JTC_CAT_WNL(A7) << JTC_CAT_WNL(A8) << JTC_CAT(A9) << "\n                )"
+
+#if defined(WIN32)
+#   define ERRNO GetLastError()
+#   define DECLARE_ERRNO
+#   define ASSIGN_ERRNO
+#else
+#   if defined(__hpux) && defined(HAVE_DCE_THREADS)
+#       define ERRNO errno
+#   else
+#       define ERRNO _jtc_syscallError
+#   endif
+#   define DECLARE_ERRNO int _jtc_syscallError;
+#   define ASSIGN_ERRNO _jtc_syscallError =
+#endif
+
+#define JTC_SYSCALL_0(FN,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN())) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_0 ) \
+} while(0);
+
+#define JTC_SYSCALL_1(FN,A1,COND) \
+{ \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_1(A1) ) \
+} while(0);
+
+#define JTC_SYSCALL_2(FN,A1,A2,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_2(A1,A2) ) \
+} while(0);
+
+#define JTC_SYSCALL_3(FN,A1,A2,A3,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_3(A1,A2,A3) ) \
+} while(0);
+
+#define JTC_SYSCALL_4(FN,A1,A2,A3,A4,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3,A4))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_4(A1,A2,A3,A4) ) \
+} while(0);
+
+#define JTC_SYSCALL_5(FN,A1,A2,A3,A4,A5,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3,A4,A5))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_5(A1,A2,A3,A4,A5) ) \
+} while(0);
+
+#define JTC_SYSCALL_6(FN,A1,A2,A3,A4,A5,A6,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3,A4,A5,A6))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << JTC_FMT_ARG_6(A1,A2,A3,A4,A5,A6) ) \
+} while(0);
+
+#define JTC_SYSCALL_7(FN,A1,A2,A3,A4,A5,A6,A7,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3,A4,A5,A6,A7))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << \
+			     JTC_FMT_ARG_7(A1,A2,A3,A4,A5,A6,A7) ) \
+} while(0);
+
+
+#define JTC_SYSCALL_8(FN,A1,A2,A3,A4,A5,A6,A7,A8,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3,A4,A5,A6,A7,A8))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << \
+			     JTC_FMT_ARG_8(A1,A2,A3,A4,A5,A6,A7,A8) ) \
+} while(0);
+
+
+#define JTC_SYSCALL_9(FN,A1,A2,A3,A4,A5,A6,A7,A8,A9,COND) \
+do { \
+    DECLARE_ERRNO \
+    if ((ASSIGN_ERRNO (FN (A1,A2,A3,A4,A5,A6,A7,A8,A9))) COND) \
+        JTC_THROW_EXCEPTION( ERRNO, #FN << \
+			     JTC_FMT_ARG_9(A1,A2,A3,A4,A5,A6,A7,A8,A9) ) \
+} while(0);
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/TSS.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/TSS.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/TSS.h	(revision 1017)
@@ -0,0 +1,48 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_TSS_H
+#define JTC_TSS_H
+
+#include <JTC/Types.h>
+
+class JTCTSS
+{
+public:
+
+    //
+    // Allocate a new Thread Specific Key
+    //
+    static JTCThreadKey allocate();
+
+    //
+    // Allocate a new Thread Specific Key and a cleanup function.
+    // When a thread is destroyed this cleanup function will be
+    // called.
+    //
+    static JTCThreadKey allocate(void (*)(void*));
+
+    //
+    // Release a Thread Specific Key
+    //
+    static void release(JTCThreadKey key);
+
+    //
+    // Get the per-thread data associated with the Thread Specific Key
+    //
+    static void* get(JTCThreadKey key);
+
+    //
+    // Set the per-thread data associated with the Thread Specific Key
+    //
+    static void set(JTCThreadKey key, void* value);
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Thread.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Thread.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Thread.h	(revision 1017)
@@ -0,0 +1,320 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_THREAD_H
+#define JTC_THREAD_H
+
+class JTCMonitor;
+class JTCThreadGroup;
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+typedef void (*JTCAttrHook)(pthread_attr_t*);
+#endif
+
+//
+// This class encapsulates the functionality of a thread.
+//
+class JTCThread : public virtual JTCRefCount
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCThread(const JTCThread&);
+    void operator=(const JTCThread&);
+
+#ifdef HAVE_JTC_STOP
+    //
+    // Check running status of this thread.  This determines whether
+    // the thread needs to be suspended or terminated.
+    //
+    void _checkRunningStatus() const;
+
+    //
+    // Set the monitor associated with this thread.
+    //
+    void setMonitor(JTCMonitor* monitor);
+    JTCMonitor* getMonitor();
+#endif
+
+    //
+    // Spawn a new thread.
+    //
+    void spawnThread();
+
+    //
+    // Helper for the constructor.
+    //
+    void init(const JTCThreadGroupHandle& group, JTCRunnableHandle target,
+	      const char* name);
+
+    //
+    // Private constructor for booting JTC.
+    //
+    JTCThread(JTCThreadId tid, bool main);
+
+    JTCThreadId thrId_; // Threads ID.
+    JTCThreadGroupHandle group_; // Group of this thread.
+
+    //
+    // Event variable used for waiting until thread data is set.
+    //
+    JTCEvent setInitialData_;
+
+    char* name_; // Name of the thread.
+    JTCRunnableHandle target_; // Target of the thread.
+    enum
+    {
+	NewThread,
+	Runnable,
+	NotRunnable,
+	Dead
+    } state_; // The thread state.
+
+    JTCEvent startRequest_; // Used for starting the thread.
+
+    //
+    // State flags.
+    // Future enhancement could be to convert these
+    // flags to a bitfield to save space.
+    //
+    enum { not_terminated, terminated, throw_termination };
+    int terminated_; // Has the thread been terminated.
+
+    JTCRecursiveMutex resumeMut_; // Mutex, associated with resumeCond.
+
+#ifdef HAVE_JTC_STOP
+    bool suspended_; // Has the thread been suspended.
+
+    JTCCond resumeCond_; // Condition variable used for resume.
+
+    JTCMutex monMutex_; // Mutex to protect monitor
+    JTCMonitor* monitor_; // Threads current monitor.
+#endif
+
+    JTCCond joinCond_; // Join condition variable.
+    JTCRecursiveMutex joinMut_; // Join mutex.
+
+    bool adopted_; // Is this thread adopted?
+    
+    static JTCThreadKey thrKey_; // TSS key.
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    static JTCAttrHook attrHook_;
+#endif
+
+    friend class JTCInitialize;
+    friend class JTCAdoptCurrentThread;
+
+public:
+
+    JTCThread (const char* name);
+    JTCThread (JTCRunnableHandle target = JTCRunnableHandle(),
+    	       const char* name = 0);
+    JTCThread (JTCThreadGroupHandle& group, JTCRunnableHandle target,
+	       const char* name = 0);
+    JTCThread (JTCThreadGroupHandle& group, const char* name = 0);
+
+    virtual ~JTCThread();
+
+    //
+    // Get the threads group.
+    //
+    JTCThreadGroupHandle getThreadGroup();
+
+    //
+    // Set the name of this thread.
+    //
+    void setName(const char*);
+
+    //
+    // Get the name of this thread.
+    //
+    const char* getName() const;
+
+#ifdef HAVE_JTC_STOP
+    //
+    // Suspend the thread.
+    //
+    void suspend();
+
+    //
+    // Resume the thread.
+    //
+    void resume();
+
+    //
+    // Stop the thread.  Subclasses should override this method to
+    // provide special functionality for stopping.
+    //
+    virtual void stop();
+#endif
+    
+    //
+    // Start the thread.
+    //
+    void start();
+
+    //
+    // Override this method to provide functionality to your thread.
+    //
+    virtual void run();
+
+    //
+    // Determine if the thread is currently running.
+    //
+    bool isAlive() const;
+
+    //
+    // Wait for this thread to terminate.
+    //
+    void join();
+
+    //
+    // Wait at most millis for this thread to terminate.
+    //
+    void join(long millis);
+
+    //
+    // Wait at most millis plus nanos for this thread to terminate.
+    //
+    void join(long millis, int nanos);
+    
+    //
+    // Set the priority of this thread.
+    //
+    void setPriority(int newPri);
+
+    //
+    // Get the priority of this thread.
+    //
+    int getPriority() const;
+
+    //
+    // Enumerate all threads in this threads group.
+    //
+    static int enumerate(JTCThreadHandle* list, int len);
+
+    enum // Under WIN32 MIN_PRIORITY is already defined in winspool.h
+    {
+	JTC_MIN_PRIORITY  = 0,
+	JTC_NORM_PRIORITY = 1,
+	JTC_MAX_PRIORITY  = 2
+    };
+
+    //
+    // Get a pointer to the current thread object.
+    //
+    static JTCThread* currentThread();
+
+    //
+    // Sleep for millis milliseconds, and nano nanoseconds.
+    //
+    static void sleep(long millis, int nano = 0);
+
+    //
+    // Yield this threads current timeslice.
+    //
+    static void yield();
+
+    //
+    // Determine the number of threads currently running in this
+    // threads ThreadGroup.
+    //
+    static int activeCount();
+
+    //
+    // Get the id of this thread.
+    //
+    JTCThreadId getId() const;
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    //
+    // This function sets a "hook" that is used to initialize custom
+    // POSIX thread attributes. This function is called before every
+    // thread that is created
+    //
+    static void setAttrHook(JTCAttrHook);
+#endif
+
+    //
+    // These two methods are part of the internal thread interface.
+    // They shouldnt be directly called by clients of the JTC
+    // threading package.
+    //
+    void _JTC_startThreadHook();
+    void _JTC_exit();
+
+#ifdef HAVE_JTC_STOP
+    static void _JTC_checkRunningStatus();
+
+    static void _JTC_setMonitor(JTCMonitor* monitor);
+#endif
+};
+
+//
+// Insert operator for the iostream library.
+//
+JTC_STD(ostream)& operator<<(JTC_STD(ostream)& os, const JTCThread& thr);
+
+//
+// Forward declaration
+//
+class JTCTSSManager;
+
+//
+// This class is used to initialize the JTC library.
+//
+class JTCInitialize
+{
+    static int init_; // Number of times the library has been initialized.
+    
+    JTCThreadHandle mainThread_; // The JTC main thread.
+    JTCTSSManager* manager_;
+
+    void initialize();
+    
+public:
+
+    JTCInitialize();
+    JTCInitialize(int&, char**);
+    ~JTCInitialize();
+
+    //
+    // Wait for all running threads to terminate.
+    //
+    void waitTermination();
+
+    //
+    // Determine if JTC has been initialized.
+    //
+    static bool initialized();
+};
+
+//
+// This class is used to incorporate a non-JTC thread into the
+// JThreads/C++ family. If an application wants to use a non-JTC
+// thread with JTC primitives (for instance, if an ORBacus method is
+// called from a non-JTC thread) an instance of this class must be
+// instantiated before using any JTC primitive.
+//
+// What this class actually does is setup a fake
+// JTCThread::currentThread() object, and create another root
+// ThreadGroup.
+//
+class JTCAdoptCurrentThread
+{
+    JTCThreadHandle adoptedThread_; // The JTC adopted thread
+
+public:
+
+    JTCAdoptCurrentThread();
+    ~JTCAdoptCurrentThread();
+};
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/ThreadGroup.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/ThreadGroup.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/ThreadGroup.h	(revision 1017)
@@ -0,0 +1,221 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_THREAD_GROUP_H
+#define JTC_THREAD_GROUP_H
+
+//
+// This class represents a grouping of threads.
+//
+class JTCThreadGroup : public JTCMonitor, public virtual JTCRefCount
+{
+    //
+    // Hide copy constructor and assignment operator.
+    //
+    JTCThreadGroup(const JTCThreadGroup&);
+    void operator=(const JTCThreadGroup&);
+
+    //
+    // This class represents a collection of ThreadGroupHandles.
+    //
+    class JTCThreadGroupSet
+    {
+	//
+        // Hide copy constructor and assignment operator.
+	//
+        JTCThreadGroupSet(const JTCThreadGroupSet&);
+        JTCThreadGroupSet& operator=(const JTCThreadGroupSet&);
+        
+        JTCThreadGroupHandle* handles_; // The set of handles.
+        int len_; // Length of the set.
+
+    public:
+
+        //
+        // Constructor/destructor.
+        //
+        JTCThreadGroupSet() : handles_(0), len_(0) { }
+        ~JTCThreadGroupSet() { delete [] handles_; }
+
+        //
+        // Allocate n members for the set.
+        //
+        void allocate(int n);
+
+        //
+        // How many members in the set.
+        //
+        int length() const;
+
+        //
+        // Return a reference to the ith member of the set.
+        //
+        JTCThreadGroupHandle& operator[](int i);
+    };
+    
+    //
+    // Copy current set of groups.
+    //
+    void createGroupSnapshot(JTCThreadGroupSet& set) const;
+
+    //
+    // Add and remove ThreadGroup.  Add and remove threads.
+    //
+    void add(JTCThreadGroup* g);
+    void remove(JTCThreadGroup* g);
+    void add(JTCThreadHandle t);
+    void remove(JTCThreadHandle t);
+
+    //
+    // Copy current set of threads, and ThreadGroups.
+    //
+    int enumerate(JTCThreadHandle* list, int len, int n, bool recurse) const;
+    int enumerate(JTCThreadGroupHandle* list, int len, int n,
+		  bool recurse) const;
+
+    //
+    // Constructor helper.
+    //
+    void init(JTCThreadGroup* parent, const char* name);
+
+    JTCThreadGroupHandle parent_; // Parent of this ThreadGroup.
+    char* name_; // Name of ThreadGroup.
+    int maxPriority_; // Maximum priority of this ThreadGroup.
+    bool destroyed_; // Has this ThreadGroup been destroyed?
+
+    int nthreads_; // Number of threads in this ThreadGroup.
+    JTCThreadHandle* threads_; // Pointer to each thread in this ThreadGroup.
+    int threadsLength_; // Capacity of the above array.
+
+    int ngroups_; // Number of child ThreadGroups.
+    JTCThreadGroup** groups_; // Pointer to each child ThreadGroup.
+    int groupsLength_; // Capacity of the above array.
+
+    bool daemon_; // Is this a daemon ThreadGroup?
+
+    friend class JTCThread;
+
+    JTCThreadGroup(bool main);
+
+public:
+
+    //
+    // Constructor and destructor.
+    //
+    JTCThreadGroup(const char* name);
+    JTCThreadGroup(JTCThreadGroup* parent, const char* name);
+
+    virtual ~JTCThreadGroup();
+
+    //
+    // Get the name of this ThreadGroup.
+    //
+    const char* getName() const;
+
+    //
+    // Return parent of this ThreadGroup.
+    //
+    JTCThreadGroupHandle getParent() const;
+
+    //
+    // Is this a daemon Threadgroup?
+    //
+    bool isDaemon() const;
+
+    //
+    // Set the daemon status of a ThreadGroup.
+    //
+    void setDaemon(bool daemon);
+
+    //
+    // Called on an uncaught exception.
+    //
+    virtual void uncaughtException(JTCThreadHandle t, const JTCException& e);
+
+    //
+    // Called on an uncaught unknown exception.
+    //
+    virtual void uncaughtException(JTCThreadHandle t);
+
+    //
+    // Get maximum priority of this ThreadGroup.
+    //
+    int getMaxPriority() const;
+
+#ifdef HAVE_JTC_STOP
+    //
+    // Stop, suspend and resume all threads in this ThreadGroup, and child
+    // ThreadGroups.
+    //
+    void stop();
+    void resume();
+    void suspend();
+#endif
+
+    //
+    // Has this ThreadGroup been destroyed?
+    //
+    bool isDestroyed() const;
+
+    //
+    // Destroy this ThreadGroup.
+    //
+    void destroy();
+
+    //
+    // Set maximum priority of threads in this ThreadGroup, and our
+    // child ThreadGroups.
+    //
+    void setMaxPriority(int pri);
+
+    //
+    // Is this ThreadGroup a parent of the argument?
+    //
+    bool parentOf(JTCThreadGroupHandle g);
+
+    //
+    // Number of active threads in this group, and child ThreadGroups.
+    // Number of active ThreadGroups in this group, and child ThreadGroups.
+    //
+    int activeCount() const;
+    int activeGroupCount() const;
+
+    //
+    // Enumerate the set of threads in this ThreadGroup, and child
+    // ThreadGroups, if recurse is true.
+    //
+    int enumerate(JTCThreadHandle* list, int len, bool recurse = true) const;
+
+    //
+    // Enumerate the set of ThreadGroups in this ThreadGroup, and child
+    // ThreadGroups, if recurse is true.
+    //
+    int enumerate(JTCThreadGroupHandle* list, int len,
+		  bool recurse = true) const;
+
+    //
+    // Display the set of threads and child ThreadGroups
+    // in this ThreadGroup to cout.
+    //
+    void list();
+
+    //
+    // Display the set of threads and child ThreadGroups
+    // in this ThreadGroup to stream os, with given indent level.
+    //
+    void list(JTC_STD(ostream)& os, int indent);
+};
+
+//
+// Insert operator for the iostream library.
+//
+JTC_STD(ostream)& operator<<(JTC_STD(ostream)& os, const JTCThreadGroup& g);
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Types.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Types.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/JTC/Types.h	(revision 1017)
@@ -0,0 +1,286 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_TYPES_H
+#define JTC_TYPES_H
+
+//
+// Configuration stuff
+//
+#include <JTC/Config.h>
+
+//
+// If we're in a pthreads environment we want to define _REENTRANT
+//
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+#   ifndef _REENTRANT
+#       define _REENTRANT  1
+#   endif
+#endif
+
+// 
+// Under HP/UX we want to define _CMA_NOWRAPPERS_ to stop read,
+// write and other friends from being redefined to the cma_              
+// versions.
+//                
+#if defined(__hpux)
+#   include <errno.h>
+#   ifndef _CMA_NOWRAPPERS_
+#       define _CMA_NOWRAPPERS_
+#   endif
+#endif
+
+//
+// DLL support
+//
+#ifdef JTC_DLL
+#   ifdef JTC_BUILD_DLL
+#        define JTC_IMPORT /**/
+#   else
+#        define JTC_IMPORT __declspec(dllimport)
+#   endif
+#else
+#   define JTC_IMPORT /**/
+#endif
+
+//
+// Include common header files.
+//
+#ifdef HAVE_IOSTREAM
+#   include <iostream>
+#else
+#   include <iostream.h>
+#endif
+
+#ifdef HAVE_STD_IOSTREAM
+#   define JTC_STD(x) std::x
+#else
+#   define JTC_STD(x) x
+#endif
+
+//
+// Typedef for bool type if bool is not supported.
+//
+#if SIZEOF_BOOL == 0
+#   ifndef HAVE_BOOL_TYPEDEF
+#       define HAVE_BOOL_TYPEDEF
+typedef int bool;
+#       if !defined(true)
+const bool true = 1;
+#       endif
+#       if !defined(false)
+const bool false = 0;
+#       endif
+#   endif
+#endif
+
+#if !defined(HAVE_POSIX_THREADS) && !defined(HAVE_DCE_THREADS) && \
+    !defined(HAVE_WIN32_THREADS)
+#   error Environment must support either POSIX threads or WIN32 threads.
+#endif
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+
+#   include <pthread.h>
+
+//
+// This class represents a thread id under POSIX threads, and DCE
+// threads.
+//
+class JTCThreadId
+{
+    pthread_t id_; // The thread id.
+    bool nullId_; // Is this a null thread id?
+
+public:
+    //
+    // Constuctor.  By default a thread id is a null thread id.
+    //
+    JTCThreadId()
+    	: nullId_(true)
+    {
+    }
+    
+    JTCThreadId(pthread_t id)
+	: id_(id), nullId_(false)
+    {
+    }
+
+    //
+    // Use default copy constructor and assignment operator.
+    //
+
+    //
+    // Equality and inequality.
+    //
+    bool operator!=(const JTCThreadId& rhs) const
+    {
+	return !(*this == rhs);
+    }
+    
+    bool operator==(const JTCThreadId& rhs) const
+    {
+        //
+        // Two thread ids that are not null should use pthread_equal.
+        //
+	if (!nullId_ && !rhs.nullId_)
+	{
+	    return pthread_equal(id_, rhs.id_);
+	}
+        //
+        // If they are both null then they are equal.
+        //
+	else if (nullId_ && rhs.nullId_)
+	{
+	    return true;
+	}
+        //
+        // Else one is null and the other isnt.  Therefore they are
+        // not equal.
+        
+        //
+	//
+	// dont remove this else.  This works around a bug with
+	// the SUN C++ 4.1 compiler.
+	//
+	else return false;
+    }
+
+    //
+    // Return the id of the current thread.
+    //
+    static JTCThreadId self()
+    {
+	return JTCThreadId(pthread_self());
+    }
+
+    //
+    // Conversion operator.
+    //
+    operator pthread_t() const
+    {
+	return id_;
+    }
+    friend JTC_STD(ostream)& operator<<(JTC_STD(ostream)&, const JTCThreadId&);
+};
+
+//
+// IOstream insertion operator. This method is different for various
+// thread packages since the type pthread_t is not specified.
+// Therefore it may not be printable.
+//
+inline JTC_STD(ostream)&
+operator<<(JTC_STD(ostream)& os, const JTCThreadId& id)
+{
+    if (id == JTCThreadId())
+    {
+        os << "NIL";
+    }
+    else
+    {
+#if defined(HAVE_POSIX_THREADS)
+        os << id.id_;
+#endif
+#if defined(HAVE_DCE_THREADS)
+        os << "(" << id.id_.field1
+           << "," << id.id_.field2
+#    if !defined(__alpha)
+           << "," << id.id_.field3
+#endif
+           << ")";
+#endif
+    }
+    return os;
+}
+
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+
+//
+// This class represents a thread id under WIN32.
+//
+class JTCThreadId
+{
+    HANDLE handle_; // Handle to the thread.
+
+public:
+
+    // This field should be private but VC++ 6 doesn't allow this.
+    DWORD threadId_; // The thread id.
+
+    //
+    // Constructor.
+    //
+    JTCThreadId(DWORD threadId = 0, HANDLE handle = 0)
+	: handle_(handle), threadId_(threadId)
+    {
+    }
+
+    //
+    // Use default copy constructor and assignment operator.
+    //
+
+    //
+    // Equality and inequality.
+    //
+    bool operator==(const JTCThreadId& rhs) const
+    {
+	return threadId_ == rhs.threadId_;
+    }
+    
+    bool operator!=(const JTCThreadId& rhs) const
+    {
+	return !(*this == rhs);
+    }
+
+    //
+    // Conversion operator.
+    //
+    operator DWORD() const
+    {
+    	return threadId_;
+    }
+
+    //
+    // Return the id of the current thread.
+    //
+    static JTCThreadId self()
+    {
+	return JTCThreadId(GetCurrentThreadId(), GetCurrentThread());
+    }
+
+//    friend ostream& operator<<(ostream&, const JTCThreadId&);
+    friend class JTCThread;
+};
+
+//
+// IOstream insertion operator.
+//
+inline JTC_STD(ostream)&
+operator<<(JTC_STD(ostream)& os, const JTCThreadId& id)
+{
+    os << id.threadId_;
+    return os;
+}
+
+#endif
+
+//
+// The type JTCThreadKey represents a thread specific storage key.
+//
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+typedef pthread_key_t JTCThreadKey;
+#endif
+#if defined(HAVE_WIN32_THREADS)
+typedef DWORD JTCThreadKey;
+#endif
+
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/License.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/License.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/License.cpp	(revision 1017)
@@ -0,0 +1,2 @@
+// The JThreads/C++ license number
+const char* JTCLicense = "non-commercial";
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Makefile
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Makefile	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Makefile	(revision 1017)
@@ -0,0 +1,84 @@
+#  Makefile for building JTC JThreads/C++ 
+#  Source code from Object Oriented Concepts  www.ooc.com
+#  R. Ansari      LAL-IN2P3/CNRS    
+
+CXX := g++
+ifdef EROSCXX
+  CXX := $(EROSCXX)
+endif
+
+SYSNOM = $(shell echo `uname`)
+SYSCOMPNOM = $(SYSNOM)-$(CXX)
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc) -o $@ $<
+
+$(OBJ)%.o:%.cpp
+	$(COMPILE.cc) -o $@ $<
+
+#  Flag pour compilo DEC-cxx (Compaq)
+ifeq ($(CXX),cxx)
+  CPPFLAGS   :=  -I. -pthread -nopt -distinguish_nested_enums 
+endif
+
+AR = ar
+ARFLAGS = -rcs
+
+LIB = Objs/
+OBJ = Objs/
+
+OBJLIST =  $(OBJ)Cond.o $(OBJ)Event.o $(OBJ)License.o $(OBJ)Monitor.o $(OBJ)Mutex.o $(OBJ)TSS.o $(OBJ)TSSManager.o $(OBJ)Thread.o $(OBJ)ThreadGroup.o $(OBJ)Version.o
+
+SYSLIBS = -lpthread 
+
+# ---------------- Building Library
+all: rep $(LIB)libJTC.a $(LIB)libJTC.so 
+
+rep :
+	if (test ! -d Objs) then mkdir Objs ; fi
+
+$(LIB)libJTC.a : $(OBJLIST)
+	$(AR) $(ARFLAGS) $(LIB)libJTC.a $(OBJLIST) 
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+
+$(LIB)libJTC.so : $(LIB)libJTC.a
+	$(CXX) -shared -o $(LIB)libJTC.so $(OBJLIST) $(SYSLIBS)
+
+# ---------------- Cleaning 
+clean:
+	rm -rf Objs
+
+# --------------- Installing 
+install:
+	if (test ! -d $(JTCBASEREP)/Include) then mkdir $(JTCBASEREP)/Include ; fi
+	if (test ! -d $(JTCBASEREP)/Include/JTC) then mkdir $(JTCBASEREP)/Include/JTC ; fi
+	cp JTC/*.h $(JTCBASEREP)/Include/JTC
+	if (test ! -d $(JTCBASEREP)/$(SYSCOMPNOM)) then mkdir $(JTCBASEREP)/$(SYSCOMPNOM) ; fi
+	if (test ! -d $(JTCBASEREP)/$(SYSCOMPNOM)/Libs)  then mkdir $(JTCBASEREP)/$(SYSCOMPNOM)/Libs ; fi
+	if (test ! -d $(JTCBASEREP)/$(SYSCOMPNOM)/ShLibs)  then mkdir $(JTCBASEREP)/$(SYSCOMPNOM)/ShLibs ; fi
+	cp Objs/libJTC.a $(JTCBASEREP)/$(SYSCOMPNOM)/Libs
+	cp Objs/libJTC.so $(JTCBASEREP)/$(SYSCOMPNOM)/ShLibs
+
+$(OBJ)Cond.o : Cond.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)Event.o : Event.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)License.o : License.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)Monitor.o : Monitor.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)Mutex.o : Mutex.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)TSS.o : TSS.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)TSSManager.o : TSSManager.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)Thread.o : Thread.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)ThreadGroup.o : ThreadGroup.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+$(OBJ)Version.o : Version.cpp
+	$(CXX) $(CPPFLAGS) -c -o $@ $< 
+
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Monitor.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Monitor.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Monitor.cpp	(revision 1017)
@@ -0,0 +1,311 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/Event.h>
+#include <JTC/Cond.h>
+#include <JTC/Monitor.h>
+#include <JTC/Exception.h>
+#include <JTC/Handle.h>
+#include <JTC/HandleI.h>
+#include <JTC/Thread.h>
+#include <JTC/ThreadGroup.h>
+#include <JTC/Runnable.h>
+#include <JTC/Sync.h>
+
+#if defined(HAVE_STRSTREAM)
+#   include <strstream>
+#else
+#   if defined(HAVE_STRSTREA_H)
+#       include <strstrea.h>
+#   else
+#       include <strstream.h>
+#   endif
+#endif
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+#include <stdlib.h>
+
+//
+// Inlining the methods causes problems with CC 7.1 under SGI
+//
+#if defined(__sgi)
+JTCSynchronized::JTCSynchronized(const JTCMonitor& mon)
+    : mon_(&mon), lockType_(LOCKED_MONITOR)
+{
+    mon_ -> lock(false);
+}
+
+JTCSynchronized::JTCSynchronized(const JTCMonitor& mon, bool internal)
+    : mon_(&mon), lockType_(LOCKED_MONITOR)
+{
+    mon_ -> lock(internal);
+}
+
+JTCSynchronized::JTCSynchronized(const JTCMutex& m)
+    : mut_(&m), lockType_(LOCKED_MUTEX)
+{
+    mut_ -> lock();
+}
+
+JTCSynchronized::JTCSynchronized(const JTCRecursiveMutex& m)
+    : nrmut_(&m), lockType_(LOCKED_RECURSIVE_MUTEX)
+{
+    nrmut_ -> lock();
+}
+
+JTCSynchronized::~JTCSynchronized()
+{
+    switch(lockType_)
+    {
+    case LOCKED_MONITOR:
+	mon_ -> unlock();
+	break;
+    case LOCKED_MUTEX:
+	mut_ -> unlock();
+	break;
+    case LOCKED_RECURSIVE_MUTEX:
+	nrmut_ -> unlock();
+	break;
+    }
+}
+
+#endif
+
+// ----------------------------------------------------------------------
+// JTCMonitor private member implementation
+// ----------------------------------------------------------------------
+
+//
+// Verify that the mutex is locked by the calling thread. If the mutex
+// is not locked by the calling thread then throw
+// JTCIllegalMonitorStateException.
+//
+void
+JTCMonitor::validateMutexOwner(const char* caller) const
+{
+    if(monMutex_._JTC_getId() != JTCThreadId::self())
+    {
+	char buf[1024];
+	ostrstream os(buf, 1024);
+	os << "JTCMonitor::"
+	   << caller
+	   << " Thread: "
+           << JTCThreadId::self()
+	   << " doesn't own mutex.  Owner: "
+	   << monMutex_._JTC_getId() << ends;
+	throw JTCIllegalMonitorStateException(buf);
+    }
+}
+
+//
+// Lock the monitors mutex. If internal is set then do not check the
+// running status of the current thread.
+//
+void
+JTCMonitor::lock(bool internal) const
+{
+#ifdef HAVE_JTC_STOP
+    if (!internal)
+    {
+	JTCThread::_JTC_checkRunningStatus();
+    }
+    ((JTCMonitor*)this) -> internalLock_ = internal;
+#endif
+    monMutex_.lock();
+}
+
+//
+// Unlock the monitors mutex. If this was a lock placed by an internal
+// method of the JTC library then do not check the current threads
+// running status.
+//
+void
+JTCMonitor::unlock() const
+{
+#ifdef HAVE_JTC_STOP
+    bool internalLock = internalLock_;
+    
+    monMutex_.unlock();
+    
+    if (!internalLock)
+    {
+	JTCThread::_JTC_checkRunningStatus();
+    }
+#else
+    
+    monMutex_.unlock();
+    
+#endif
+}
+
+// ----------------------------------------------------------------------
+// JTCMonitor constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCMonitor::JTCMonitor()
+    : monCond_(monMutex_)
+#ifdef HAVE_JTC_STOP
+    , internalLock_(false)
+#endif
+{
+}
+
+JTCMonitor::~JTCMonitor()
+{
+}
+
+// ----------------------------------------------------------------------
+// JTCMonitor public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Wait for the monitor to be signalled.
+//
+void
+JTCMonitor::wait()
+{
+#ifdef HAVE_JTC_STOP
+    //
+    // Check the threads running status.
+    //
+    JTCThread::_JTC_checkRunningStatus();
+
+    //
+    // Verify that the monitor is locked by the calling thread.
+    //
+    validateMutexOwner("wait");
+
+    //
+    // Tell the current thread that it is waiting in a monitor.
+    //
+    JTCThread::_JTC_setMonitor(this);
+
+    try
+    {
+	monCond_.wait();
+    }
+    catch(...)
+    {
+        //
+        // The current thread is no longer in a monitor. Check the
+        // running status.
+        //
+	JTCThread::_JTC_setMonitor(0);
+	JTCThread::_JTC_checkRunningStatus();
+	throw;
+    }
+
+    //
+    // The current thread is no longer in a monitor. Check the running
+    // status.
+    //
+    JTCThread::_JTC_setMonitor(0);
+    JTCThread::_JTC_checkRunningStatus();
+#else
+    
+    //
+    // Verify that the monitor is locked by the calling thread.
+    //
+    validateMutexOwner("wait(long)");
+
+    monCond_.wait();
+    
+#endif
+}
+
+//
+// Wait to be signalled for timeout milliseconds.
+//
+void
+JTCMonitor::wait(long timeout)
+{
+#ifdef HAVE_JTC_STOP
+    //
+    // Check the threads running status.
+    //
+    JTCThread::_JTC_checkRunningStatus();
+
+    //
+    // Verify that the monitor is locked by the calling thread.
+    //
+    validateMutexOwner("wait(long)");
+
+    //
+    // Tell the current thread that it is waiting in a monitor.
+    //
+    JTCThread::_JTC_setMonitor(this);
+
+    try
+    {
+	monCond_.wait(timeout);
+    }
+    catch(...)
+    {
+        //
+        // The current thread is no longer in a monitor. Check the
+        // running status.
+        //
+	JTCThread::_JTC_setMonitor(0);
+	JTCThread::_JTC_checkRunningStatus();
+	throw;
+    }
+
+    //
+    // The current thread is no longer in a monitor. Check the running
+    // status.
+    //
+    //
+    JTCThread::_JTC_setMonitor(0);
+    JTCThread::_JTC_checkRunningStatus();
+#else
+
+    //
+    // Verify that the monitor is locked by the calling thread.
+    //
+    validateMutexOwner("wait(long)");
+
+    monCond_.wait(timeout);
+
+#endif
+}
+
+//
+// Wake one waiting thread.
+//
+void
+JTCMonitor::notify()
+{
+    //
+    // Ensure that the monitors mutex is locked by the calling thread.
+    //
+    validateMutexOwner("notify");
+    monCond_.signal();
+}
+
+//
+// Wake all waiting threads.
+//
+void
+JTCMonitor::notifyAll()
+{
+    //
+    // Ensure that the monitors mutex is locked by the calling thread.
+    //
+    validateMutexOwner("notifyAll");
+    monCond_.broadcast();
+}
+
+
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Mutex.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Mutex.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Mutex.cpp	(revision 1017)
@@ -0,0 +1,234 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Exception.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+// ----------------------------------------------------------------------
+// JTCRecursiveMutex private member implementation
+// ----------------------------------------------------------------------
+
+void
+JTCRecursiveMutex::lockI(int count)
+{
+    //
+    // This flag is set to true once the mutex has been obtained.
+    //
+    bool ob = false;
+    while(!ob)
+    {
+        //
+        // Lock the internal mutex.
+        //
+	internal_.lock();
+
+        //
+        // count_ represents the number of times the mutex has been
+        // aquired.  If count_ is zero then the mutex is not yet
+        // aquired.  Note that two mutexes cannot be in here at once,
+        // since this CS is protected by the mutex internal_.
+        //
+	if(!count_)
+	{
+            //
+            // We're attempting to aquire the mutex count more times.
+            //
+	    count_ = count;
+	    owner_ = JTCThreadId::self();
+	    ob = true;
+
+            //
+            // Acquire the mutexes critical section.
+            //
+            try
+	    {
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+		JTC_SYSCALL_1(pthread_mutex_lock, &crit_, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+		EnterCriticalSection(&crit_);
+#endif
+	    }
+	    catch(...)
+	    {
+		try
+		{
+		    internal_.unlock();
+		}
+		catch(...)
+		{
+		}
+		throw;
+	    }
+	}
+        //
+        // Otherwise count_ is non-zero.  This means that the mutex is
+        // currently aquired.  There are two cases here:
+	//
+        // - The mutex is owned by the caller. Simply increment the
+        //   count in this case.
+	//
+        // - The mutex is owned by a thread other than the caller. In
+        //   this case we attempt to aquire the mutexes critical
+        //   section. This CS is unlocked once mutex is released count_
+        //   times.
+        //
+	else if(owner_ == JTCThreadId::self())
+	{
+	    count_ += count;
+	    ob = true;
+	}
+	internal_.unlock();
+
+        //
+        // If we haven't yet obtained the mutex lock the critical
+        // section mutex.  Immediately unlock the CS, then attempt to
+        // re-obtain.
+        //
+	if(!ob)
+	{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+	    JTC_SYSCALL_1(pthread_mutex_lock, &crit_, != 0)
+	    pthread_mutex_unlock(&crit_);
+#endif
+#if defined(HAVE_WIN32_THREADS)
+	    EnterCriticalSection(&crit_);
+	    LeaveCriticalSection(&crit_);
+#endif
+	}
+    }
+}
+
+void
+JTCRecursiveMutex::unlockI()
+{
+    //
+    // Aquire the internal mutex.
+    //
+    internal_.lock();
+
+    //
+    // If count_ decrements to zero then unlock the mutexes CS. The
+    // mutex is no longer owned by a thread.
+    //
+    if(--count_ == 0)
+    {
+	owner_ = JTCThreadId();
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+	pthread_mutex_unlock(&crit_);
+#endif
+#if defined(HAVE_WIN32_THREADS)
+	LeaveCriticalSection(&crit_);
+#endif
+    }
+
+    internal_.unlock();
+}
+
+//
+// Lock the mutex count times.
+//
+void
+JTCRecursiveMutex::lock(int count) const
+{
+    //
+    // Work around lack of mutable.
+    //
+    ((JTCRecursiveMutex*)this) -> lockI(count);
+}
+
+// ----------------------------------------------------------------------
+// JTCRecursiveMutex constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCRecursiveMutex::JTCRecursiveMutex()
+	: count_(0), owner_(JTCThreadId())
+{
+#if defined(HAVE_POSIX_THREADS)
+    JTC_SYSCALL_2(pthread_mutex_init, &crit_, 0, != 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_mutex_init, &crit_, pthread_mutexattr_default, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    InitializeCriticalSection(&crit_);
+#endif
+}
+
+JTCRecursiveMutex::~JTCRecursiveMutex()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_mutex_destroy(&crit_);
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    DeleteCriticalSection(&crit_);
+#endif
+}
+
+// ----------------------------------------------------------------------
+// JTCRecursiveMutex public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Lock the mutex.
+//
+void
+JTCRecursiveMutex::lock() const
+{
+    //
+    // Work around lack of mutable.
+    //
+    ((JTCRecursiveMutex*)this) -> lockI(1);
+}
+
+//
+// Unlock the mutex.
+//
+void
+JTCRecursiveMutex::unlock() const
+{
+    //
+    // Work around lack of mutable.
+    //
+    ((JTCRecursiveMutex*)this) -> unlockI();
+}
+
+//
+// Return the ID of the owning thread. If the mutex isn't locked then
+// return nullThreadId.
+//
+JTCThreadId
+JTCRecursiveMutex::_JTC_getId() const
+{
+    JTCRecursiveMutex* This = (JTCRecursiveMutex*)this;
+    //
+    // Aquire the internal mutex.
+    //
+    This -> internal_.lock();
+    JTCThreadId id;
+    if(count_ > 0)
+        id = owner_;
+    This -> internal_.unlock();
+    
+    return id;
+}
+
+
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSS.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSS.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSS.cpp	(revision 1017)
@@ -0,0 +1,148 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Exception.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/TSS.h>
+
+#include <TSSManager.h>
+
+#include <errno.h>
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+// ----------------------------------------------------------------------
+// JTCTSS public member implementation
+// ----------------------------------------------------------------------
+
+JTCThreadKey
+JTCTSS::allocate()
+{
+    JTCThreadKey key;
+#if defined(HAVE_POSIX_THREADS)
+    JTC_SYSCALL_2(pthread_key_create, &key, 0, != 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_keycreate, &key, 0, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_0(key = TlsAlloc, == 0xFFFFFFFF)
+#endif
+    return key;
+}
+
+JTCThreadKey
+JTCTSS::allocate(void (*cleanup)(void*))
+{
+    JTCThreadKey key;
+#if defined(HAVE_POSIX_THREADS)
+    JTC_SYSCALL_2(pthread_key_create, &key, 0, != 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_keycreate, &key, 0, != 0)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_0(key = TlsAlloc, == 0xFFFFFFFF)
+#endif
+
+    JTCTSSManager::instance() -> allocate(key, cleanup);
+
+    return key;
+}
+
+void
+JTCTSS::release(JTCThreadKey key)
+{
+    //
+    // It's possible that release is called after the JTCTSS Manager
+    // has already been destroyed -- although this is technically
+    // an error, just ignore it.
+    //
+    JTCTSSManager* manager = JTCTSSManager::instance();
+    if(manager != 0)
+	manager -> release(key);
+
+#if defined(HAVE_POSIX_THREADS)
+    JTC_SYSCALL_1(pthread_key_delete, key, != 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+    //
+    // DCE threads doesn't have this operation.
+    //
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_1(TlsFree, key, == 0)
+#endif
+}
+
+void*
+JTCTSS::get(JTCThreadKey key)
+{
+    void* v;
+#if defined(HAVE_POSIX_THREADS)
+    //
+    // FSU Threads has bad definition for pthread_getspecific.
+    //
+#   if defined(HAVE_FSU_THREADS)
+
+    pthread_getspecific(key, &v);
+
+#   else
+
+    v = pthread_getspecific(key);
+
+#   endif
+#endif
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_getspecific, key, &v, != 0);
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    v = TlsGetValue(key);
+#endif
+    return v;
+}
+
+void
+JTCTSS::set(JTCThreadKey key, void* value)
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    try
+    {
+	JTC_SYSCALL_2(pthread_setspecific, key, value, != 0)
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	if(e.getError() == EAGAIN || e.getError() == ENOMEM)
+	{
+	    throw JTCOutOfMemoryError(e.getMessage());
+	}
+	throw;
+    }
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    try
+    {
+	JTC_SYSCALL_2(TlsSetValue, key, value, == 0)
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	if(e.getError() == ERROR_NOT_ENOUGH_MEMORY ||
+	    e.getError() == ERROR_OUTOFMEMORY)
+	{
+	    throw JTCOutOfMemoryError(e.getMessage());
+	}
+	throw;
+    }
+#endif
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSSManager.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSSManager.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSSManager.cpp	(revision 1017)
@@ -0,0 +1,113 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Exception.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/TSS.h>
+
+#include <TSSManager.h>
+
+#include <assert.h>
+
+//
+// Static members
+//
+JTCTSSManager* JTCTSSManager::instance_ = 0;
+
+// ----------------------------------------------------------------------
+// JTCTSSManager constructor/destructor
+// ----------------------------------------------------------------------
+
+JTCTSSManager::JTCTSSManager()
+    : head_(0)
+{
+    assert(instance_ == 0);
+    instance_ = this;
+}
+
+JTCTSSManager::~JTCTSSManager()
+{
+    assert(instance_ != 0);
+    instance_ = 0;
+}
+
+// ----------------------------------------------------------------------
+// JTCTSSManager public member implementation
+// ----------------------------------------------------------------------
+
+JTCTSSManager*
+JTCTSSManager::instance()
+{
+    return instance_;
+}
+
+//
+// Associate a key and a cleanup function
+//
+void
+JTCTSSManager::allocate(JTCThreadKey key, void(*release)(void*))
+{
+    mut_.lock();
+
+    KeyCleanup* node = new KeyCleanup;
+    node -> key = key;
+    node -> release = release;
+    node -> next = head_;
+    head_ = node;
+
+    mut_.unlock();
+}
+
+//
+// Remove the key from our internal table
+//
+void
+JTCTSSManager::release(JTCThreadKey key)
+{
+    mut_.lock();
+
+    KeyCleanup** node = &head_;
+    while(*node != 0)
+    {
+        if((*node) -> key == key)
+            break;
+        node = &(*node) -> next;
+    }
+    if(*node != 0)
+    {
+        KeyCleanup* tmp = *node;
+        *node = (*node) -> next;
+        delete tmp;
+    }
+
+    mut_.unlock();
+}
+
+//
+// Run the cleanup functions
+//
+void
+JTCTSSManager::cleanup()
+{
+    mut_.lock();
+
+    KeyCleanup* node = head_;
+    while(node != 0)
+    {
+        void* data = JTCTSS::get(node -> key);
+        (*node -> release)(data);
+        JTCTSS::set(node -> key, 0);
+        node = node -> next;
+    }
+
+    mut_.unlock();
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSSManager.h
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSSManager.h	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/TSSManager.h	(revision 1017)
@@ -0,0 +1,61 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef JTC_TSS_MANAGER_H
+#define JTC_TSS_MANAGER_H
+
+//
+// This class is needed under WIN32 since there are no native support
+// for thread specific data cleanup. Although POSIX threads have
+// support for associating destructor functions with a thread key they
+// cannot be used. This is because the destructor functions have to
+// run before the thread terminates since any thread joins will occur
+// before the thread terminates.
+//
+class JTCTSSManager
+{
+    struct KeyCleanup
+    {
+        JTCThreadKey key;
+        void (*release)(void*);
+
+        KeyCleanup* next;
+    };
+
+    KeyCleanup* head_; // Head of the cleanup queue
+    JTCMutex mut_;
+
+    static JTCTSSManager* instance_;
+    
+public:
+
+    JTCTSSManager();
+    ~JTCTSSManager();
+
+    //
+    // Get the singleton
+    //
+    static JTCTSSManager* instance();
+
+    //
+    // Associate a key and a cleanup function
+    //
+    void allocate(JTCThreadKey key, void(*)(void*));
+
+    //
+    // Remove the key from our internal table
+    void release(JTCThreadKey);
+
+    //
+    // Run the cleanup functions
+    //
+    void cleanup();
+};
+#endif
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Thread.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Thread.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Thread.cpp	(revision 1017)
@@ -0,0 +1,1597 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/Event.h>
+#include <JTC/Handle.h>
+#include <JTC/HandleI.h>
+#include <JTC/Cond.h>
+#include <JTC/Thread.h>
+#include <JTC/Monitor.h>
+#include <JTC/Sync.h>
+#include <JTC/Exception.h>
+#include <JTC/ThreadGroup.h>
+#include <JTC/TSS.h>
+#include <JTC/Runnable.h>
+
+#include <TSSManager.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+#   ifdef HAVE_SCHED_H
+#       include <sched.h>
+#   else
+#       ifdef HAVE_SYS_SCHED_H
+#           include <sys/sched.h>
+#       endif
+#   endif
+#   include <unistd.h>
+#endif
+
+#if defined(HAVE_POSIX_THREADS)
+#   include <sys/time.h>
+#   include <sys/types.h>
+#endif
+
+#if defined(WIN32)
+#   include <sys/timeb.h>
+#   include <process.h>
+#endif
+
+#if defined(HAVE_EXCEPTION)
+#   include <exception>
+#endif
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+#if defined(HAVE_EXCEPTION_H)
+#   include <exception.h>
+#elif defined(HAVE_UNEXPECTED_H)
+#   include <unexpected.h>
+#endif
+
+#ifdef HAVE_TERMINATE_H
+#   include <terminate.h>
+#endif
+
+#ifndef HAVE_NO_EXPLICIT_TEMPLATES
+template class JTCHandleT<JTCThread>;
+#else
+#  ifdef HAVE_PRAGMA_DEFINE
+#    pragma define(JTCHandleT<JTCThread>)
+#  endif
+#endif
+
+#ifndef HAVE_NO_EXPLICIT_TEMPLATES
+template class JTCHandleT<JTCRunnable>;
+#else
+#  ifdef HAVE_PRAGMA_DEFINE
+#    pragma define(JTCHandleT<JTCRunnable>)
+#  endif
+#endif
+
+//
+// This class keeps track of the number of running threads. When the
+// last JTCInititalize object is destroyed it waits for all running
+// threads to terminate.
+//
+class JTCThreadCounter : public JTCMonitor
+{
+    int threads_;
+public:
+    JTCThreadCounter()
+	: threads_(0)
+    {
+    }
+
+    //
+    // Called when each new thread is started.
+    //
+    void threadStart()
+    {
+	JTCSynchronized guard(*this, true);
+	++threads_;
+    }
+
+    //
+    // Called when each thread is terminated. If there are no more
+    // running threads then notify any threads waiting in waitZero.
+    //
+    void threadEnd()
+    {
+	JTCSynchronized guard(*this, true);
+	--threads_;
+	if(threads_ == 0)
+	{
+	    notify();
+	}
+    }
+
+    //
+    // Wait for all threads to terminate.
+    //
+    void waitZero()
+    {
+	JTCSynchronized guard(*this, true);
+	while(threads_ > 0)
+	{
+	    try
+	    {
+		wait();
+	    }
+	    catch(const JTCInterruptedException&)
+	    {
+	    }
+	}
+    }
+};
+
+//
+// Global instance JTCThreadCounter.
+//
+static JTCThreadCounter* threadCounter = 0;
+
+static size_t initialStackSize = 0;
+
+#if defined(__sgi) && !defined(__GNUC__)
+static long
+_jtc_threadId()
+{
+	return pthread_self();
+}
+#endif
+
+//
+// This is used as a hook from the WIN32 threading library, and the
+// POSIX threading library into JTC. It's better not to use a static
+// member of the JTCThread class since they are not guaranteed to be C
+// callable.
+//
+#ifndef WIN32
+extern "C"
+#else
+static
+#endif
+void*
+_JTC_threadAdapter(void* arg)
+{
+    //
+    // Ensure that unexpected exceptions cause an abort.
+    //
+    set_terminate(abort);
+    set_unexpected(abort);
+
+#if defined(__sgi) && !defined(__GNUC__)
+    //
+    // SGI needs this to handle multiple exceptions in threads.
+    //
+    set_thread_id_function(_jtc_threadId);
+#endif
+
+    //
+    // The arg is a pointer to the JTCThread class.
+    //
+    JTCThread* thr = (JTCThread*)arg;
+    try
+    {
+        //
+        // Invoke the _JTC_startThreadHook.
+        //
+	thr -> _JTC_startThreadHook();
+    }
+    catch(...)
+    {
+    }
+
+    try
+    {
+        //
+        // Call the exit method of the thread.
+        //
+        thr -> _JTC_exit();
+    }
+    catch(...)
+    {
+    }
+
+    //    
+    //
+    // No return value.
+    //
+    return 0;
+}
+
+// ----------------------------------------------------------------------
+// JTCThread private member implementation
+// ----------------------------------------------------------------------
+
+//
+// TSS key. This key is used to store a pointer to the JTCThread
+// object.
+//
+JTCThreadKey JTCThread::thrKey_;
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+JTCAttrHook JTCThread::attrHook_ = 0;
+#endif
+
+#ifdef HAVE_JTC_STOP
+//
+// Check the running status of this thread. This determines whether
+// the thread needs to be suspended, or terminated.
+//
+void
+JTCThread::_checkRunningStatus() const
+{
+    JTCThread* This = (JTCThread*)this;
+    JTCSynchronized guard(resumeMut_);
+
+    //
+    // If this thread is the same as the current thread, and the
+    // thread isn't dead yet then check suspended, and terminated.
+    //
+    if(getId() == JTCThreadId::self() && state_ != JTCThread::Dead)
+    {
+        //
+        // Thread suspended?
+        //
+	if(This -> suspended_)
+	{
+            //
+            // If so then wait for the resume condition variable to be
+            // signalled.
+            //
+	    This -> resumeCond_.wait();
+	}
+
+        //
+        // Thread terminated, but ThreadDeath exception not thrown
+        // yet?
+        //
+	if(This -> terminated_ == terminated)
+	{
+            //
+            // If so note that the ThreadDeath exception has been
+            // thrown, and throw the exception.
+            //
+	    This -> terminated_ = throw_termination;
+	    throw JTCThreadDeath();
+	}
+    }
+}
+
+//
+// Set the monitor of the current thread. This is used for suspend and
+// stop functionality. If the thread currently has a monitor then we
+// need to signal it so that the thread can be terminated in a timely
+// fashion.
+//
+void
+JTCThread::setMonitor(JTCMonitor* monitor)
+{
+    JTCSynchronized guard(monMutex_);
+    monitor_ = monitor;
+}
+
+//
+// Get the monitor of the current thread.
+//
+JTCMonitor*
+JTCThread::getMonitor()
+{
+    JTCSynchronized guard(monMutex_);
+    return monitor_;
+}
+#endif
+
+//
+// IOstream operator for pointer to void function taking a pointer
+// to void.
+//
+/*
+ostream&
+operator<<(ostream& os, void * (fn)(void *))
+{
+    os << (void*)fn;
+    return os;
+}
+*/
+#if defined(HAVE_POSIX_THREADS)
+#define PTHREAD_ATTR_INIT(a) pthread_attr_init(a)
+#define PTHREAD_ATTR_DESTROY(a) pthread_attr_destroy(a)
+#define PTHREAD_CREATE(a,b,c,d)  \
+	JTC_SYSCALL_4(pthread_create, &a, &b, c, d,!= 0)
+#endif
+#if defined(HAVE_DCE_THREADS)
+#define PTHREAD_ATTR_INIT(a) pthread_attr_create(a)
+#define PTHREAD_ATTR_DESTROY(a) pthread_attr_delete(a)
+#define PTHREAD_CREATE(a,b,c,d)  \
+	JTC_SYSCALL_4(pthread_create, &a, b, c, d,!= 0)
+#endif
+
+//
+// Start the thread. The entry point into the JTC library is the C
+// call-style function _JTC_threadAdapter. This in turn calls
+// _JTC_startThreadHook.
+//
+void
+JTCThread::spawnThread()
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    pthread_attr_t attr;
+    try
+    {
+	JTC_SYSCALL_1(PTHREAD_ATTR_INIT, &attr, != 0)
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	if(e.getError() == ENOMEM)
+	{
+	    throw JTCOutOfMemoryError(e.getMessage());
+	}
+	throw;
+    }
+# if defined(_AIX)
+    //
+    // On AIX threads are created by default DETACHED.  This makes
+    // it kinda tough to join with them.  Best change this.
+    //
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
+# endif
+# ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+    if(initialStackSize != 0)
+        pthread_attr_setstacksize(&attr, initialStackSize);
+# endif
+
+    //
+    // Call the custom pthread attribute hook, if defined.
+    //
+    if(attrHook_ != 0)
+	(*attrHook_)(&attr);
+    
+    pthread_t threadId;
+    try
+    {
+	PTHREAD_CREATE(threadId, attr, _JTC_threadAdapter, this)
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	PTHREAD_ATTR_DESTROY(&attr);
+	if(e.getError() == EAGAIN || e.getError() == ENOMEM)
+	{
+	    throw JTCOutOfMemoryError(e.getMessage());
+	}
+	throw;
+    }
+
+    PTHREAD_ATTR_DESTROY(&attr);
+
+    thrId_ = JTCThreadId(threadId);
+#endif
+    
+#if defined(HAVE_WIN32_THREADS)
+    DWORD threadId;
+    HANDLE handle;
+    try
+    {
+	JTC_SYSCALL_6(
+	    handle = (HANDLE)::_beginthreadex,
+	    NULL, initialStackSize,
+            (unsigned (__stdcall*)(void*))_JTC_threadAdapter, (LPVOID)this,
+	    0, (unsigned int*)&threadId, == NULL)
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	if(e.getError() == ERROR_NOT_ENOUGH_MEMORY ||
+	    e.getError() == ERROR_OUTOFMEMORY)
+	{
+	    throw JTCOutOfMemoryError(e.getMessage());
+	}
+	throw;
+    }
+    thrId_ = JTCThreadId(threadId, handle);
+#endif
+
+    //
+    // Wait for the TSS data to be set by the running thread.
+    //
+    setInitialData_.wait();
+}
+
+//
+// Helper for the constructor.
+//
+void
+JTCThread::init(const JTCThreadGroupHandle& group, JTCRunnableHandle target,
+		const char* name)
+{
+    //
+    // Set default values for the thread state flags.
+    //
+    terminated_ = not_terminated;
+#ifdef HAVE_JTC_STOP
+    monitor_ = 0;
+    suspended_ = false;
+#endif
+    name_ = 0;
+    target_ = target;
+    state_ = NewThread;
+    thrId_ = JTCThreadId();
+    ++_jtc_refCount_; // We're referencing outself.  Boost the reference count.
+    adopted_ = false; // The thread was not adopted
+
+    //
+    // Group of 0 means that we inherit the thread group from the creating
+    // thread.
+    //
+    group_ = group;
+    if(group_.get() == 0)
+    {
+	group_ = currentThread() -> getThreadGroup();
+    }
+
+    //
+    // We create the thread on construction. Note that the thread
+    // doesn't invoke run until JTCThread::start is called. We cannot
+    // start the thread until a later point since we need the thread
+    // id one the constructor is called.
+    //
+    spawnThread();
+
+    //
+    // Set the threads name.
+    //
+    setName(name);
+
+    //
+    // Add this thread to the group.
+    //
+    group_ -> add(this);
+}
+
+// ----------------------------------------------------------------------
+// JTCThread private constructor
+// ----------------------------------------------------------------------
+
+//
+// This is called to initialize the JTC thread system.
+//
+JTCThread::JTCThread(JTCThreadId id, bool main)
+    : name_(0),
+#ifdef HAVE_JTC_STOP
+    resumeCond_(resumeMut_),
+#endif
+    joinCond_(joinMut_)
+{
+    //
+    // We need to create the key that contains the current thread
+    // data.
+    //
+    if(main)
+    {
+        thrKey_ = JTCTSS::allocate();
+        adopted_ = false;
+    }
+    else
+        adopted_ = true;
+
+    //
+    // Initialize to default state. Remember that this thread doesn't
+    // need to be spawned since it represents the main thread of the
+    // application.
+    //
+
+    //
+    // Set default values for the thread state variables.
+    //
+#ifdef HAVE_JTC_STOP
+    suspended_ = false;
+    monitor_ = 0;
+#endif
+    terminated_ = not_terminated;
+    thrId_ = id;
+    state_ = JTCThread::Runnable;
+
+    //
+    // Set the TSS data for this thread.
+    //
+    JTCTSS::set(thrKey_, this);
+    setName(0);
+    ++_jtc_refCount_; // We're referencing outself.  Boost the reference count.
+
+    //
+    // Create the default `system' thread group.
+    //
+    group_ = new JTCThreadGroup(main);
+    group_ -> add(this);
+
+    //
+    // The main thread runs at normal priority. This may or may not be
+    // the default for the OS.
+    //
+    setPriority(JTC_NORM_PRIORITY);
+}
+
+// ----------------------------------------------------------------------
+// JTCThread constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCThread::JTCThread(const char* name)
+    :
+#ifdef HAVE_JTC_STOP
+    resumeCond_(resumeMut_),
+#endif
+    joinCond_(joinMut_)
+{
+    init(JTCThreadGroupHandle(0), JTCRunnableHandle(0), name);
+}
+
+JTCThread::JTCThread(JTCRunnableHandle target, const char* name)
+    :
+#ifdef HAVE_JTC_STOP
+    resumeCond_(resumeMut_),
+#endif
+    joinCond_(joinMut_)
+{
+    init(JTCThreadGroupHandle(0), target, name);
+}
+
+JTCThread::JTCThread(JTCThreadGroupHandle& group, const char* name)
+    :
+#ifdef HAVE_JTC_STOP
+    resumeCond_(resumeMut_),
+#endif
+    joinCond_(joinMut_)
+{
+    init(group, JTCRunnableHandle(0), name);
+}
+
+JTCThread::JTCThread(JTCThreadGroupHandle& group, JTCRunnableHandle target,
+		     const char* name)
+    :
+#ifdef HAVE_JTC_STOP
+    resumeCond_(resumeMut_),
+#endif
+    joinCond_(joinMut_)
+{
+    init(group, target, name);
+}
+
+JTCThread::~JTCThread()
+{
+    try
+    {
+        //
+        // The group needs to be defererences *before* the Thread
+        // object is destructed since if the ThreadGroup is
+        // destroyed a synchronization primitive is called
+        // which uses _JTC_checkRunningStatus.  The bad news
+        // is at this point the thread has been destructed.
+        //
+        group_._jtc_deref();
+
+	delete[] name_;
+    }
+    catch(...)
+    {
+    }
+}
+
+// ----------------------------------------------------------------------
+// JTCThread public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Get a handle to this threads ThreadGroup.
+//
+JTCThreadGroupHandle
+JTCThread::getThreadGroup()
+{
+    return group_;
+}
+
+//
+// Set the name of the current thread.
+//
+void
+JTCThread::setName(const char* name)
+{
+    char buf[1024];
+
+    //
+    // 0 means use the default name of the thread. That is
+    // Thread-<THR-ID>
+    //
+    if(name == 0)
+    {
+	ostrstream os(buf, sizeof(buf));
+	os << "Thread-" << thrId_ << ends;
+	name = buf;
+    }
+
+    JTCSynchronized guard(resumeMut_);
+    
+    char* newName = new char[strlen(name) + 1];
+    strcpy(newName, name);
+
+    delete[] name_;
+    name_ = newName;
+}
+
+//
+// Return the name of the thread.
+//
+const char*
+JTCThread::getName() const
+{
+    JTCSynchronized guard(resumeMut_);
+    return name_;
+}
+
+#ifdef HAVE_JTC_STOP
+//
+// Suspend execution of this thread.
+//
+void
+JTCThread::suspend()
+{
+    JTCSynchronized guard(resumeMut_);
+    _checkRunningStatus();
+    if(!suspended_)
+    {
+	suspended_ = true;
+	if(getId() == JTCThreadId::self())
+	{
+	    resumeCond_.wait();
+            _checkRunningStatus();
+	}
+    }
+}
+
+//
+// Resume execution of this thread.
+//
+void
+JTCThread::resume()
+{
+    JTCSynchronized guard(resumeMut_);
+    if(suspended_)
+    {
+	resumeCond_.broadcast();
+	suspended_ = false;
+    }
+}
+
+//
+// Stop execution of this thread.
+//
+void
+JTCThread::stop()
+{
+    JTCMonitor* currentMonitor = 0;
+    {
+	JTCSynchronized guard(resumeMut_);
+
+	//
+	// First check if the thread hasn't already been terminated.
+	//
+	if(terminated_ == not_terminated)
+	{
+	    //
+	    // Mark state as terminated, but ThreadDeath exception not
+	    // yet thrown.
+	    //
+	    terminated_ = terminated;
+
+	    //
+	    // Terminate immediately if the calling thread is stopping
+	    // itself.
+	    //
+	    if(getId() == JTCThreadId::self() && terminated_ == not_terminated)
+	    {
+		terminated_ = throw_termination;
+		throw JTCThreadDeath();
+	    }
+	    //
+	    // these conditions are all mutually exclusive.  the
+	    // thread cannot be stopping itself if it hasn't been
+	    // started. The thread cannot be suspended if it's
+	    // stopping itself, or if it hasn't yet been started.
+	    //
+	    else if(state_ == JTCThread::NewThread)
+	    {
+		//
+		// If the thread hasn't been started yet, then start
+		// it.
+		//
+		startRequest_.post();
+	    }
+	    else if (suspended_)
+	    {
+		resume();
+	    }
+	    else
+	    {
+		currentMonitor = getMonitor();
+	    }
+	}
+    }
+
+    //
+    // If the thread has an associated monitor, then notify to allow
+    // termination in a timely fashion.  Note that this needs to be
+    // notified outside of the resumeMut_ mutex lock.
+    //
+    if(currentMonitor != 0)
+    {
+	JTCSynchronized monGuard(*currentMonitor, true);
+	currentMonitor -> notifyAll();
+    }
+}
+#endif
+
+//
+// Start execution of the thread.
+//
+void
+JTCThread::start()
+{
+    if(state_ != JTCThread::NewThread)
+    {
+	throw JTCIllegalThreadStateException("state is not NewThread");
+    }
+
+    //
+    // State is runnable.
+    //
+    state_ = JTCThread::Runnable;
+
+    //
+    // Tell the thread counter that a new thread has started.
+    // We don't up the running thread count until *after*
+    // start() has been called since we don't want unstarted
+    // threads to block JTCInitialize::~JTCInitialize()
+    //
+    threadCounter -> threadStart();
+
+    startRequest_.post();
+}
+
+//
+// The run method of the thread. If the thread has an associated
+// target (that is the thread has a Runnable object), then invoke it's
+// run method.
+//
+void
+JTCThread::run()
+{
+    if(target_)
+    {
+	target_ -> run();
+    }
+}
+
+//
+// The thread is alive if runnable or not runnable.
+//
+bool
+JTCThread::isAlive() const
+{
+    JTCSynchronized guard(resumeMut_);
+    return  state_ == JTCThread::Runnable || state_ == JTCThread::NotRunnable;
+}
+
+//
+// Wait for termination of this thread.
+//
+void
+JTCThread::join()
+{
+    join(0,0);
+}
+
+static unsigned long
+currentTimeMillis()
+{
+    unsigned long t;
+#ifdef WIN32
+    struct _timeb timebuffer;
+    _ftime(&timebuffer);
+    t = timebuffer.time * 1000;
+    t += timebuffer.millitm;
+#else
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    t = tv.tv_sec * 1000;
+    t += tv.tv_usec/1000;
+#endif
+    return t;
+}
+
+//
+// Wait at most millis milliseconds for termination of this thread.
+//
+void
+JTCThread::join(long millis)
+{
+    if(millis < 0)
+    {
+	throw JTCIllegalArgumentException
+		("timeout value is negative");
+    }
+
+#ifdef HAVE_JTC_STOP
+    _checkRunningStatus();
+#endif
+    
+    unsigned long base = currentTimeMillis();
+    unsigned long now = 0;
+
+    JTCSynchronized guard(joinMut_);
+    
+    if(millis == 0)
+    {
+        while(isAlive())
+        {
+            joinCond_.wait();
+        }
+    }
+    else
+    {
+        while(isAlive())
+        {
+            long delay = millis - now;
+            if(delay <= 0)
+            {
+                break;
+            }
+            joinCond_.wait(delay);
+            now = currentTimeMillis() - base;
+        }
+    }
+
+#ifdef HAVE_JTC_STOP
+    _checkRunningStatus();
+#endif
+}
+
+//
+// Wait at most millis milliseconds plus nanos nanoseconds for termination
+// of this thread.
+//
+void
+JTCThread::join(long millis, int nanos)
+{
+    if(millis < 0)
+    {
+	throw JTCIllegalArgumentException
+		("timeout value is negative");
+    }
+    if(nanos > 999999)
+    {
+	throw JTCIllegalArgumentException
+		("nanosecond timeout out of range");
+    }
+    if(nanos >= 500000 || (nanos != 0 && millis == 0))
+    {
+        ++millis;
+    }
+    join(millis);
+}
+
+static int levelMap[] =
+{
+#if defined(HAVE_DCE_THREADS)
+
+    PRI_OTHER_MIN,
+    ( PRI_OTHER_MIN + PRI_OTHER_MAX + 1 ) / 2,
+    PRI_OTHER_MAX
+
+#elif defined(HAVE_WIN32_THREADS)
+
+    THREAD_PRIORITY_LOWEST,
+    THREAD_PRIORITY_NORMAL,
+    THREAD_PRIORITY_HIGHEST
+
+#else // defined(HAVE_POSIX_THREADS)
+# if defined(__sun) && defined(__SVR4)
+    //
+    // Solaris.
+    //
+    5,
+    3,
+    1
+# elif defined(HAVE_FSU_THREADS)
+    0,
+    1,
+    2
+# elif defined(__linux__)
+    //
+    // Linux has no priorities under LinuxThreads.
+    //
+    0,
+    0,
+    0
+# elif defined(__sgi)
+   -20,
+    0,
+    20
+# elif defined(_AIX)
+    //
+    // AIX doesn't appear to have priorities either.
+    //
+    //PTHREAD_PRIO_MIN,
+    //( PTHREAD_PRIO_MIN + PTHREAD_PRIO_MAX ) / 2,
+    //PTHREAD_PRIO_MAX
+    1,
+    1,
+    1
+# elif defined(__osf__)
+    PRI_OTHER_MIN,
+    ( PRI_OTHER_MIN + PRI_OTHER_MAX + 1 ) / 2,
+    PRI_OTHER_MAX
+#elif defined(__hpux) && defined(HAVE_POSIX_THREADS)
+    //
+    // No thread priorities under HPUX 11.x.
+    //
+    0,
+    0,
+    0
+# else
+#  error "No known priority levels!"
+# endif
+#endif
+};
+
+#if defined(HAVE_FSU_THREADS)
+ostream&
+operator<<(ostream& os, const pthread_attr_t& attr)
+{
+    os << "sched: " << attr.sched << " prio: " << attr.prio;
+    return os;
+}
+#endif
+
+//
+// Set the threads priority.
+//
+void
+JTCThread::setPriority(int newPri)
+{
+    if(newPri < JTC_MIN_PRIORITY || newPri > JTC_MAX_PRIORITY)
+    {
+	throw JTCIllegalArgumentException("priority out of range");
+    }
+    if(newPri > group_ -> getMaxPriority())
+    {
+	newPri = group_ -> getMaxPriority();
+    }
+#if defined(HAVE_POSIX_THREADS)
+#   if defined(HAVE_FSU_THREADS)
+    pthread_attr_t attr;
+    JTC_SYSCALL_2(pthread_getschedattr, thrId_, &attr, != 0);
+    attr.prio = levelMap[newPri];
+    JTC_SYSCALL_2(pthread_setschedattr, thrId_, attr, != 0);
+#   elif !defined(__hpux)
+    sched_param param;
+    int policy = 0;
+    JTC_SYSCALL_3(pthread_getschedparam, thrId_, &policy, &param, != 0)
+    param.sched_priority = levelMap[newPri];
+    JTC_SYSCALL_3(pthread_setschedparam, thrId_, policy, &param, != 0)
+#   endif
+#endif
+#if defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_2(pthread_setprio, thrId_, levelMap[newPri], == -1)
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    JTC_SYSCALL_2(SetThreadPriority, thrId_.handle_, levelMap[newPri],
+		   == 0)
+#endif
+}
+
+//
+// Get the threads priority.
+//
+int
+JTCThread::getPriority() const
+{
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+    int prio;
+# if defined(HAVE_FSU_THREADS)
+    pthread_attr_t attr;
+    JTC_SYSCALL_2(pthread_getschedattr, thrId_, &attr, != 0)
+    prio = attr.prio;
+# elif defined(HAVE_POSIX_THREADS)
+    sched_param param;
+    int policy;
+    JTC_SYSCALL_3(pthread_getschedparam, thrId_, &policy, &param, != 0)
+    prio = param.sched_priority;
+# elif defined(HAVE_DCE_THREADS)
+    JTC_SYSCALL_1(prio = pthread_getprio, thrId_, != 0)
+# endif
+    if(prio <= 0)
+    {
+	return JTC_MIN_PRIORITY;
+    }
+    else if(prio == 1)
+    {
+	return JTC_NORM_PRIORITY;
+    }
+    return JTC_MAX_PRIORITY;
+#endif
+#if defined(HAVE_WIN32_THREADS)
+    DWORD rc;
+    JTC_SYSCALL_1(rc = GetThreadPriority, thrId_.handle_,
+     		   == THREAD_PRIORITY_ERROR_RETURN);
+    switch(rc)
+    {
+	case THREAD_PRIORITY_HIGHEST:
+	case THREAD_PRIORITY_ABOVE_NORMAL:
+	    return JTC_MAX_PRIORITY;
+	case THREAD_PRIORITY_NORMAL:
+	    return JTC_NORM_PRIORITY;
+	case THREAD_PRIORITY_BELOW_NORMAL:
+	case THREAD_PRIORITY_LOWEST:
+	    return JTC_MIN_PRIORITY;
+    }
+    return JTC_NORM_PRIORITY;
+#endif
+}
+
+//
+// Enumerate the set of threads in this group.
+//
+int
+JTCThread::enumerate(JTCThreadHandle* list, int len)
+{
+    return currentThread() -> getThreadGroup() -> enumerate(list, len);
+}
+
+//
+// Get a pointer to the current thread.
+//
+JTCThread*
+JTCThread::currentThread()
+{
+    JTCThread* current = (JTCThread*)JTCTSS::get(JTCThread::thrKey_);
+    if(current == 0)
+        throw JTCUnknownThreadException();
+    return current;
+}
+
+#if defined(HAVE_MIT_THREADS)
+extern "C" { void usleep(unsigned); };
+int
+nanosleep(struct timespec* tv, int)
+{
+	unsigned nsecs = tv -> tv_sec * 1000000;
+	nsecs += tv -> tv_nsec / 1000;
+	usleep(nsecs);
+	return 0;
+}
+#endif
+
+//
+// Put the current thread to sleep for millis millseconds and nano
+// nanoseconds.
+//
+void
+JTCThread::sleep(long millis, int nano)
+{
+#ifdef HAVE_JTC_STOP
+    _JTC_checkRunningStatus();
+#endif
+
+    if(millis < 0)
+    {
+	throw JTCIllegalArgumentException
+		("timeout value is negative");
+    }
+    if(nano > 999999)
+    {
+	throw JTCIllegalArgumentException
+		("nanosecond timeout out of range");
+    }
+
+    //state_ = JTCThread::NotRunnable;
+
+#if defined(HAVE_PTHREAD_DELAY_NP)
+    struct timespec tv;
+    tv.tv_sec = millis/1000;
+    tv.tv_nsec = (millis% 1000)*1000000 + nano;
+    JTC_SYSCALL_1(pthread_delay_np, &tv, != 0);
+    
+#elif defined(HAVE_POSIX_THREADS)
+    
+    struct timespec tv;
+    tv.tv_sec = millis/1000;
+    tv.tv_nsec = (millis% 1000)*1000000 + nano;
+    if(nanosleep(&tv, 0) < 0 && errno == EINTR)
+    {
+	throw JTCInterruptedException();
+    }
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    Sleep(millis);
+#endif
+    //state_ = JTCThread::Runnable;
+
+#ifdef HAVE_JTC_STOP
+    _JTC_checkRunningStatus();
+#endif
+}
+
+//
+// Provide definition for sched_yield under SGI.
+//
+#ifdef __sgi
+extern "C" { int sched_yield(void); };
+#endif
+
+//
+// Yield the current threads timeslice.
+//
+void
+JTCThread::yield()
+{
+#ifdef HAVE_JTC_STOP
+    _JTC_checkRunningStatus();
+#endif
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+# if defined(HAVE_SCHED_YIELD)
+    sched_yield();
+# elif defined(HAVE_PTHREAD_YIELD)
+    pthread_yield();
+# endif
+#endif
+
+#if defined(HAVE_WIN32_THREADS)
+    Yield();
+#endif
+
+#ifdef HAVE_JTC_STOP
+    _JTC_checkRunningStatus();
+#endif
+}
+
+//
+// Return the number of active threads in the current thread group.
+//
+int
+JTCThread::activeCount()
+{
+    return currentThread() -> getThreadGroup() -> activeCount();
+}
+
+//
+// Get the id of this thread. thrId_ is immutable so this method
+// doesn't need to be mutex protected.
+//
+JTCThreadId
+JTCThread::getId() const
+{
+    return thrId_;
+}
+
+#if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
+void
+JTCThread::setAttrHook(JTCAttrHook attrHook)
+{
+    attrHook_ = attrHook;
+}
+#endif
+
+//
+// This method is called by the external "C" calling function used by
+// the native thread package. This is the entrance point from the
+// native thread library into the sane world of JTC.
+//
+void
+JTCThread::_JTC_startThreadHook()
+{
+    //
+    // Flag to indicate that we want to lower the thread counter
+    // at thread termination.
+    //
+    bool lowerCounter = false;
+
+    try
+    {
+        //
+        // Set the TSS data for this thread. This should a pointer to
+        // this thread data.
+        //
+	JTCTSS::set(thrKey_, this);
+
+        setInitialData_.post();
+
+	//cout << "Start: " << name_ << endl;
+        //
+        // Wait for the user to actually `start' the thread.  That is
+        // call the start method for this thread object.
+        //
+	startRequest_.wait();
+
+	//
+	// We want to lower the threadCounter if JTCThread::start()
+	// has been called.
+	//
+	lowerCounter = (state_ != JTCThread::NewThread);
+
+        //
+        // Make sure that the thread didn't `start' because the user
+        // stopped the thread.
+        //
+	if(terminated_ == not_terminated)
+	{
+	    //
+	    // It's not possible to set the priority until after the
+            // start request has been sent, since under WIN32 the handle
+            // may not have been set yet.
+	    //
+	    setPriority(JTC_NORM_PRIORITY);
+
+
+            //
+            // Call the run method of the thread.
+            //
+	    run();
+	}
+    }
+    catch(const JTCThreadDeath&)
+    {
+        //
+        // This exception is thrown when stop() is called.
+        //
+    }
+    catch(const JTCException& e)
+    {
+	group_ -> uncaughtException(this, e);
+    }
+    catch(...)
+    {
+	group_ -> uncaughtException(this);
+    }
+
+#if defined(HAVE_WIN32_THREADS)
+    //
+    // Under WIN32 we must now close the thread handle, or suffer
+    // the consequences.
+    //
+    CloseHandle(thrId_.handle_);
+    thrId_.handle_ = 0;
+#endif
+
+    //
+    // Run the TSS cleanup hooks. The TSSManager should always
+    // be present at this point. Note that the thrKey_ is cleared
+    // out below and not at this point. However, this shouldn't make
+    // any difference since the thrKey_ doesn't have an associated
+    // data destructor.
+    //
+    JTCTSSManager* manager = JTCTSSManager::instance();
+    assert(manager != 0);
+    manager -> cleanup();
+
+    if (lowerCounter)
+    {
+	//
+	// Inform the counter that this thread died.  This has to be
+	// done before _JTC_exit is called since the current thread
+	// object could be deleted if the reference count drops to
+	// zero.
+	//
+	threadCounter -> threadEnd();
+    }
+}
+
+void
+JTCThread::_JTC_exit()
+{
+    {
+        //
+        // Set the state to Dead.  This needs to be done before the
+        // removal from the ThreadGroup since this eventually ends up
+        // calling _checkRunningStatus, which if the state isn't dead
+        // may end up throwing a JTCThreadDeath exception.  We'll keep
+        // the join and internal mutex locked to stop a join from
+        // proceeding until _JTC_exit is completed.  Ensure that
+        // joinMut_ is aquired before resumeMut_ else a race can occur
+        // between isAlive() and join().
+        //
+        JTCSynchronized joinGuard(joinMut_);
+        JTCSynchronized guard(resumeMut_);
+
+        state_ = JTCThread::Dead;
+        joinCond_.broadcast();
+
+	//
+	// Detach the thread, assuming it was not adopted. That is
+	// ensures that the thread resources are freed once the thread
+	// terminates.
+	//
+        if(!adopted_)
+        {
+#if defined(HAVE_DCE_THREADS)
+            pthread_t id = thrId_;
+            JTC_SYSCALL_1(pthread_detach, &id, != 0)
+#elif defined(HAVE_POSIX_THREADS)
+            JTC_SYSCALL_1(pthread_detach, thrId_, != 0)
+#endif
+        }
+
+        //
+        // Remove this thread from its ThreadGroup.
+        //
+        group_ -> remove(this);
+    }
+
+    //
+    // Lower the reference count.
+    //
+    if (--_jtc_refCount_ == 0)
+        delete this;
+
+    //
+    // Clear the current value after the reference count has been
+    // lowered.  This ensures that the currentThread is available in
+    // the thread objects destructor.
+    //
+    JTCTSS::set(thrKey_, 0);
+}
+
+#ifdef HAVE_JTC_STOP
+//
+// Check the running status of the currently active thread.
+//
+void
+JTCThread::_JTC_checkRunningStatus()
+{
+    JTCThreadHandle current((JTCThread*)JTCTSS::get(JTCThread::thrKey_));
+    if (current)
+	current -> _checkRunningStatus();
+}
+
+//
+// Set a monitor for the currently running thread.
+//
+void
+JTCThread::_JTC_setMonitor(JTCMonitor* monitor)
+{
+    JTCThreadHandle current((JTCThread*)JTCTSS::get(JTCThread::thrKey_));
+    if (current)
+	current -> setMonitor(monitor);
+}
+#endif
+
+//
+// IOstream operator for the thread class.
+//
+ostream&
+operator<<(ostream& os, const JTCThread& thr)
+{
+    os << "Thread: " << thr.getName();
+    return os;
+}
+
+//
+// This represents the number of times that the thread has been
+// initialized.
+//
+int JTCInitialize::init_ = 0;
+
+// ----------------------------------------------------------------------
+// JTCThread private member implementation
+// ----------------------------------------------------------------------
+
+void
+JTCInitialize::initialize()
+{
+    manager_ = new JTCTSSManager;
+
+    //
+    // Create ThreadCounter.
+    //
+    threadCounter = new JTCThreadCounter;
+    try
+    {
+        //
+        // Create entry for main thread.
+        //
+	mainThread_ = new JTCThread(JTCThreadId::self(), true);
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	cerr << "JTC failed initialization:\n"
+	     << "\t" << e.getMessage()
+	     << endl;
+	abort();
+    }
+    catch(...)
+    {
+	cerr << "Caught unexpected exception in initialization" << endl;
+	abort();
+    }
+}
+
+// ----------------------------------------------------------------------
+// JTCInitialize constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCInitialize::JTCInitialize()
+{
+    if(init_++ != 0)
+    {
+        return;
+    }
+    initialize();
+}
+
+JTCInitialize::JTCInitialize(int& argc, char** argv)
+{
+    //
+    // Only initialize on first call. Subsequent attempts do nothing.
+    //
+    if(init_++ != 0)
+    {
+	return;
+    }
+
+    int i = 0;
+    while(i < argc)
+    {
+        //
+        // Initial stack size in kilobytes.
+        //
+	if(strcmp(argv[i], "-JTCss") == 0)
+	{
+            int ssTmp;
+	    if(i + 1 < argc)
+		ssTmp = atoi(argv[i + 1]);
+	    else
+	    {
+                cerr << "JTCInitialize:: argument expected for -JTCss" << endl;
+                exit(1);
+	    }
+            if(ssTmp <= 0)
+            {
+                cout << "JTCInitialize:: stack size must be positive." << endl;
+                exit(1);
+            }
+            initialStackSize = ssTmp * 1024;
+	    for(int j = i ; j + 2 <  argc ; j++)
+		argv[j] = argv[j + 2];
+
+	    argc -= 2;
+	}
+	else if(strcmp(argv[i], "-JTCversion") == 0)
+	{
+            extern const char* JTCVersion;
+            cout << JTCVersion << endl;
+
+	    for(int j = i ; j + 1 < argc ; j++)
+		argv[j] = argv[j + 1];
+
+	    argc -= 1;
+	}
+	else if(strcmp(argv[i], "-JTClicense") == 0)
+	{
+            extern const char* JTCLicense;
+            cout << JTCLicense << endl;
+
+	    for(int j = i ; j + 1 < argc ; j++)
+		argv[j] = argv[j + 1];
+
+	    argc -= 1;
+	}
+	else if(strncmp(argv[i], "-JTC", strlen("-JTC")) == 0)
+	{
+            cout << "JTCInitialize:: unknown option: " << argv[i] << endl;
+	    
+	    for(int j = i ; j + 1 < argc ; j++)
+		argv[j] = argv[j + 1];
+	    
+	    argc -= 1;
+	}
+	else
+	{
+	    i++;
+	}
+    }
+    initialize();
+}
+
+JTCInitialize::~JTCInitialize()
+{
+    //
+    // On terminate on last call.
+    //
+    if(--init_ > 0)
+	return;
+
+    //
+    // Wait for all threads to disappear.
+    //
+    threadCounter -> waitZero();
+
+    //
+    // Clean up main thread, and the ThreadCounter.
+    //
+    mainThread_ -> _JTC_exit();
+    delete threadCounter;
+
+    delete manager_;
+}
+
+// ----------------------------------------------------------------------
+// JTCInitialize public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Wait for all running threads to terminate.
+//
+void
+JTCInitialize::waitTermination()
+{
+    threadCounter -> waitZero();
+}
+
+//
+// Determine if the JTC library has been initialized.
+//
+bool
+JTCInitialize::initialized()
+{
+    return init_ > 0;
+}
+
+// ----------------------------------------------------------------------
+// JTCAdoptCurrentThread constructor and destructor
+// ----------------------------------------------------------------------
+
+JTCAdoptCurrentThread::JTCAdoptCurrentThread()
+{
+    try
+    {
+        //
+        // Create entry for adopted thread.
+        //
+	adoptedThread_ = new JTCThread(JTCThreadId::self(), false);
+    }
+    catch(const JTCSystemCallException& e)
+    {
+	    cerr << "JTC failed initialization:\n"
+		 << "\t" << e.getMessage()
+		 << endl;
+	    abort();
+    }
+    catch(...)
+    {
+	    cerr << "Caught unexpected exception in initialization" << endl;
+	    abort();
+    }
+}
+
+JTCAdoptCurrentThread::~JTCAdoptCurrentThread()
+{
+    //
+    // Clean up main thread, and the ThreadCounter.
+    //
+    adoptedThread_ -> _JTC_exit();
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/ThreadGroup.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/ThreadGroup.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/ThreadGroup.cpp	(revision 1017)
@@ -0,0 +1,887 @@
+// **********************************************************************
+//
+// Copyright (c) 2000
+// Object Oriented Concepts, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <JTC/Types.h>
+#include <JTC/Syscall.h>
+#include <JTC/Mutex.h>
+#include <JTC/Handle.h>
+#include <JTC/HandleI.h>
+#include <JTC/Event.h>
+#include <JTC/Cond.h>
+#include <JTC/Monitor.h>
+#include <JTC/Exception.h>
+#include <JTC/Thread.h>
+#include <JTC/ThreadGroup.h>
+#include <JTC/Runnable.h>
+#include <JTC/Sync.h>
+
+#include <string.h>
+
+#ifndef HAVE_NO_EXPLICIT_TEMPLATES
+template class JTCHandleT<JTCThreadGroup>;
+#else
+#  ifdef HAVE_PRAGMA_DEFINE
+#    pragma define(JTCHandleT<JTCThreadGroup>)
+#  endif
+#endif
+
+#ifdef HAVE_STD_IOSTREAM
+using namespace std;
+#endif
+
+// ----------------------------------------------------------------------
+// JTCThreadGroup::JTCThreadGroupSet public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Allocate n members.
+//
+inline void
+JTCThreadGroup::JTCThreadGroupSet::allocate(int n)
+{
+    len_ = n;
+    handles_ = new JTCThreadGroupHandle[n];
+}
+
+//
+// Return the number of elements in the set.
+//
+inline int
+JTCThreadGroup::JTCThreadGroupSet::length() const
+{
+    return len_;
+}
+
+//
+// Return a reference to the i'th element.
+//
+inline JTCThreadGroupHandle&
+JTCThreadGroup::JTCThreadGroupSet::operator[](int i)
+{
+    return handles_[i];
+}
+
+// ----------------------------------------------------------------------
+// JTCThreadGroup private member implementation
+// ----------------------------------------------------------------------
+
+//
+// Create a snapshot of current child ThreadGroups.
+//
+void
+JTCThreadGroup::createGroupSnapshot(JTCThreadGroupSet& set) const
+{
+    set.allocate(ngroups_);
+    for(int i = 0; i < ngroups_; ++i)
+    {
+	set[i] = groups_[i];
+    }
+}
+
+//
+// Add a ThreadGroup to my child list.
+//
+void
+JTCThreadGroup::add(JTCThreadGroup* g)
+{
+    JTCSynchronized sync(*this);
+    if(destroyed_)
+    {
+	throw JTCIllegalThreadStateException();
+    }
+    //
+    // No children yet?
+    //
+    if(groups_ == 0)
+    {
+	groups_ = new JTCThreadGroup*[4];
+	groupsLength_ = 4;
+    }
+    //
+    // Time to grow array?
+    //
+    else if(ngroups_ == groupsLength_)
+    {
+        //
+        // Allocate memory and then copy...  This is more exception
+        // safe.
+        //
+	int newGroupsLength = ngroups_*2;
+	JTCThreadGroup** newGroups = new JTCThreadGroup*[newGroupsLength];
+	for(int i = 0; i < ngroups_; ++i)
+	{
+	    newGroups[i] = groups_[i];
+	}
+        
+	delete[] groups_;
+	groups_ = newGroups;
+	groupsLength_ = newGroupsLength;
+    }
+
+    //
+    // Add the group to the child list.
+    //
+    groups_[ngroups_] = g;
+    ++ngroups_;
+}
+
+//
+// Remove a ThreadGroup from my child list.
+//
+void
+JTCThreadGroup::remove(JTCThreadGroup* g)
+{
+    JTCSynchronized sync(*this);
+    if(destroyed_)
+    {
+	throw JTCIllegalThreadStateException();
+    }
+    
+    for(int i =0 ; i < ngroups_; ++i)
+    {
+	if(groups_[i] == g)
+	{
+	    --ngroups_;
+	    for(int j = i; j < ngroups_; ++j)
+	    {
+		groups_[j] = groups_[j+1];
+	    }
+	    groups_[ngroups_] = 0;
+	}
+    }
+
+    //
+    // If we remove the last thread then notify the ThreadGroups
+    // monitor.
+    //
+    if(nthreads_ == 0)
+    {
+	notifyAll();
+    }
+
+    //
+    // If we've gotten rid of all threads and ThreadGroups then
+    // destroy the ThreadGroup.
+    //
+    if(daemon_ && nthreads_ == 0 && ngroups_ == 0)
+    {
+	destroy();
+    }
+}
+
+//
+// This code is present to deal with internal compilation errors
+// in gcc 2.7.2
+//
+void
+copy_it(JTCThreadHandle* from, int len, JTCThreadHandle* to)
+{
+    for (int i =0; i < len; ++i)
+    {
+        to[i] = from[i];
+    }
+}
+
+void
+delete_it(JTCThreadHandle* it)
+{
+    delete[] it;
+}
+
+//
+// End internal compilation error code
+//
+
+//
+// Add a thread to my thread set.
+//
+void
+JTCThreadGroup::add(JTCThreadHandle t)
+{
+    JTCSynchronized sync(*this);
+
+    if(destroyed_)
+    {
+	throw JTCIllegalThreadStateException();
+    }
+
+
+    //
+    // No threads yet?
+    //
+    if(threads_ == 0)
+    {
+	threads_ = new JTCThreadHandle[4];
+	threadsLength_ = 4;
+    }
+    //
+    // Time to grow the array?
+    //
+    else if(nthreads_ == threadsLength_)
+    {
+
+        //
+        // Allocate and then copy.  This is more exception safe.
+        //
+	int newThreadLength = nthreads_*2;
+	JTCThreadHandle* newThreads = new JTCThreadHandle[newThreadLength];
+
+
+        // This generates an internal error with gcc 2.7.2
+	//for(int i = 0; i < nthreads_; ++i)
+	//{
+	//    newThreads[i] = threads_[i];
+	//}
+        // Use this instead
+        copy_it(threads_, nthreads_, newThreads);
+        //
+        
+        // This generates an internal error with gcc 2.7.2
+	//delete[] threads_;
+        // Use this instead
+        delete_it(threads_);
+        //
+	threads_ = newThreads;
+	threadsLength_ = newThreadLength;
+    }
+    //
+    // Add thread.
+    //
+    threads_[nthreads_] = t;
+    ++nthreads_;
+}
+
+//
+// Remove a thread from my thread set.
+//
+void
+JTCThreadGroup::remove(JTCThreadHandle t)
+{
+    JTCSynchronized sync(*this);
+    if(destroyed_)
+    {
+	throw JTCIllegalThreadStateException();
+    }
+    for(int i = 0; i < nthreads_; ++i)
+    {
+	if(threads_[i] == t)
+	{
+	    --nthreads_;
+	    for(int j = i; j < nthreads_; ++j)
+	    {
+		threads_[j]  = threads_[j+1];
+	    }
+	    threads_[nthreads_] = JTCThreadHandle();
+	}
+    }
+    if(nthreads_ == 0)
+    {
+    	notifyAll();
+    }
+    if(daemon_ && nthreads_ == 0 && ngroups_ == 0)
+    {
+	destroy();
+    }
+}
+
+//
+// TODO:  ensure that exceptions don't cause memory leaks.  Currently
+// exceptions can cause the GroupSnapshot to be trashed.  Some sort
+// of auto_ptr can fix this.
+//
+
+//
+// Copy threads from my thread set into the provided array.
+//
+int
+JTCThreadGroup::enumerate(JTCThreadHandle* list, int len, int n,
+			  bool recurse) const
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+
+	if(destroyed_)
+	{
+	    return 0;
+	}
+
+        //
+        // Copy threads into the provided list.
+        //
+	int nt = nthreads_;
+	if(nt > len - n)
+	{
+	    nt = len - n;
+	}
+	if(nt > 0)
+	{
+	    for(int i = 0; i < nt; ++i)
+	    {
+		    list[i+n] = threads_[i];
+	    }
+	    n += nt;
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    //
+    // Recurse into child ThreadGroups?
+    //
+    if(recurse)
+    {
+	for(int i = 0; i < groupsSnapshot.length(); ++i)
+	{
+	    n = groupsSnapshot[i] -> enumerate(list, len, n, 1);
+	}
+    }
+
+    return n;
+}
+
+//
+// Copy the set of ThreadGroups into the provided array.
+//
+int
+JTCThreadGroup::enumerate(JTCThreadGroupHandle* list, int len, int n,
+			   bool recurse) const
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+
+	if(destroyed_)
+	{
+	    return 0;
+	}
+        
+	int ng = nthreads_;
+	if(ng > len - n)
+	{
+	    ng = len - n;
+	}
+	if(ng > 0)
+	{
+	    for(int i = 0; i < ng; ++i)
+	    {
+		list[i+n] = groups_[i];
+	    }
+	    n += ng;
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    //
+    // Recurse into child ThreadGroups?
+    //
+    if(recurse)
+    {
+	for(int i = 0; i < groupsSnapshot.length(); ++i)
+	{
+	    n = groupsSnapshot[i] -> enumerate(list, len, n, 1);
+	}
+    }
+
+    return n;
+}
+
+//
+// Constructor helper.
+//
+void
+JTCThreadGroup::init(JTCThreadGroup* parent, const char* n)
+{
+    //
+    // Initialize state variables.
+    //
+    ngroups_ = 0;
+    groups_ = 0;
+    groupsLength_ = 0;
+    nthreads_ = 0;
+    threads_ = 0;
+    threadsLength_ = 0;
+    destroyed_ = false;
+    daemon_ = parent -> daemon_;
+
+    //
+    // Copy name.
+    //
+    name_ = new char[strlen(n)+1];
+    strcpy(name_, n);
+    
+    maxPriority_ = parent -> maxPriority_;
+
+    //
+    // Add myself to my parent.
+    //
+    parent_ = parent;
+    parent -> add(this);
+}
+
+// ----------------------------------------------------------------------
+// JTCThreadGroup private constructor
+// ----------------------------------------------------------------------
+
+//
+// This is the constructor that creates the main thread group.
+//
+JTCThreadGroup::JTCThreadGroup(bool main)
+    : parent_(0),
+      destroyed_(false),
+      nthreads_(0),
+      threads_(0),
+      threadsLength_(0),
+      ngroups_(0),
+      groups_(0),
+      groupsLength_(0),
+      daemon_(false)
+{
+    //
+    // Default name of the system ThreadGroup is system, otherwise
+    // the name is adopted.
+    //
+    const char* defaultName = (main) ? "system" : "adopted";
+    name_ = new char[strlen(defaultName)+1];
+    strcpy(name_, defaultName);
+    
+    maxPriority_ = JTCThread::JTC_MAX_PRIORITY;
+}
+
+// ----------------------------------------------------------------------
+// JTCThreadGroup constructors and destructor
+// ----------------------------------------------------------------------
+
+JTCThreadGroup::JTCThreadGroup(const char* name)
+{
+    init(JTCThread::currentThread() -> getThreadGroup().get(), name);
+}
+
+JTCThreadGroup::JTCThreadGroup(JTCThreadGroup* parent, const char* name)
+{
+    init(parent, name);
+}
+
+JTCThreadGroup::~JTCThreadGroup()
+{
+    try
+    {
+        JTCSynchronized sync(*this);
+	if (!destroyed_)
+        {
+	    destroy();
+        }
+    }
+    catch(const JTCIllegalThreadStateException&)
+    {
+	cerr << "Unexpected JTCIllegalThreadStateException in ~JTCThreadGroup"
+	     << endl;
+    }
+    delete[] name_;
+}
+
+// ----------------------------------------------------------------------
+// JTCThreadGroup public member implementation
+// ----------------------------------------------------------------------
+
+//
+// Return name of the this ThreadGroup.
+//
+const char*
+JTCThreadGroup::getName() const
+{
+    return name_;
+}
+
+//
+// Return the parent of this ThreadGroup.
+//
+JTCThreadGroupHandle
+JTCThreadGroup::getParent() const
+{
+    return JTCThreadGroupHandle(parent_);
+}
+
+//
+// Is this a daemon ThreadGroup?
+//
+bool
+JTCThreadGroup::isDaemon() const
+{
+    return daemon_;
+}
+
+//
+// Set the daemon ThreadGroup flag.
+//
+
+void
+JTCThreadGroup::setDaemon(bool daemon)
+{
+    daemon_ = daemon;
+}
+
+//
+// Called on an uncaught exception.
+//
+void
+JTCThreadGroup::uncaughtException(JTCThreadHandle t, const JTCException& e)
+{
+    if (parent_)
+    {
+	parent_ -> uncaughtException(t, e);
+    }
+    else
+    {
+	cerr << e << endl;
+    }
+}
+
+//
+// Called on an uncaught exception (... style)
+//
+void
+JTCThreadGroup::uncaughtException(JTCThreadHandle t)
+{
+    if (parent_)
+    {
+	parent_ -> uncaughtException(t);
+    }
+    else
+    {
+	cerr << "unknown exception" << endl;
+    }
+}
+
+//
+// Return the maximum priority of this ThreadGroup.
+//
+int
+JTCThreadGroup::getMaxPriority() const
+{
+    return maxPriority_;
+}
+
+#ifdef HAVE_JTC_STOP
+//
+// Stop all threads in this ThreadGroup, and child ThreadGroups.
+//
+void
+JTCThreadGroup::stop()
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+
+        //
+        // Stop all of the threads that this ThreadGroup owns.
+        //
+	for (int i = 0; i < nthreads_; ++i)
+	{
+	    threads_[i] -> stop();
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    //
+    // Ask each child ThreadGroup to stop their threads.
+    //
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	groupsSnapshot[i] -> stop();
+    }
+}
+
+//
+// Resume all threads in our ThreadGroup, and child ThreadGroups.
+//
+void
+JTCThreadGroup::resume()
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+        //
+        // Resume all threads in our ThreadGroup.
+        //
+	for (int i = 0; i < nthreads_; ++i)
+	{
+	    threads_[i] -> resume();
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    //
+    // Resume all threads in our child ThreadGroups.
+    //
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	groupsSnapshot[i] -> resume();
+    }
+}
+
+//
+// Suspend all threads in our ThreadGroup, and child ThreadGroups.
+//
+void
+JTCThreadGroup::suspend()
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+
+        //
+        // Suspend all threads in our ThreadGroup.
+        //
+	for (int i = 0; i < nthreads_; ++i)
+	{
+	    threads_[i] -> suspend();
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    //
+    // Suspend all threads in our child ThreadGroups.
+    //
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	groupsSnapshot[i] -> suspend();
+    }
+}
+#endif
+
+//
+// Has this ThreadGroup been destroyed?
+//
+bool
+JTCThreadGroup::isDestroyed() const
+{
+    JTCSynchronized sync(*this);
+    return destroyed_;
+}
+
+//
+// Destroy this ThreadGroup.
+//
+void
+JTCThreadGroup::destroy()
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+	if(destroyed_ || nthreads_ > 0)
+	{
+	    throw JTCIllegalThreadStateException();
+	}
+	createGroupSnapshot(groupsSnapshot);
+
+	destroyed_ = true;
+	ngroups_ = 0;
+	delete[] groups_;
+	groups_ = 0;
+	groupsLength_ = 0;
+	nthreads_ = 0;
+	delete[] threads_;
+	threads_ = 0;
+	threadsLength_ = 0;
+    }
+
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	groupsSnapshot[i] -> destroy();
+    }
+
+    if(parent_)
+    {
+	parent_ -> remove(this);
+    }
+}
+
+//
+// Set maximum priority value for this ThreadGroup, and our child
+// ThreadGroups.
+//
+void
+JTCThreadGroup::setMaxPriority(int pri)
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+	if(pri < JTCThread::JTC_MIN_PRIORITY)
+	{
+	    maxPriority_ = JTCThread::JTC_MIN_PRIORITY;
+	}
+	else if(pri < maxPriority_)
+	{
+	    maxPriority_ = pri;
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	groupsSnapshot[i] -> setMaxPriority(pri);
+    }
+}
+
+//
+// Is this ThreadGroup a parent of handle?
+//
+bool
+JTCThreadGroup::parentOf(JTCThreadGroupHandle handle)
+{
+    JTCThreadGroup* g = handle.get();
+    for(;g != 0; g = g -> parent_.get())
+    {
+	if(g == this)
+	{
+	    return true;
+	}
+    }
+    return false;
+}
+
+//
+// Determine the number of active threads in this ThreadGroup, and
+// child ThreadGroups.
+//
+int
+JTCThreadGroup::activeCount() const
+{
+    int result = 0;
+
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+
+	if(destroyed_)
+	{
+	    return 0;
+	}
+	result = nthreads_;
+
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	result += groupsSnapshot[i] -> activeCount();
+    }
+
+    return result;
+}
+
+//
+// Determine the number of ThreadGroups in this group, and child
+// ThreadGroups.
+//
+int
+JTCThreadGroup::activeGroupCount() const
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+
+	if(destroyed_)
+	{
+	    return 0;
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+
+    int n = groupsSnapshot.length();
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	n += groupsSnapshot[i] -> activeCount();
+    }
+    return n;
+}
+
+//
+// Copy the set of threads in this ThreadGroup, and child ThreadGroups
+// if recurse is true into array list.
+//
+int
+JTCThreadGroup::enumerate(JTCThreadHandle* list, int len, bool recurse) const
+{
+    return enumerate(list, len, 0, recurse);
+}
+
+//
+// Copy the set child ThreadGroups in this ThreadGroup, and child ThreadGroups
+// if recurse is true into array list.
+//
+int
+JTCThreadGroup::enumerate(JTCThreadGroupHandle* list, int len,
+			  bool recurse) const
+{
+    return enumerate(list, len, 0, recurse);
+}
+
+//
+// Display set of threads and ThreadGroups to cout.
+//
+void
+JTCThreadGroup::list()
+{
+    list(cout, 0);
+}
+
+//
+// Display the set of threads and ThreadGroups to os, with given indent
+// level.
+//
+void
+JTCThreadGroup::list(ostream& os, int indent)
+{
+    JTCThreadGroupSet groupsSnapshot;
+
+    {
+	JTCSynchronized sync(*this);
+	for(int j = 0; j < indent; ++j)
+	{
+	    os << " ";
+	}
+	os << *this << endl;
+	indent += 4;
+	for(int i = 0; i < nthreads_; ++i)
+	{
+	    for(int i_level = 0; i_level < indent; ++i_level)
+	    {
+		os << " ";
+	    }
+	    os << *threads_[i] << endl;
+	}
+	createGroupSnapshot(groupsSnapshot);
+    }
+    for(int i = 0; i < groupsSnapshot.length(); ++i)
+    {
+	groupsSnapshot[i] -> list(os, indent);
+    }
+}
+
+//
+// IOstream insertion operator for a ThreadGroup.
+//
+ostream&
+operator<<(ostream& os, const JTCThreadGroup& g)
+{
+    os << "ThreadGroup: "
+       << "[name=" << g.getName() << ",maxpri=" << g.getMaxPriority() << "]";
+    return os; 
+}
Index: /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Version.cpp
===================================================================
--- /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Version.cpp	(revision 1017)
+++ /tags/JTC_V1/SophyaExt/JThreadsC++/JTCSrc/Version.cpp	(revision 1017)
@@ -0,0 +1,2 @@
+// The JThreads/C++ version
+const char* JTCVersion = "1.0.10";
