#if   !defined(__EVENTSEMAPHOREGROUP_HPP)
#define __EVENTSEMAPHOREGROUP_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(__SEMAPHOREGROUP_HPP)
#include <SemaphoreGroup.hpp>
#endif

namespace corelinux
{
   DECLARE_CLASS( EventSemaphoreGroup );

   /**
   A EventSemaphoreGroup is an extension to the SemaphoreGroup for creating
   only EventSemaphore types. Default behavior for creating semaphores via
   the SemaphoreGroup interface is to create a Event and autolock it.
   There is no option for not autolocking it.
   */

   class EventSemaphoreGroup : public SemaphoreGroup
   {
   public:
               /**
                  Default constructor creates a private group semaphores
                  with access for OWNER_ALL. Maximum limit of listeners
                  will be set to "infinity"
                  @param aSemCount Number of semaphores in group
                  @param aRightSet access control for group 
                  @exception Assertion if aSemCount < 1 
                  @exception SemaphoreException if kernel group create
                  call fails.  
                  @see AccessRights
               */
                                       
               EventSemaphoreGroup
                  ( 
                     Short aSemCount, 
                     Int aRightSet = OWNER_ALL 
                  ) throw(Assertion,SemaphoreException);

               /**
                  Constructor to open or create a semaphore group with a
                  specific identifier. Maximum limit of listeners will
                  be set to "infinity".
                  @param  aSemCount Number of semaphores in group, this
                  only has meaning used if failOnExist = true
                  @param aGID valid group identifier either through a
                  system call or via another ipc mechanism
                  @param aRightSet Specifies access control for group 
                  @param dist indicates how to treat the conditions that
                  the group may meet in the request:
                     @arg CREATE_OR_REUSE indicates that the caller doesn't
                     care
                     @arg FAIL_IF_EXISTS indicates the attempt was for a
                     create
                     @arg FAIL_IF_NOTEXISTS indicates the attempt was for a
                     open 
                  @exception Assertion if aCount < 1 
                  @exception SemaphoreException for described states
               */

               EventSemaphoreGroup
                  (
                     Short aSemCount,
                     SemaphoreGroupIdentifierCref aGID,
                     Int aRightSet,
                     CreateDisposition disp=FAIL_IF_EXISTS
                  ) throw(Assertion,SemaphoreException);

               /**
                  Constructor to open or create a semaphore group by
                  name.  Maximum limit of listeners is set to "infinity"

                  @param  aSemCount Short Number of semaphores in group,
                  this only has meaning used if failOnExist = true
                  @param aName pointer to Group name
                  @param aRightSet specifies access control for group 
                  @param disp indicates how to treat the conditions that
                  the group may meet in the request:
                     @arg CREATE_OR_REUSE indicates that the caller doesn't
                     care 
                     @arg FAIL_IF_EXISTS indicates the attempt was for a
                     create
                     @arg FAIL_IF_NOTEXISTS indicates the attempt was for a
                     open 
                  @exception Assertion if aCount < 1 or aCount > system
                  defined maximum for group 
                  @exception SemaphoreException for described states
               */

               EventSemaphoreGroup
                  (
                     Short aSemCount,
                     CharCptr aName,
                     Int aRightSet,
                     CreateDisposition disp=FAIL_IF_EXISTS
                  ) throw(Assertion,SemaphoreException);


               /// Virtual destructor

      virtual  ~EventSemaphoreGroup( void );

                     //
                     // Accessors
                     //

                     //
                     // Factory methods
                     //

               /**
                  Create a default EventSemaphore
                  @return AbstractSemaphore aSem - pointer to created
                  semaphore 
                  @exception SemaphoreException if no sems left in group
               */
                  
      virtual  AbstractSemaphorePtr createSemaphore( void )
                  throw( SemaphoreException ) ;

               /**
                  Create an EventSemaphore and set the maximum number of
                  listeners allowed on this semaphore.
                  @param aLimit maximum number of listeners 
                  @return AbstractSemaphore aSem - pointer to created
                  semaphore
                  @exception SemaphoreException if no sems left in group
               */

      virtual  AbstractSemaphorePtr createSemaphore( Counter aLimit )
                  throw( SemaphoreException ) ;

               /**
                  Create or open (use) a specific EventSemphore 
                  @param aIdentifier identifies which semphore id to
                  create or attempt to use
                  @param disp indicates how to treat the conditions that
                  the group may meet in the request:
                     @arg CREATE_OR_REUSE indicates that the caller doesn't
                     care 
                     @arg FAIL_IF_EXISTS indicates the attempt was for a
                     create
                     @arg FAIL_IF_NOTEXISTS indicates the attempt was for a
                     open 
                  @param Recursive to allow same thread multiple locks 
                  @param Recursive allow lock to recurse
                  @param Balking to allow the semaphore to balk
                  @return AbstractSemaphore aSem - pointer to created or
                  opened semaphore
                  @exception SemaphoreException if the disposition
                  disagrees with the semaphore state, or if it is a
                  erroneous identifier
               */

      virtual  AbstractSemaphorePtr createSemaphore
                  ( 
                     SemaphoreIdentifierRef aIdentifier,
                     CreateDisposition disp = CREATE_OR_REUSE,
                     bool Recursive = false, 
                     bool Balking = false 
                  ) throw( SemaphoreException ) ;

