#if   !defined(__MUTEXSEMAPHORE_HPP)
#define  __MUTEXSEMAPHORE_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(__COMMON_HPP)
#include <Common.hpp>
#endif

#if   !defined(__SEMAPHORE_HPP)
#include <Semaphore.hpp>
#endif

namespace corelinux
{
   DECLARE_CLASS( MutexSemaphore );

   /**
   MutexSemaphore implements a mutual exclusion control which can
   be used to insure that at most one (1) task has access at
   a time.
   
   The semantics for Recursion:
   The thread that is successful is obtaining the lock will be regarded
   as theOwningThreadIdentifier. If, upon a lock request, it is determined
   that the same thread that owns the lock is asking to lock again, 
   theRecursionQueueLength will be incremented. It is thereafter neccessary
   for theOwningThread to release the semaphore until 
   theRecursionQueueLength returns to zero (0). All other callers will block
   or not based on their lock call disposition.
   */

   class MutexSemaphore : public Semaphore
   {
   public:

      //
      // Constructors and destructors
      //

                        /**
                        Default constructor requires the identifier
                        of the semaphore in the semaphore group
                        @param SemaphoreGroup pointer to the owning
                        SemaphoreGroup 
                        @param SemaphoreIdentifier The identifier
                        for the Semaphore from the SemaphoreGroup
                        @param bool true if autolock on creation
                        @param bool true if recursion enabled
                        @param bool true if balking enabled
                        */
                  
                        MutexSemaphore
                           ( 
                              SemaphoreGroupPtr,
                              SemaphoreIdentifierRef,
                              bool AutoLock = false,
                              bool Recursive = true,
                              bool Balking = false
                           ) throw ( NullPointerException );

                        /// Virtual Destructor

      virtual           ~MutexSemaphore( void );

      //
      // Accessors
      //

               /// Ask if semaphore instance is locked
      
      virtual  bool isLocked( void ) ;

      //
      // Mutators
      //

               /// Request the semaphore, wait for availability
      
      virtual  SemaphoreOperationStatus lockWithWait( void ) 
                        throw(SemaphoreException);

               /// Request the semaphore without waiting
      
      virtual  SemaphoreOperationStatus lockWithNoWait( void )
                        throw(SemaphoreException);

               /// Request the semaphore but timeout if not available
      
//      virtual  SemaphoreOperationStatus   lockWithTimeOut( Timer )
//                   throw(SemaphoreException) = 0;
      
               /// Release the semaphore if owner
      
      virtual  SemaphoreOperationStatus release( void ) 
                        throw(SemaphoreException);


   protected:

      //
      // Constructors
      //
                           /// Default construct throws assert

                           MutexSemaphore( void ) throw( Assertion );

                           /// Copy constructor throws assertion

                           MutexSemaphore( MutexSemaphoreCref ) 
                              throw( Assertion );

      //
      // Operator overloads
      //
               /// Assignment operator throws assertion

               MutexSemaphoreRef operator=( MutexSemaphoreCref ) 
                              throw( Assertion );

   private:

   };

}

#endif // if !defined(__MUTEXSEMAPHORE_HPP)

/*
   Common rcs information do not modify
   $Author: frankc $
   $Revision: 1.2 $
   $Date: 2000/06/02 11:51:52 $
   $Locker:  $
*/


