version 1.1.2.1, 2006/07/27 23:11:52
|
version 1.1.2.6, 2006/08/02 07:26:35
|
|
|
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
#include <Pegasus/Common/Time.h> |
|
#include <Pegasus/Common/IPCExceptions.h> |
#include "Semaphore.h" | #include "Semaphore.h" |
#include "IPCExceptions.h" |
|
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
static const Uint32 PEGASUS_SEM_VALUE_MAX = 0x0000ffff; |
|
|
//============================================================================== | //============================================================================== |
// | // |
// PEGASUS_USE_PTHREAD_SEMAPHORE | // PEGASUS_USE_PTHREAD_SEMAPHORE |
// | // |
//============================================================================== | //============================================================================== |
| |
#define SEM_VALUE_MAX 0x0000FFFF |
|
|
|
#if defined(PEGASUS_USE_PTHREAD_SEMAPHORE) | #if defined(PEGASUS_USE_PTHREAD_SEMAPHORE) |
| |
Semaphore::Semaphore(Uint32 initial) | Semaphore::Semaphore(Uint32 initial) |
|
|
pthread_mutex_init (&_rep.mutex, NULL); | pthread_mutex_init (&_rep.mutex, NULL); |
pthread_cond_init (&_rep.cond, NULL); | pthread_cond_init (&_rep.cond, NULL); |
| |
if (initial > SEM_VALUE_MAX) |
if (initial > PEGASUS_SEM_VALUE_MAX) |
_count = SEM_VALUE_MAX - 1; |
_count = PEGASUS_SEM_VALUE_MAX - 1; |
else | else |
_count = initial; | _count = initial; |
| |
|
|
#endif | #endif |
} | } |
| |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
#if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
// cleanup function | // cleanup function |
static void semaphore_cleanup(void *arg) | static void semaphore_cleanup(void *arg) |
{ | { |
|
|
| |
// Push cleanup function onto cleanup stack | // Push cleanup function onto cleanup stack |
// The mutex will unlock if the thread is killed early | // The mutex will unlock if the thread is killed early |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
#if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
Threads::cleanup_push(&semaphore_cleanup, &_rep); | Threads::cleanup_push(&semaphore_cleanup, &_rep); |
#endif | #endif |
| |
|
|
| |
// Since we push an unlock onto the cleanup stack | // Since we push an unlock onto the cleanup stack |
// We will pop it off to release the mutex when leaving the critical section. | // We will pop it off to release the mutex when leaving the critical section. |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
#if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
Threads::cleanup_pop(1); | Threads::cleanup_pop(1); |
#endif | #endif |
// Release mutex to leave critical section. | // Release mutex to leave critical section. |
|
|
pthread_mutex_lock (&_rep.mutex); | pthread_mutex_lock (&_rep.mutex); |
Boolean timedOut = false; | Boolean timedOut = false; |
| |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || \ |
#if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
|
// Push cleanup function onto cleanup stack | // Push cleanup function onto cleanup stack |
// The mutex will unlock if the thread is killed early | // The mutex will unlock if the thread is killed early |
Thread::cleanup_push(&semaphore_cleanup, &_rep); | Thread::cleanup_push(&semaphore_cleanup, &_rep); |
|
|
// Decrement the waiters count. | // Decrement the waiters count. |
_rep.waiters--; | _rep.waiters--; |
| |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || \ |
#if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
|
// Since we push an unlock onto the cleanup stack | // Since we push an unlock onto the cleanup stack |
// We will pop it off to release the mutex when leaving the critical section. | // We will pop it off to release the mutex when leaving the critical section. |
Threads::cleanup_pop(1); | Threads::cleanup_pop(1); |
|
|
| |
Semaphore::Semaphore(Uint32 initial) | Semaphore::Semaphore(Uint32 initial) |
{ | { |
if(initial > SEM_VALUE_MAX) |
if(initial > PEGASUS_SEM_VALUE_MAX) |
initial = SEM_VALUE_MAX - 1; |
initial = PEGASUS_SEM_VALUE_MAX - 1; |
sem_init(&_rep.sem,0,initial); | sem_init(&_rep.sem,0,initial); |
_rep.owner = Threads::self(); | _rep.owner = Threads::self(); |
} | } |
|
|
| |
#if defined(PEGASUS_USE_WINDOWS_SEMAPHORE) | #if defined(PEGASUS_USE_WINDOWS_SEMAPHORE) |
| |
static const int SEM_VALUE_MAX = 0x0000ffff; |
|
|
|
Semaphore::Semaphore(Uint32 initial) | Semaphore::Semaphore(Uint32 initial) |
{ | { |
if(initial > SEM_VALUE_MAX) |
if(initial > PEGASUS_SEM_VALUE_MAX) |
initial = SEM_VALUE_MAX - 1; |
initial = PEGASUS_SEM_VALUE_MAX - 1; |
_count = initial; | _count = initial; |
_rep.owner = (ThreadType)GetCurrentThreadId(); |
_rep.owner = Threads::self(); |
_rep.sem = CreateSemaphore(NULL, initial, SEM_VALUE_MAX, NULL); |
_rep.sem = CreateSemaphore(NULL, initial, PEGASUS_SEM_VALUE_MAX, NULL); |
} | } |
| |
Semaphore::~Semaphore() | Semaphore::~Semaphore() |
|
|
if(errorcode != WAIT_FAILED) | if(errorcode != WAIT_FAILED) |
_count--; | _count--; |
else | else |
throw(WaitFailed((ThreadType)GetCurrentThreadId())); |
throw(WaitFailed(Threads::self())); |
} | } |
| |
// wait succeeds immediately if semaphore has a non-zero count, | // wait succeeds immediately if semaphore has a non-zero count, |
|
|
{ | { |
DWORD errorcode = WaitForSingleObject(_rep.sem, 0); | DWORD errorcode = WaitForSingleObject(_rep.sem, 0); |
if(errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED) | if(errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED) |
throw(WaitFailed((ThreadType)GetCurrentThreadId())); |
throw(WaitFailed(Threads::self())); |
_count--; | _count--; |
} | } |
| |
|
|
{ | { |
DWORD errorcode = WaitForSingleObject(_rep.sem, milliseconds); | DWORD errorcode = WaitForSingleObject(_rep.sem, milliseconds); |
if (errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED) | if (errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED) |
throw(TimeOut((ThreadType)GetCurrentThreadId())); |
throw(TimeOut(Threads::self())); |
_count--; | _count--; |
} | } |
| |