#if   !defined(__THREAD_HPP)
#define  __THREAD_HPP

/*
  CoreLinux++ 
  Copyright (C) 1999,2000 CoreLinux Consortium
  
   The CoreLinux++ Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CoreLinux++ Library Library is distributed in the hope that it will 
   be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
*/

#if !defined IN_COMMON_HPP
   #error Thread.hpp is included by Common.hpp only.
#endif

#if   !defined(__SINGLETON_HPP)
#include <Singleton.hpp>
#endif

#if   !defined(__MAP_HPP)
#include <Map.hpp>
#endif

#if   !defined(__INVALIDTHREADEXCEPTION_HPP)
#include <InvalidThreadException.hpp>
#endif

namespace   corelinux
{
   DECLARE_CLASS( ThreadContext );

   CORELINUX_MAP
      ( 
         ThreadIdentifier, 
         ThreadContextPtr, 
         std::less<ThreadIdentifier>,
	 ThreadMap
      );

   //
   // Start of class declaration
   //

   DECLARE_CLASS( Thread );
   DECLARE_TYPE( Singleton<Thread>, ThreadManager );

   /**
   Thread is a framework for the creation, management, and destruction
   of caller threads. It accomplishes this by allowing the caller to
   setup a context for execution and calling their defined entry point.
   There is still much work to be done such as:<p>
   <ul>
   <li> Thread completion notification and processing
   <li> Signal handling and masking
   <li> Subject/Observer relationships
   <li> Instrumentation
   <li> Testing...testing...testing!
   </ul>
   */

   class Thread : public Synchronized
   {
   public:

      //
      // Constructors and destructor
      //

                        /// Default constructor

                        Thread( void ) throw( Assertion );

                        /// Virtual destructor

      virtual           ~Thread( void );

      //
      // Operator overloads
      //

      //
      // Accessors (class)
      //

               /**
               getKernelError returns the thread instance errno for
               the last kernel call the thread made
               @return Int errno for thread function
               */

      static   Int      getKernelError( void );

               /**
               getThreadIdentifier retrieves the kernel process id
               for the caller thread
               @return ThreadIdentifier identifies the caller
               */

      static   ThreadIdentifier  getThreadIdentifier( void );

               /**
               getParentThreadIdentifier retrieves the parent thread
               of the current thread.
               @return ThreadIdentifier identifies the parent
               */

      static   ThreadIdentifier  getParentThreadIdentifier( void );

               /**
               getThreadManagerIdentifier retrieves the thread that
               Thread was instantiated from
               @return ThreadIdentifier identifies the owner
               */

      static   ThreadIdentifierCref getThreadManagerIdentifier( void );

               /**
               Retrieve a ThreadContext given a identifier
               @param ThreadIdentifier unique id
               @return ThreadContext const reference
               @exception InvalidThreadException if
               it does not exist.
               */

      static   ThreadContextCref getThreadContext( ThreadIdentifierCref )
                  throw ( InvalidThreadException ) ;


               /**
               Retrieve the number of created threads 
               @return Count number of active threads
               */

      static   Count getCreatedThreadCount( void );

               /**
               Retrieve the number of threads that are starting or running
               @return Count number of active threads
               */

      static   Count getActiveThreadCount( void );

               /**
               Retrieve the number of threads that are waiting ro tun
               @return Count number of active threads
               */

      static   Count getBlockedThreadCount( void );

               /**
               Retrieve the number of threads that are not starting or
               running or waiting to run.
               @return Count number of completed threads
               */

      static   Count getCompletedThreadCount( void );

               /// Debugging method for the moment

      static   void dump( void );

      //
      // Mutators
      //

               /**
               Start a thread as described by the context
               @param ThreadContext reference to thread context
               object. This object is copied into a managed
               context.
               @return ThreadIdentifier identifies the process/thread
               id as assigned by the operating system.
               */

      static   ThreadIdentifier  startThread( ThreadContextRef ) ;
                  
               /**
               Blocks the caller until the thread has ended execution,
               retrieving the return code from the associated thread
               context
               @param ThreadIdentifier unique thread id
               @return Int return code from thread context
               @exception InvalidThreadException if not a valid
               thread identifier.
               */

      static   Int   waitForThread( ThreadIdentifierCref ) 
                  throw ( InvalidThreadException );

               /**
               Destroys the managed context for the given identifier
               @param ThreadIdentifier unique thread id
               @exception InvalidThreadException if the thread id is
               not one in the managed store.
               @exception Assertion if the thread is in a running
               state.
               */

      static   void     destroyThreadContext( ThreadIdentifierCref )
                  throw ( InvalidThreadException, Assertion );

               /**
               Get thread priority for the given indentifier
               @param ThreadIdentifier unique thread id
               @exception InvalidThreadException if the thread id is
               not one in the managed store.
               @exception Assertion if the thread is in a running
               state.
               */

      static   Int      getThreadPriority( ThreadIdentifierCref )
                  throw ( InvalidThreadException, Assertion );

               /**
               Set thread priority for the given indentifier
               @param ThreadIdentifier unique thread id
               @param prio priority value
               @exception InvalidThreadException if the thread id is
               not one in the managed store.
               @exception Assertion if the thread is in a running
               state.
               */

      static   void     setThreadPriority( ThreadIdentifierCref, Int )
                  throw ( InvalidThreadException, Assertion );

   protected:

      //
      // Constructor
      //
                           /**
                           Copy constructor won't do, its a singleton
                           @param Thread reference to another Thread
                           @exception Assertion NEVER_GET_HERE
                           */

                           Thread( ThreadCref ) throw ( Assertion );

      //
      // Operator overloads
      //

               /**
               Assignment operator won't do, we should never get here
               anyway but the compiler will generate the missing method.
               @param Thread reference to another Thread
               @return Thread reference to self
               @exception Assertion NEVER_GET_HERE
               */

               ThreadRef   operator=( ThreadCref ) throw ( Assertion );

               /**
               Equality operator not valid for class utility
               @param Thread reference to Thread
               @return bool True if equal
               @exception Assertion NEVER_GET_HERE
               */

               bool operator==( ThreadCref ) const throw ( Assertion ) ;

      //
      // Thread terminate
      //

      static   void  threadTerminated( Int, VoidPtr, VoidPtr );

   protected:

               /// The singleton instance of Thread for synchronization

      static   ThreadManager  theThreadManager;

   private:

               /// Associative map of ThreadContexts by id

      static   ThreadMap               theThreadMap;

      static   ThreadIdentifier        theThreadManagerId;
      static   Count                   theThreadCount;
   };

}

#endif // if !defined(__THREAD_HPP)

/*
   Common rcs information do not modify
   $Author: dulimart $
   $Revision: 1.5 $
   $Date: 2001/03/20 04:06:50 $
   $Locker:  $
*/

