From f83ec34c675aaba9f271347c6657614f6b4ed6a1 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Wed, 9 Apr 2014 23:32:13 -0700 Subject: [PATCH] Move the old IPC-based semaphore to hsGlobalSemaphore, and provide a "normal" (inter-thread only) semaphore class. --- Sources/Plasma/CoreLib/hsThread.h | 42 +++++++++++++++++-- Sources/Plasma/CoreLib/hsThread_Mac.cpp | 8 ++-- Sources/Plasma/CoreLib/hsThread_Unix.cpp | 8 ++-- Sources/Plasma/CoreLib/hsThread_Win.cpp | 8 ++-- .../FeatureLib/pfCrashHandler/plCrashBase.cpp | 4 +- .../FeatureLib/pfCrashHandler/plCrashBase.h | 4 +- .../PubUtilLib/plStatusLog/plStatusLog.cpp | 4 +- .../PubUtilLib/plStatusLog/plStatusLog.h | 2 +- 8 files changed, 58 insertions(+), 22 deletions(-) diff --git a/Sources/Plasma/CoreLib/hsThread.h b/Sources/Plasma/CoreLib/hsThread.h index 02745ed6..0da3171c 100644 --- a/Sources/Plasma/CoreLib/hsThread.h +++ b/Sources/Plasma/CoreLib/hsThread.h @@ -107,8 +107,44 @@ public: }; ////////////////////////////////////////////////////////////////////////////// +class hsSemaphore +{ + std::mutex fMutex; + std::condition_variable fCondition; + unsigned fValue; + +public: + hsSemaphore(unsigned initial = 0) : fValue(initial) { } + + inline void Wait() + { + std::unique_lock lock(fMutex); + fCondition.wait(lock, [this]() { return fValue > 0; }); + --fValue; + } + + template + inline bool Wait(const std::chrono::duration<_Rep, _Period> &duration) + { + std::unique_lock lock(fMutex); + + bool result = fCondition.wait_for(lock, duration, [this]() { return fValue > 0; }); + if (result) + --fValue; + + return result; + } + + inline void Signal() + { + std::unique_lock lock(fMutex); + ++fValue; + fCondition.notify_one(); + } +}; -class hsSemaphore { +////////////////////////////////////////////////////////////////////////////// +class hsGlobalSemaphore { #if HS_BUILD_FOR_WIN32 HANDLE fSemaH; #elif HS_BUILD_FOR_UNIX @@ -122,8 +158,8 @@ class hsSemaphore { #endif #endif public: - hsSemaphore(int initialValue=0, const char* name=nullptr); - ~hsSemaphore(); + hsGlobalSemaphore(int initialValue = 0, const char* name = nullptr); + ~hsGlobalSemaphore(); #ifdef HS_BUILD_FOR_WIN32 HANDLE GetHandle() const { return fSemaH; } diff --git a/Sources/Plasma/CoreLib/hsThread_Mac.cpp b/Sources/Plasma/CoreLib/hsThread_Mac.cpp index 9429604d..d64aad9c 100644 --- a/Sources/Plasma/CoreLib/hsThread_Mac.cpp +++ b/Sources/Plasma/CoreLib/hsThread_Mac.cpp @@ -115,19 +115,19 @@ void hsThread::ThreadYield() ////////////////////////////////////////////////////////////////////////////// -hsSemaphore::hsSemaphore(int initialValue) +hsGlobalSemaphore::hsGlobalSemaphore(int initialValue) { OSStatus status = MPCreateSemaphore(kPosInfinity32, initialValue, &fSemaId); hsThrowIfOSErr(status); } -hsSemaphore::~hsSemaphore() +hsGlobalSemaphore::~hsGlobalSemaphore() { OSStatus status = MPDeleteSemaphore(fSemaId); hsThrowIfOSErr(status); } -bool hsSemaphore::Wait(hsMilliseconds timeToWait) +bool hsGlobalSemaphore::Wait(hsMilliseconds timeToWait) { Duration duration; @@ -145,7 +145,7 @@ bool hsSemaphore::Wait(hsMilliseconds timeToWait) return true; } -void hsSemaphore::Signal() +void hsGlobalSemaphore::Signal() { OSStatus status = MPSignalSemaphore(fSemaId); hsThrowIfOSErr(status); diff --git a/Sources/Plasma/CoreLib/hsThread_Unix.cpp b/Sources/Plasma/CoreLib/hsThread_Unix.cpp index a6b3e72d..4349270c 100644 --- a/Sources/Plasma/CoreLib/hsThread_Unix.cpp +++ b/Sources/Plasma/CoreLib/hsThread_Unix.cpp @@ -192,7 +192,7 @@ static void InitEventLoggingFile() ///////////////////////////////////////////////////////////////////////////// -hsSemaphore::hsSemaphore(int initialValue, const char* name) +hsGlobalSemaphore::hsGlobalSemaphore(int initialValue, const char* name) { #ifdef USE_SEMA fPSema = nil; @@ -222,7 +222,7 @@ hsSemaphore::hsSemaphore(int initialValue, const char* name) #endif } -hsSemaphore::~hsSemaphore() +hsGlobalSemaphore::~hsGlobalSemaphore() { #ifdef USE_SEMA int status = 0; @@ -242,7 +242,7 @@ hsSemaphore::~hsSemaphore() #endif } -bool hsSemaphore::Wait(hsMilliseconds timeToWait) +bool hsGlobalSemaphore::Wait(hsMilliseconds timeToWait) { #ifdef USE_SEMA // SHOULDN'T THIS USE timeToWait??!?!? -rje // shouldn't this use sem_timedwait? -dpogue (2012-03-04) @@ -294,7 +294,7 @@ EXIT: #endif } -void hsSemaphore::Signal() +void hsGlobalSemaphore::Signal() { #ifdef USE_SEMA int status = sem_post(fPSema); diff --git a/Sources/Plasma/CoreLib/hsThread_Win.cpp b/Sources/Plasma/CoreLib/hsThread_Win.cpp index a4717713..6c1d8f46 100644 --- a/Sources/Plasma/CoreLib/hsThread_Win.cpp +++ b/Sources/Plasma/CoreLib/hsThread_Win.cpp @@ -135,19 +135,19 @@ void hsThread::ThreadYield() ////////////////////////////////////////////////////////////////////////////// -hsSemaphore::hsSemaphore(int initialValue, const char *name) +hsGlobalSemaphore::hsGlobalSemaphore(int initialValue, const char *name) { fSemaH = ::CreateSemaphore(nil, initialValue, kPosInfinity32, name); if (fSemaH == nil) throw hsOSException(-1); } -hsSemaphore::~hsSemaphore() +hsGlobalSemaphore::~hsGlobalSemaphore() { ::CloseHandle(fSemaH); } -bool hsSemaphore::Wait(hsMilliseconds timeToWait) +bool hsGlobalSemaphore::Wait(hsMilliseconds timeToWait) { if (timeToWait == kPosInfinity32) timeToWait = INFINITE; @@ -162,7 +162,7 @@ bool hsSemaphore::Wait(hsMilliseconds timeToWait) } } -void hsSemaphore::Signal() +void hsGlobalSemaphore::Signal() { ::ReleaseSemaphore(fSemaH, 1, nil); } diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp index 36444b50..f0d3c017 100644 --- a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp +++ b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.cpp @@ -53,8 +53,8 @@ void plCrashBase::IInit(const char* file) { char sema[128]; snprintf(sema, arrsize(sema), "%s-%s", file, CRASH_NOTIFY_SUFFIX); - fCrashed = new hsSemaphore(0, sema); + fCrashed = new hsGlobalSemaphore(0, sema); snprintf(sema, arrsize(sema), "%s-%s", file, CRASH_HANDLE_SUFFIX); - fHandled = new hsSemaphore(0, sema); + fHandled = new hsGlobalSemaphore(0, sema); } diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h index 3dbc13d3..a480f7ea 100644 --- a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h +++ b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashBase.h @@ -48,8 +48,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com class plCrashBase { protected: - hsSemaphore* fCrashed; - hsSemaphore* fHandled; + hsGlobalSemaphore* fCrashed; + hsGlobalSemaphore* fHandled; ~plCrashBase(); void IInit(const char* file); diff --git a/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.cpp b/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.cpp index 197d8bd6..92abff83 100644 --- a/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.cpp +++ b/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.cpp @@ -277,14 +277,14 @@ plStatusLog::plStatusLog( uint8_t numDisplayLines, const plFileName &filename, u if (filename.IsValid()) { fFilename = filename; - fSema = new hsSemaphore(1, fFilename.AsString().c_str()); + fSema = new hsGlobalSemaphore(1, fFilename.AsString().c_str()); } else { fFilename = ""; flags |= kDontWriteFile; - fSema = new hsSemaphore(1); + fSema = new hsGlobalSemaphore(1); } fOrigFlags = fFlags = flags; diff --git a/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h b/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h index 65fe3484..35bd351f 100644 --- a/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h +++ b/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h @@ -86,7 +86,7 @@ class plStatusLog plFileName fFilename; char** fLines; uint32_t* fColors; - hsSemaphore* fSema; + hsGlobalSemaphore* fSema; FILE* fFileHandle; uint32_t fSize; bool fForceLog;