/****************************************************************************

  module      : OMS_VersionDirRegions.hpp

  -------------------------------------------------------------------------

  responsible : MarkusSi

  special area: OMS 
  description : OMS regions for the version directory

  first created: 2003-09-18  

  -------------------------------------------------------------------------




    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end



*****************************************************************************/



#ifndef OMS_VERSION_DIR_REGIONS_HPP
#define OMS_VERSION_DIR_REGIONS_HPP

#include "Oms/OMS_Defines.h"


//////////////////////////////////////////////////////////////////////////
// Class: ExclusiveVersionDirRgn                                        //
//////////////////////////////////////////////////////////////////////////
/*!
 * \brief Exclusive lock scope.
 *
 * Use this class to protect a critical section with exclusive write access.
 */
class ExclusiveVersionDirRgn {
public:
  /// Locks exclusively the specified lock.
  ExclusiveVersionDirRgn(int lockId, bool useRWLocks);
  
  /// Locks exclusively all entries in the specified array.
  /*! Locks exclusively all entries in the specified array.
  ** \param pLockId    [in] array with the ids of the locks
  ** \param size       [in] number of lock-ids in the array pLockId
  ** \param useRWLocks [in] true: use reader-writer locks; false: use 'normal' regions
  ** 
  ** \attention To prevent deadlocks it must be ensured, that the ids are stored 
  ** in ascending order in the the array pLockId. If the entries are not ascending,
  ** then an exception is thrown.
  */
  ExclusiveVersionDirRgn(const int *pLockId, int size, bool useRWLocks);

  /// Unlock the previously aquired lock(s).
  ~ExclusiveVersionDirRgn();

private:
  /// Flag whether to use use reader-writer locks (true) or normal regions (false)
  bool m_useRWLocks; 
  /// Number of locks which should be hold while being in this 'region'
  int  m_size;       
  /// Array with the ids of the locks which should be hold while being in this 'region'
  int  m_pLockId[OMS_VDIR_SIZE]; 

  /// Returns the offset of the ids of the lock
  /*! Logically the ids of the locks always start with the id 0, but because of other
  **  other lock this is not always possible. Therefore the offset returned by this
  **  function is always added to the logical id. This offset will in general be
  **  different for the two methods and these constants are defined in gco001.h
  */
  inline int GetVDirStartCnt() const
  { return m_useRWLocks ? OMS_VDIR_RW_START_CNT : OMS_VDIR_CS_START_CNT; }
};


//////////////////////////////////////////////////////////////////////////
// Class: SharedVersionDirRgn                                           //
//////////////////////////////////////////////////////////////////////////
/*!
 * \brief Shared lock scope.
 *
 * Use this class to protect a critical section with shared read-only access.
 */
class SharedVersionDirRgn {
public:
  /// Aquire a shared lock on the specified id.
  SharedVersionDirRgn(int lockId, bool useRWLocks);
  
  /// Aquire a shared lock on all the specified ids in the array.
  /*! Aquire a shared lock on all the specified ids in the array.
  ** \param pLockId    [in] array with the ids of the locks
  ** \param size       [in] number of lock-ids in the array pLockId
  ** \param useRWLocks [in] true: use reader-writer locks; false: use 'normal' regions
  ** 
  ** \attention To prevent deadlocks it must be ensured, that the ids are stored 
  ** in ascending order in the the array pLockId. If the entries are not ascending,
  ** then an exception is thrown.
  */
  SharedVersionDirRgn(const int *pLockId, int size, bool useRWLocks);

  /// Unlock the previously aquired lock(s).
  ~SharedVersionDirRgn();

private:
  /// Flag whether to use use reader-writer locks (true) or normal regions (false)
  bool m_useRWLocks;
  /// Number of locks which should be hold while being in this 'region'
  int  m_size;
  /// Array with the ids of the locks which should be hold while being in this 'region'
  int  m_pLockId[OMS_VDIR_SIZE];

  /// Returns the offset of the ids of the lock
  /*! Logically the ids of the locks always start with the id 0, but because of other
  **  other lock this is not always possible. Therefore the offset returned by this
  **  function is always added to the logical id. This offset will in general be
  **  different for the two methods and these constants are defined in gco001.h
  */
  inline int GetVDirStartCnt() const
  { return m_useRWLocks ? OMS_VDIR_RW_START_CNT : OMS_VDIR_CS_START_CNT; }
};

#endif  // OMS_VERSION_DIR_REGIONS_HPP