/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework 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 as in version 2 of the License.

 * 
 * The iWear Framework 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
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWEAR_IWSEMAPHORE_H
#define __IWEAR_IWSEMAPHORE_H

extern "C"
{
#include <semaphore.h>
}

namespace iwear
{
/**
 * This is a simple wrapper for a POSIX semaphore.
 */
class IWSemaphore
{
private:
protected:
    /**
     * The POSIX Semaphore which we wrap.
     */
    sem_t sema;
public:
    /**
     * Constructs a semaphore with initial count of 0, which can optionally be
     * set.
     */
    IWSemaphore( int v = 0);
    /**
     * Destroys the semaphore.
     */
    ~IWSemaphore();
    /**
     * Posts the semaphore, i.e. increases the count on the semaphore.
     */
    int Post( void );
    /**
     * Suspends the current thread until the semaphore count is non-zero. Then
     * it decreases the semaphore count.
     */
    int Wait( void );
    /**
     * Tries to decrease the count. If it works, it returns true, false otherwise.
     */
    int TryWait( void );
    /**
     * Returns the current value of the semaphore.
     */
    int Value( void );
};

inline IWSemaphore::~IWSemaphore( )
{
    sem_destroy(&sema);
}

inline IWSemaphore::IWSemaphore( int v )
{
    sem_init(&sema,0,v);
}

inline int IWSemaphore::Post( void )
{
    return sem_post(&sema);
}

inline int IWSemaphore::Wait( void )
{
    return sem_wait(&sema);
}

inline int IWSemaphore::TryWait( void )
{
    return sem_trywait(&sema);
}

inline int IWSemaphore::Value( void )
{
    int val;
    sem_getvalue(&sema,&val);
    return val;
}

}
#endif
