diff --git a/slsReceiverSoftware/src/ThreadObject.cpp b/slsReceiverSoftware/src/ThreadObject.cpp index eec0d2aaf..1a10aad12 100644 --- a/slsReceiverSoftware/src/ThreadObject.cpp +++ b/slsReceiverSoftware/src/ThreadObject.cpp @@ -16,7 +16,6 @@ namespace sls { ThreadObject::ThreadObject(int index, std::string type) : index(index), type(type) { LOG(logDEBUG) << type << " thread created: " << index; - sem_init(&semaphore, 1, 0); try { threadObject = std::thread(&ThreadObject::RunningThread, this); } catch (...) { @@ -27,9 +26,8 @@ ThreadObject::ThreadObject(int index, std::string type) ThreadObject::~ThreadObject() { killThread = true; - sem_post(&semaphore); + semaphore.release(); threadObject.join(); - sem_destroy(&semaphore); } pid_t ThreadObject::GetThreadId() const { return threadId; } @@ -49,14 +47,14 @@ void ThreadObject::RunningThread() { ThreadExecution(); } // wait till the next acquisition - sem_wait(&semaphore); + semaphore.acquire(); } LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << threadId << "]"; threadId = 0; } -void ThreadObject::Continue() { sem_post(&semaphore); } +void ThreadObject::Continue() { semaphore.release(); } void ThreadObject::SetThreadPriority(int priority) { struct sched_param param; diff --git a/slsReceiverSoftware/src/ThreadObject.h b/slsReceiverSoftware/src/ThreadObject.h index 6089e1042..f004200af 100644 --- a/slsReceiverSoftware/src/ThreadObject.h +++ b/slsReceiverSoftware/src/ThreadObject.h @@ -11,9 +11,9 @@ #include "sls/logger.h" #include "sls/sls_detector_defs.h" +#include "sls/thread_utils.h" #include -#include #include #include @@ -45,7 +45,7 @@ class ThreadObject : private virtual slsDetectorDefs { std::atomic killThread{false}; std::atomic runningFlag{false}; std::thread threadObject; - sem_t semaphore; + binary_semaphore semaphore{0}; const std::string type; std::atomic threadId{0}; }; diff --git a/slsSupportLib/include/sls/thread_utils.h b/slsSupportLib/include/sls/thread_utils.h index c1a7ff69c..ac20a5099 100644 --- a/slsSupportLib/include/sls/thread_utils.h +++ b/slsSupportLib/include/sls/thread_utils.h @@ -18,6 +18,8 @@ * within a single process. */ +#include +#include #include // pid_t #if defined(__APPLE__) @@ -46,4 +48,38 @@ inline pid_t getThreadId() noexcept { #endif } +/** + * Minimal C++17 backport of the subset of std::binary_semaphore used in this + * project. API matches std::binary_semaphore so call sites can switch to + * verbatim once the project moves to C++20. Built on + * std::mutex + std::condition_variable; therefore NOT async-signal-safe, do + * not call release() from a signal handler. + */ +class binary_semaphore { + public: + explicit binary_semaphore(int desired) : count_(desired) {} + + binary_semaphore(const binary_semaphore &) = delete; + binary_semaphore &operator=(const binary_semaphore &) = delete; + + void acquire() { + std::unique_lock lk(mtx_); + cv_.wait(lk, [this] { return count_ > 0; }); + --count_; + } + + void release() { + { + std::lock_guard lk(mtx_); + ++count_; + } + cv_.notify_one(); + } + + private: + std::mutex mtx_; + std::condition_variable cv_; + int count_; +}; + } // namespace sls