/****************************************************
 * File: Semaphore.hh
 * Author: Keith Schwarz (htiek@cs.stanford.edu)
 *
 * A class representing a semaphore.  This purpose of
 * this file is to provide a single interface for
 * semaphores that can be backed by one of multiple
 * different implementations depending on what
 * libraries are available on the system.  Ideally,
 * this will support:
 *
 * - C++0x
 * - boost
 * - pthreads
 * - Win32 API
 */

#ifndef Semaphore_Included
#define Semaphore_Included

#include "Lock.hh"
#include <stdlib.h>

namespace synch {
  class Semaphore: public synch::Lock {
  public:
    /**
     * Constructor: Semaphore(size_t permits = 0);
     * -------------------------------------------------
     * Creates a new Semaphore with the specified number
     * of permits.
     */
    explicit Semaphore(size_t permits = 0);
    
    /**
     * Destructor: ~Semaphore();
     * -------------------------------------------------
     * Deallocates all resources associated with the
     * specified Semaphore.  If any threads are blocked
     * on the semaphore, the behavior is undefined.
     */
    ~Semaphore();
    
    /**
     * void lock(size_t numPermits = 1);
     * Usage: semaphore.lock();
     * -------------------------------------------------
     * Acquires the specified number of permits, blocking
     * until they become available.
     */
    void lock(size_t numPermits);
    void lock();
    
    /**
     * void unlock(size_t numPermits = 1);
     * Usage: semaphore.unlock();
     * -------------------------------------------------
     * Releases the specified number of permits
     */
    void unlock(size_t numPermits);
    void unlock();
    
  private:
    /* pImpl idiom to hide the implementation from the client. */
    struct Impl;
    Impl* mImpl;
  };
}
  
#endif
