#if   !defined(__GATEWAYSEMAPHOREGROUP_HPP)
#define __GATEWAYSEMAPHOREGROUP_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( GatewaySemaphoreGroup );

   /**
   A GatewaySemaphoreGroup is an extension to the SemaphoreGroup for creating
   only GatewaySemaphore types. Default behavior for creating semaphores via
   the SemaphoreGroup interface is to create a Gateway and initialize it to
   a count of two (2) Use the createCountSemaphore(...) interface to 
   accomplish initializing the GatewaySemaphore to a count > 2.
   */

   class GatewaySemaphoreGroup : public SemaphoreGroup
   {
   public:

                        /**
                        Default constructor creates a private group 
                        semaphores with access for OWNER_ALL
                        @param Short Number of semaphores in group
                        @param AccessRights Specifies access control for 
                        group
                        @exception Assertion if aCount < 1 
                        @exception SemaphoreException if kernel group 
                        create call fails.
                        @see AccessRights
                        */
                        
                        GatewaySemaphoreGroup( Short, Int Rights = OWNER_ALL ) 
                           throw(Assertion,SemaphoreException);

                        /**
                        Constructor to open or create a semaphore group with
                        a specific identifier.
                        @param  Short Number of semaphores in group,
                        this only has meaning used if failOnExist = true
                        @param SemaphoreGroupIdentifier valid group 
                        identifier either through a system call or via 
                        another ipc mechanism
                        @param AccessRights Specifies access control for 
                        group
                        @param CreateDisposition indicates how to treat the 
                        conditions that the group may meet in the request:
                        <br>
                        CREATE_OR_REUSE indicates that the caller doesn't care
                        <br>
                        FAIL_IF_EXISTS indicates the attempt was for a create
                        <br>
                        FAIL_IF_NOTEXISTS indicates the attempt was for a open
                        @exception Assertion if aCount < 1 
                        @exception SemaphoreException for described states
                        */

                        GatewaySemaphoreGroup
                           ( 
                              Short,
                              SemaphoreGroupIdentifierCref, 
                              Int ,
                              CreateDisposition disp=FAIL_IF_EXISTS
                           ) throw(Assertion,SemaphoreException);

                        /**
                        Constructor to open or create a semaphore group by
                        name.
                        @param  Short Number of semaphores in group,
                        this only has meaning used if failOnExist = true
                        @param Char pointer to Group name
                        @param AccessRights Specifies access control for 
                        group
                        @param CreateDisposition indicates how to treat the 
                        conditions that the group may meet in the request:
                        CREATE_OR_REUSE indicates that the caller doesn't care
                        FAIL_IF_EXISTS indicates the attempt was for a create
                        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
                        */

                        GatewaySemaphoreGroup
                           ( 
                              Short,
                              CharCptr aName, 
                              Int ,
                              CreateDisposition disp=FAIL_IF_EXISTS
                           ) throw(Assertion,SemaphoreException);


                        /// Virtual destructor

      virtual           ~GatewaySemaphoreGroup( void );

      //
      // Accessors
      //

      //
      // Factory methods
      //

               /**
               Create a default GatewaySemaphore
               @return AbstractSemaphore aSem - pointer to created semaphore
               @exception SemaphoreException if no sems left in group
               */

      virtual  AbstractSemaphorePtr createSemaphore( void )
                                       throw( SemaphoreException ) ;

               /**
               Create a count GatewaySemaphore
               @param Count initializing count for GatewaySemaphore
               @return AbstractSemaphore aSem - pointer to created semaphore
               @exception SemaphoreException if no sems left in group
               */

      virtual  AbstractSemaphorePtr createCountSemaphore( Count aCount )
                                       throw( SemaphoreException ) ;

               /**
               Create or open (use) a specific GatewaySemphore 
               @param SemaphoreIdentifier identifies which semphore id to
               create or attempt to use
               @param CreateDisposition indicates how to treat the conditions
               that the group may meet in the request:
               CREATE_OR_REUSE indicates that the caller doesn't care
               FAIL_IF_EXISTS indicates the attempt was for a create
               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,
                                    CreateDisposition disp = CREATE_OR_REUSE,
                                    bool Recursive = false, 
                                    bool Balking = false 
                                 ) throw( SemaphoreException ) ;

               /**
               Create or open (use) a specific GatewaySemphore and have it
               automatically initialized to the specified count.
               @param SemaphoreIdentifier identifies which semphore id to
               create or attempt to use
               @param Count initializing count for GatewaySemaphore
               @param CreateDisposition indicates how to treat the conditions
               that the group may meet in the request:
               CREATE_OR_REUSE indicates that the caller doesn't care
               FAIL_IF_EXISTS indicates the attempt was for a create
               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 createCountSemaphore
                                 ( 
                                    SemaphoreIdentifierRef aIdentifier,
                                    Count aCount, 
                                    CreateDisposition disp = CREATE_OR_REUSE,
                                    bool Recursive = false, 
                                    bool Balking = false 
                                 ) throw( SemaphoreException ) ;
               /**
               Create or open (use) a specific GatewaySemphore 
               @param string identifies which semphore id to create or 
               attempt to use
               @param CreateDisposition indicates how to treat the conditions
               that the group may meet in the request:
               CREATE_OR_REUSE indicates that the caller doesn't care
               FAIL_IF_EXISTS indicates the attempt was for a create
               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 ) ;


               /**
               Destroys a created GatewaySemaphore 
               @note Reference counting is not enabled so applications
               should ensure that only one (1) destroy is called per
               semaphore.
               @param AbstractSemaphore pointer of semaphore to destroy
               @exception SemaphoreException if semaphore does not belong
               to this group or if already destroyed.
               */

      virtual  void  destroySemaphore( AbstractSemaphorePtr )
                        throw( SemaphoreException ) ;
   protected:

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

                        GatewaySemaphoreGroup( void ) throw( Assertion );

                        /// Copy constructor not allowed

                        GatewaySemaphoreGroup( GatewaySemaphoreGroupCref )
                           throw( Assertion );

      //
      // Operator overloads
      //

               /// Assignment operator not allowed

               GatewaySemaphoreGroupRef operator=( GatewaySemaphoreGroupCref )
                                    throw( Assertion );

      //
      // GatewayGroup methods
      //

               /// Protected method for resolving mutex between CSA and local

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

   private:

               /// Local share counts

               SemaphoreShares   theUsedMap;

   };
}

#endif // if !defined(__GATEWAYSEMAPHOREGROUP_HPP)

/*
   Common rcs information do not modify
   $Author: frankc $
   $Revision: 1.4 $
   $Date: 2000/06/04 22:16:32 $
   $Locker:  $
*/


