|
@ -5,7 +5,11 @@ namespace pEp { |
|
|
class Semaphore { |
|
|
class Semaphore { |
|
|
std::mutex mtx; |
|
|
std::mutex mtx; |
|
|
std::condition_variable cv; |
|
|
std::condition_variable cv; |
|
|
bool _stop; |
|
|
// Atomic types are types that encapsulate a value whose access is guaranteed
|
|
|
|
|
|
// to not cause data races and can be used to synchronize memory accesses among
|
|
|
|
|
|
// different threads.
|
|
|
|
|
|
// To synchronize threads, ALWAYS use <atomic> types
|
|
|
|
|
|
std::atomic_bool _stop; |
|
|
|
|
|
|
|
|
public: |
|
|
public: |
|
|
Semaphore() : _stop(false) { } |
|
|
Semaphore() : _stop(false) { } |
|
@ -13,23 +17,25 @@ namespace pEp { |
|
|
void stop() |
|
|
void stop() |
|
|
{ |
|
|
{ |
|
|
std::unique_lock<std::mutex> lock(mtx); |
|
|
std::unique_lock<std::mutex> lock(mtx); |
|
|
_stop = true; |
|
|
_stop.store(true); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void try_wait() |
|
|
void try_wait() |
|
|
{ |
|
|
{ |
|
|
std::unique_lock<std::mutex> lock(mtx); |
|
|
std::unique_lock<std::mutex> lock(mtx); |
|
|
if (!_stop) |
|
|
if (_stop.load() == false) { |
|
|
return; |
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
while(_stop) |
|
|
while(_stop.load() == true) { |
|
|
cv.wait(lock); |
|
|
cv.wait(lock); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void go() |
|
|
void go() |
|
|
{ |
|
|
{ |
|
|
std::unique_lock<std::mutex> lock(mtx); |
|
|
std::unique_lock<std::mutex> lock(mtx); |
|
|
_stop = false; |
|
|
_stop.store(false); |
|
|
cv.notify_all(); |
|
|
cv.notify_all(); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|