
                               ZTHREADS 1.5.0
                               by Eric Crahen 
                           <crahen@cs.buffalo.edu>
                        http://zthread.sourceforge.net

LICENSE:				

	This source has been released under the LGPL. See LGPL.TXT for
  details regarding the liscense.


OVERVIEW:

    Concurrency has become an increasingly important aspect of software today. 
  The ZThread package is an advanced object-oriented, cross-platform, C++ 
  threading and synchronization library that has been designed and implemented 
  by the author and released under the GPL. It provides a high level 
  abstraction of the native threading mechanisms to offer a great deal of 
  flexibility and control. 

    This software features interruptible Thread and Runnable objects for C++, 
  control objects and implementations of concurrency design patterns. This 
  includes semaphores, mutexes, condition variabes as well as other more 
  complex components.

    Existing threading APIs do not provide a consistent means for exercising 
  asynchronous control over software. Thread cancellation and termination is 
  one example of this complexity. ZThreads includes an elegant method of 
  safely terminating threads without the complications of using cancellation 
  handlers or other similar constructs. 

    This is a platform independent architecture that was designed by the 
  author. Implementations have been provided for POSIX and Win32 platforms. 
  Building this library was quite different for POSIX than it was for Win32 
  due to the nature of the functionality each platform naturally provides; 
  each platform had strong and weak points. They were used to create the most 
  flexible and efficent abstraction possible. 

    The result is an excellent software layer on which to build mutlithreaded 
  code. 

COMPILING:

    On Win32 builds, there is a ZTHREAD_STATIC define that should be defined 
  if you are using the static version of the library. If this define
  is omited then the shared version is assumed.

    On POSIX builds your should define _POSIX. The binaries are a little
  'smarter' than the Win32 ones and the compiler will be able to decide
  without any help which version (static or shared) you are using.

    GNU Pth can be used more easily now. If its compiled with pthread 
  emulation you can use the --with-pthread option to select it.


CUSTOMIZING YOUR COMPILATION:

    Priorities, debug-mode & the I/O interrupt mechanism can all be enabled
  or disabled in your compilation by making the appropriate defines. The
  autoconf toold available to unix platforms make this very easy. The same
  can be done for a Win32 compilation, but you will have to setup your
  projects by hand to make these defines.  

    An m4 macro file is included to help build projects with autoconf that
  use ZThreads. It defines the standard --with-zthreads-xxx= type configure
  switches that you see with alot of autoconf-friendly libraries.


DISTRIBUTION:
  
    If you package ZThreads with your application, that fine with me. You can
  do it in binary form or source form. Don't forget to mention somewhere in
  your documents the LGPL & the credits for the library.

    In the case of development or source release it would be nice if you 
  pointed the other developers to the source distribution of this library.
  This keeps things a little more centralized & current; as well as giving
  this library a little more exposure.
  
   If you find this library useful, or you release something that uses it, 
  please let me know. I'd be curious to see how people have made use of
  this library.

NOTES:

   Beta gcc compilers have problems with this library in some cases. Its
  error free on any stable compiler. (2.96 in RH 7.1 is a common source
  of this problem)

HISTORY:

  So far, this library has been tested on Linux, Tru64 Unix, Win98, WinNT,
  Win2k, SunOS, Solaris and FreeBSD. 

---------------------------------------------------------------------------

                              SUMMARY OF USE

---------------------------------------------------------------------------

THREAD LOCALS:
 
    The ThreadLocal variables have recently been enchanced. They provide
  more functionality as well as flexibility and are still very fast. These
  variables should _always_ be static. It makes the most sense this way.
  Check the documentation for further details.
  
WORKING WITH STATIC OBJECTS:

    The ZThreads library will clean up all reference and detached threads
  when the main() function exits. This is done in a static destructor within
  the library. Because of the nature of C compilers, one can not predict the
  order of destruction (the order in which static objects destructors are 
  invoked)   

    This leads to two common pitfalls. One is deadlock in static destructors
  because of unpredictable destruction order. The other is static constructor
  errors, because of static objects trying to use ZThreads resources before
  the library has initilized.

    Because of this, one should avoid actions like joining a thread from 
  within a static destructor of your own (an extended Execute class for
  instance) This can lead to errors if the ZThreads objects are destroyed
  before your static objects. There is a method for obtaining the behavior
  originally desired, however.

