// Semaphore.h V0.1pre - Provides class Semaphore (Binary & Counting) member
functions
// © 2003 Elliot
Nierman
// Semaphore( )
// Default Constructor, instantiates a binary semaphore with an initial
// count of one, and as binary semaphores go, a maximum count of one
Semaphore::Semaphore()
{
#ifdef WIN
sem = CreateSemaphore(NULL,
1, 1, NULL);
#endif
#ifdef POSIX
p_sem = semget (IPC_PRIVATE,
1, (IPC_CREAT | IPC_EXCL | 0400));
options.val = 1;
count = 1;
semctl(p_sem, 0, SETVAL, options);
#endif
}
// Semaphore( long initial_count )
// Overloaded constructor. initializes a semaphore with an initial count
// as well as a maximum count indicated by initial_count. If initial_count
// is zero, then a semaphore with an initial count of zero with a maximum
// count of one is instantiated(Binary Semaphore)
Semaphore::Semaphore(long initial_count)
{
#ifdef WIN
if(initial_count != 0)
sem
= CreateSemaphore(NULL, initial_count, initial_count, NULL);
else
sem
= CreateSemaphore(NULL, 0, 1, NULL);
#endif
#ifdef POSIX
p_sem = semget (IPC_PRIVATE,
1, (IPC_CREAT | IPC_EXCL | 0400));
options.val = initial_count;
if (initial_count != 0)
count
= initial_count;
else
count
= 1;
semctl(p_sem, 0, SETVAL, options);
#endif
}
// Semaphore(long initial_count, long max_count
// Overloaded constructor which creates a semaphore with an initial
// count specified by initial_count and a maximum count specified
// by max_count
Semaphore::Semaphore(long initial_count, long max_count)
{
#ifdef WIN
sem = CreateSemaphore(NULL,
initial_count, max_count, NULL);
#endif
#ifdef POSIX
p_sem = semget (IPC_PRIVATE, 1, (IPC_CREAT | IPC_EXCL | 0400));
options.val = initial_count;
count = max_count;
count = 1;
semctl(p_sem, 0, SETVAL, options);
#endif
}
// Post( )
// If the integer count associated with the semaphore is less than
// the specified maximum count, the count is incremented by one
void Semaphore::Post()
{
#ifdef WIN
ReleaseSemaphore(sem, 1, NULL);
#endif
#ifdef POSIX
if (semctl(p_sem, 0, GETVAL,
0) < count)
{
action.sem_num
= 0;
action.sem_op
= 1;
action.sem_flg
= 0;
semop(p_sem,
&action, 1);
}
#endif
}
// Wait()
// If Semaphore count is non-zero the thread decrements the count and continues
// execution, otherwise the thread is blocked until the count becomes non-zero.
void Semaphore::Wait()
{
#ifdef WIN
WaitForSingleObject(sem,INFINITE);
#endif
#ifdef POSIX
action.sem_num = 0;
action.sem_op = -1;
action.sem_flg = 0;
semop (p_sem, &action, 1);
#endif
}
//~Semaphore()
// Destructor, frees system resources
Semaphore::~Semaphore()
{
#ifdef WIN
CloseHandle(sem);
#endif
#ifdef POSIX
semctl(p_sem, 0, IPC_RMID, 0);
#endif
}