               /**
                  Create or open (use) a specific EventSemphore and set
                  the maximum number of listeners to the specified
                  count.

                  @param aIdentifier identifies which semphore id to
                  create or attempt to use
                  @param aLimit maximum number of listeners for
                  EventSemaphore 
                  @param disp indicates how to treat the conditions that
                  the group may meet in the request:
                     @arg CREATE_OR_REUSE indicates that the caller doesn't
                     care 
                     @arg FAIL_IF_EXISTS indicates the attempt was for a
                     create
                     @arg FAIL_IF_NOTEXISTS indicates the attempt was for a
                     open 
                  @param Recursive to allow same thread multiple locks 
                  @param Balking to allow the semaphore to balk
                  @return AbstractSemaphore aSem - pointer to created or
                  opened semaphore
                  @exception SemaphoreException if the disposition
                  disagrees with the semaphore state, or if it is a
                  erroneous identifier
               */

      virtual  AbstractSemaphorePtr createSemaphore
                  ( 
                     SemaphoreIdentifierRef aIdentifier,
                     Counter aLimit, 
                     CreateDisposition disp = CREATE_OR_REUSE,
                     bool Recursive = false, 
                     bool Balking = false 
                  ) throw( SemaphoreException );

               /**
                  Create or open (use) a specific EventSemaphore
                  identified by its name
                  @param aName identifies which semphore id to create or
                  attempt to use
                  @param disp indicates how to treat the conditions that
                  the group may meet in the request:
                     @arg CREATE_OR_REUSE indicates that the caller doesn't
                     care 
                     @arg FAIL_IF_EXISTS indicates the attempt was for a
                     create
                     @arg FAIL_IF_NOTEXISTS indicates the attempt was for a
                     open 
                  @param Recursive to allow same thread multiple locks 
                  @param Balking to allow the semaphore to balk
                  @return AbstractSemaphore aSem - pointer to created or
                  opened semaphore
                  @exception SemaphoreException if the disposition
                  disagrees with the semaphore state, or if it is a
                  erroneous identifier
               */

      virtual  AbstractSemaphorePtr createSemaphore
                  ( 
                     std::string aName,
                     CreateDisposition disp = CREATE_OR_REUSE,
                     bool Recursive=false, 
                     bool Balking = false 
                  ) throw( SemaphoreException ) ;

               /**
                  Create or open (use) a specific EventSemaphore @param
                  aName identifies which semphore id to create or
                  attempt to use
                  @param aLimit maximum number of listeners for
                  EventSemaphore
                  @param disp indicates how to treat the conditions that
                  the group may meet in the request: 
                     @arg CREATE_OR_REUSE indicates that the caller doesn't
                     care 
                     @arg FAIL_IF_EXISTS indicates the attempt was for a
                     create
                     @arg FAIL_IF_NOTEXISTS indicates the attempt was for a
                     open 
                  @param Recursive to allow same thread multiple locks 
                  @param Balking to allow the semaphore to balk
                  @return AbstractSemaphore aSem - pointer to created or
                  opened semaphore
                  @exception SemaphoreException if the disposition
                  disagrees with the semaphore state, or if it is a
                  erroneous identifier
               */

      virtual  AbstractSemaphorePtr createSemaphore
                  (
                     std::string aName,
                     Counter aLimit, 
                     CreateDisposition disp = CREATE_OR_REUSE,
                     bool Recursive=false, 
                     bool Balking = false 
                  ) throw( SemaphoreException ) ;


               /**
                  Destroys a previously created EventSemaphore 
                  @param aPtr pointer of semaphore to destroy 
                  @exception SemaphoreException if semaphore does not
                  belong to this group or if already destroyed.
               */

      virtual  void  destroySemaphore( AbstractSemaphorePtr aPtr )
                        throw( SemaphoreException ) ;

   protected:

      //
      // Constructors
      //
               /// Default constructor not allowed

               EventSemaphoreGroup( void ) throw( Assertion );

               /// Copy constructor not allowed

               EventSemaphoreGroup( EventSemaphoreGroupCref ) 
                  throw( Assertion );

      //
      // Operator overloadings
      //

               // Assignment operator not allowed

               EventSemaphoreGroupRef operator=( EventSemaphoreGroupCref )
                  throw( Assertion );

      //
      // EventGroup methods
      //

               // Protected method for resolving event between CSA and local

               AbstractSemaphorePtr resolveSemaphore
                  (
                     SemaphoreIdentifierRef  aIdentifier,
                     Short                   aSemId,
                     CreateDisposition       aDisp,
                     bool                    aRecurse, 
                     bool                    aBalk,
                     Counter                 aMaxValue = 1
                  ) throw( SemaphoreException ) ;

   private:

      /// Local share counts

      SemaphoreShares   theUsedMap;

   };
}

#endif // if !defined(__EVENTSEMAPHOREGROUP_HPP)

/*
   Common rcs information do not modify
   $Author: dulimart $
   $Revision: 1.6 $
   $Date: 2000/11/13 15:20:25 $
   $Locker:  $
*/