STATIC THREADS & EXECUTORS:

    To avoid this error two solutions are available. One is that you can
  set a thread that is used in a static object to be a daemon thread. This
  thread will be joined by ZThreads when the library is unloaded (very
  much like detached thread operate). This allows you to write an object
  that will not require the join() in the static destructor.

    This first solution and best solution to using a static Thread or 
  Executor is make use of the new setDaemon() functon on Threads/creation
  flag on Executors. This allows the threads resource to be reclaimed in such
  a way as to allow for safe static deconstruction. Threads or Executors
  must be static if you enable this flag. You need to be aware of your objects 
  lifetime if you use these options. See the setDaemon() function for details

    The second solution is to make use of the atexit() function. This is
  garunteed to be called *before* any static objects have thier destructors
  invoked. Therefore, it will safely execute before ZThreads is destroyed.
  In some cases, this may require making use of dynamic rather than static
  allocation so that you can be certain your synchronization objects are 
  destroyed in your psuedo-destructor (the atexit() function) rather than in
  an unpredicatble destructor.

EXTENDING THREADS FOR STATIC USE:

    In order to properly extend a thread based object that is intended to
  be static there are just a few things to keep in mind.

  -  Mark the thread as a daemon, creating a garuntee it will be 
     join()ed  *before*  its destructor is called.

  -  If a daemon thread uses its setNotify() method, it will recieve an 
     interrupt() before the system waits for it to be join()ed.

     This provides an important signal to an object so that it has some
     chance to clean up & exit before its join()ed. If these threads
     did not recieve an interrupt then there would be great potential for
     deadlock.

  -  Make sure the resources used by that thread are either members of  
     the thread, or are somehow garunteed to live as long as, or outlive 
     your object.

    Consider the Timer object. It depends on its resource being canceled 
  before it can exit. If its thread were simply marked as a daemon it would
  join() with the main thread before its destructor executed. However, that
  resource would not be cancel()ed (unless the user has done so before the 
  program terminates - but this can be akward with static objects). So the
  Thread's task pays attention to its interruption status; exiting if its
  interrupted, allowing the thread to join when the program exits.

    A rule of thumb to use is basically daemon threads should belong to
  static objects and static objects should have daemon thread members.

STATIC CONSTRUCTORS:

    Static objects should avoid starting threads as much as possible within
  thier constructors. This is because it is possible for that static object
  to be initialized before the ZThreads static objects are initialized. This
  can lead to subtle problems. While I have not expirenced this on a unix
  platform it has occured on several type of Win32 systems.

    The best solution for this is to create a start() method of some kind for
  your object. This way, once main() enters and begins executing all your 
  static initialization (and the static initialization from other libraries)
  is complete. Its safe then to start using those objects. Again, check the 
  Timer class for a simple example of this

KILLING THREADS:

    Recently, the effect of kill()ing a thread has been changed for this
  library. Previously, it relied on the native thread killing mechanism. This
  has several disadvantages. For one, it almost always leaves your system in
  an undesired state. You can not recover nicely from that malfunctioning
  state. Your task had no chance to respond to being killed.

    As of 1.3.4 I have changed the effect of the kill function to improve this
  situation. Killing a thread now has the effect of unblocking any blocked
  thread, without marking the thread as interrupted. In addition, after being 
  killed, any attempt to use a synchronization object that might block the 
  thread will result in an Unexpected_Exception being thrown; preventing any 
  furthur blocking of that thread. This should allow user code to clean up as
  the exceptions are caught, and the kill() function can be used without as 
  much fear.
  

INTERRUPTING I/O:

    A very usful mechanism is included for creating libraries that use 
  ZThreads while perfoming some possibly lengthly I/O. It allows the user
  to write functions that use read(), connect() etc, so that they can 
  abort waiting for those functions to complete if an interrupt() is 
  invoked. The POSIX system uses a signal based mechanism to accomplish
  this. The Win32 system uses an event object to do the same. See the 
  XXX_ThreadImpl sources for further information & examples.

    Unless you choose to disable it in your build it will automatically be
  invoked any time a thread is kill()ed or interrupt()ed.

PRIORITIES:

    Preliminary support for priorities has been added. By default its disabled 
  for POSIX. 



