Browse Source

Support named semaphores on *nix.

Darryl Pogue 13 years ago
parent
commit
8437d676fb
  1. 9
      Sources/Plasma/CoreLib/hsThread.h
  2. 36
      Sources/Plasma/CoreLib/hsThread_Unix.cpp

9
Sources/Plasma/CoreLib/hsThread.h

@ -145,7 +145,8 @@ class hsSemaphore {
HANDLE fSemaH; HANDLE fSemaH;
#elif HS_BUILD_FOR_UNIX #elif HS_BUILD_FOR_UNIX
#ifdef USE_SEMA #ifdef USE_SEMA
sem_t fPSema; sem_t* fPSema;
bool fNamed;
#else #else
pthread_mutex_t fPMutex; pthread_mutex_t fPMutex;
pthread_cond_t fPCond; pthread_cond_t fPCond;
@ -153,11 +154,7 @@ class hsSemaphore {
#endif #endif
#endif #endif
public: public:
#ifdef HS_BUILD_FOR_WIN32 hsSemaphore(int initialValue=0, const char* name=nil);
hsSemaphore(int initialValue=0, const char *name=nil);
#else
hsSemaphore(int initialValue=0);
#endif
~hsSemaphore(); ~hsSemaphore();
hsBool Wait(hsMilliseconds timeToWait = kPosInfinity32); hsBool Wait(hsMilliseconds timeToWait = kPosInfinity32);

36
Sources/Plasma/CoreLib/hsThread_Unix.cpp

@ -42,6 +42,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsThread.h" #include "hsThread.h"
#include "hsExceptions.h" #include "hsExceptions.h"
#include <sys/errno.h> #include <sys/errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#define NO_POSIX_CLOCK 1 #define NO_POSIX_CLOCK 1
@ -72,7 +74,7 @@ extern "C" {
static void* gEntryPoint(void* param) static void* gEntryPoint(void* param)
{ {
pthread_mutex_lock(((hsThread*)param)->GetStartupMutex()); pthread_mutex_lock(((hsThread*)param)->GetStartupMutex());
void* ret = (void*)((hsThread*)param)->Run(); void* ret = (void*)(uintptr_t)((hsThread*)param)->Run();
pthread_mutex_unlock(((hsThread*)param)->GetStartupMutex()); pthread_mutex_unlock(((hsThread*)param)->GetStartupMutex());
pthread_exit(ret); pthread_exit(ret);
return ret; return ret;
@ -266,12 +268,24 @@ void hsMutex::Unlock()
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
hsSemaphore::hsSemaphore(int initialValue) hsSemaphore::hsSemaphore(int initialValue, const char* name)
{ {
#ifdef USE_SEMA #ifdef USE_SEMA
int shared = 0; // 1 if sharing between processes fPSema = nil;
int status = ::sem_init(&fPSema, shared, initialValue); if ((fNamed = (name != nil))) {
hsThrowIfOSErr(status); /* Named semaphore shared between processes */
fPSema = sem_open(name, O_CREAT, 0666, initialValue);
if (fPSema == SEM_FAILED)
{
hsAssert(0, "hsOSException");
throw hsOSException(errno);
}
} else {
/* Anonymous semaphore shared between threads */
int shared = 0; // 1 if sharing between processes
int status = sem_init(fPSema, shared, initialValue);
hsThrowIfOSErr(status);
}
#else #else
int status = ::pthread_mutex_init(&fPMutex, nil); int status = ::pthread_mutex_init(&fPMutex, nil);
hsThrowIfOSErr(status); hsThrowIfOSErr(status);
@ -286,7 +300,12 @@ hsSemaphore::hsSemaphore(int initialValue)
hsSemaphore::~hsSemaphore() hsSemaphore::~hsSemaphore()
{ {
#ifdef USE_SEMA #ifdef USE_SEMA
int status = ::sem_destroy(&fPSema); int status = 0;
if (fNamed) {
status = sem_close(fPSema);
} else {
status = sem_destroy(fPSema);
}
hsThrowIfOSErr(status); hsThrowIfOSErr(status);
#else #else
int status = ::pthread_cond_destroy(&fPCond); int status = ::pthread_cond_destroy(&fPCond);
@ -300,8 +319,9 @@ hsSemaphore::~hsSemaphore()
hsBool hsSemaphore::Wait(hsMilliseconds timeToWait) hsBool hsSemaphore::Wait(hsMilliseconds timeToWait)
{ {
#ifdef USE_SEMA // SHOULDN'T THIS USE timeToWait??!?!? -rje #ifdef USE_SEMA // SHOULDN'T THIS USE timeToWait??!?!? -rje
// shouldn't this use sem_timedwait? -dpogue (2012-03-04)
hsAssert( timeToWait==kPosInfinity32, "sem_t does not support wait with timeout. #undef USE_SEMA and recompile." ); hsAssert( timeToWait==kPosInfinity32, "sem_t does not support wait with timeout. #undef USE_SEMA and recompile." );
int status = ::sem_wait(&fPSema); int status = sem_wait(fPSema);
hsThrowIfOSErr(status); hsThrowIfOSErr(status);
return true; return true;
#else #else
@ -351,7 +371,7 @@ EXIT:
void hsSemaphore::Signal() void hsSemaphore::Signal()
{ {
#ifdef USE_SEMA #ifdef USE_SEMA
int status = ::sem_post(&fPSema); int status = sem_post(fPSema);
hsThrowIfOSErr(status); hsThrowIfOSErr(status);
#else #else
int status = ::pthread_mutex_lock(&fPMutex); int status = ::pthread_mutex_lock(&fPMutex);

Loading…
Cancel
Save