/*
 *  Semaphore.hpp
 *  Copyright (C) 2001-2003 by Marc Parizeau
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Contact:
 *  Laboratoire de Vision et Systemes Numeriques
 *  Departement de genie electrique et de genie informatique
 *  Universite Laval, Quebec, Canada, G1K 7P4
 *  http://vision.gel.ulaval.ca
 *
 */

#ifndef Threading_Semaphore_hpp_
#define Threading_Semaphore_hpp_

#include "Threading/Mutex.hpp"
#include "Threading/Condition.hpp"

namespace Threading {

   /*! \brief %Semaphore for thread synchronization.
   \author Marc Parizeau

   This class incapsulates a semaphore with classic Semaphore::post, Semaphore::tryWait, and Semaphore::wait methods. The semaphore is initialized with a count of \c inMaxCount ressources. A post increments the count while a wait decrements it. A count of 0 means that no more ressources are available. Subsequent calls to wait will block until future post releases some of the allocated ressources. When several threads have blocked because of exhausted ressources, the order in which they will be released is undetermined (FIFO should not be assumed).
   */
   class Semaphore : public Condition
   {
   public:
      Semaphore(unsigned int inMaxCount) : mCount(inMaxCount) {}
      ~Semaphore(void) {}

      //! Return count of semaphore (semaphore should be locked prior to call).
      int getCount(void) const {return mCount;}
      void post(void);
      //! Set count of semaphore (semaphore should be locked prior to call).
      void setCount(unsigned int inCount) {mCount = inCount;}
      bool tryWait(void);
      void wait(void);
   
   protected:
      int mCount; //!< Count of semaphore
   };

}

#endif // MT_Semaphore_hpp_
