#if   !defined(__EVENTSEMAPHORE_HPP)
#define  __EVENTSEMAPHORE_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( EventSemaphore );

   /**
      EventSemaphore implements a way to queue its caller until a certain
      event takes place.
   */

   class EventSemaphore : public Semaphore
   {
   public:

      //
      // Constructors and destructors
      //

                  /**
                      Default constructor requires the identifier of the
                      semaphore in the semaphore group
                      @param aGroup pointer to the owning SemaphoreGroup 
                      @param aIdentifier The identifier for the
                      Semaphore from the SemaphoreGroup
                      @param aLimit the maximum number of listeners.
                         @arg aLimit < 0 : infinite number of listeners,
                         @arg aLimit >= 0 : finite number of listeners
                      @param Recursive true if recursion enabled
                      @param Balking true if balking enabled
                  */
                       
               EventSemaphore
                  ( 
                     SemaphoreGroupPtr aGroup,
                     SemaphoreIdentifierRef aIdentifier,
                     Counter aLimit,
                     bool aRecursionFlag = true,
                     bool aBalkingFlag = false
                  ) throw ( NullPointerException );

               /// Virtual Destructor
     
      virtual  ~EventSemaphore( void );

      //
      // Accessors
      //

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

      //
      // Mutators
      //

               /**
                  Indicate owner commitment to trigger the event
                  after a finite amount of time.
               */
               SemaphoreOperationStatus post( void )
                  throw( SemaphoreException );

               /** 
                  Wait for the event associated with this semaphore to
                  take place. Block if the event has not occured
               */ 
      
      virtual  SemaphoreOperationStatus lockWithWait( void ) 
                  throw( SemaphoreException );

               /**
                  Check if the associated event has taken place.
               */      

      virtual  SemaphoreOperationStatus lockWithNoWait( void )
                  throw( SemaphoreException );

               /// Request the semaphore but timeout if not available
      
//      virtual  SemaphoreOperationStatus   lockWithTimeOut( Timer )
//                   throw(SemaphoreException) = 0;
      
               /// Signal the observer that an event has occured.
      
      virtual  SemaphoreOperationStatus release( void ) 
                  throw( SemaphoreException );
      
               /** 
                  Set the maximum number of listeners allowed on this
                  semaphore.
                  @param aLimit the maximum number of listeners.
                     @arg aLimit < 0: infinite number of listeners,
                     @arg aLimit >= 0: finite number of listeners,
               */

      virtual  void setLimit ( Counter aLimit ) throw ( SemaphoreException );

               /** 
                  Get the maximum number of listeners of this semaphore.
               */

      virtual  Counter getLimit ( void ) const;

   protected:

      //
      // Constructors
      //
               /// Default constructor throws assert

               EventSemaphore( void ) throw( Assertion );

               /// Copy constructor throws assertion

               EventSemaphore( EventSemaphoreCref ) throw( Assertion );

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

               EventSemaphoreRef operator=( EventSemaphoreCref ) 
                  throw( Assertion );

   private:

      /// # of threads which are currently listening to this event

      Counter   theNumListeners; 

      ///   Max number of allowed listeners

      Counter   theMaxListeners;
   };

}

#endif // if !defined(__EVENTSEMAPHORE_HPP)

/*
   Common rcs information do not modify
   $Author: dulimart $
   $Revision: 1.7 $
   $Date: 2000/11/15 22:32:06 $
   $Locker:  $
*/


