mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 14:08:40 +01:00
sync: modernize CSemaphore / CSemaphoreGrant
This commit is contained in:
75
src/sync.h
75
src/sync.h
@@ -301,6 +301,10 @@ inline MutexType* MaybeCheckNotHeld(MutexType* m) LOCKS_EXCLUDED(m) LOCK_RETURNE
|
||||
//! gcc and the -Wreturn-stack-address flag in clang, both enabled by default.
|
||||
#define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())
|
||||
|
||||
/** An implementation of a semaphore.
|
||||
*
|
||||
* See https://en.wikipedia.org/wiki/Semaphore_(programming)
|
||||
*/
|
||||
class CSemaphore
|
||||
{
|
||||
private:
|
||||
@@ -309,25 +313,33 @@ private:
|
||||
int value;
|
||||
|
||||
public:
|
||||
explicit CSemaphore(int init) : value(init) {}
|
||||
explicit CSemaphore(int init) noexcept : value(init) {}
|
||||
|
||||
void wait()
|
||||
// Disallow default construct, copy, move.
|
||||
CSemaphore() = delete;
|
||||
CSemaphore(const CSemaphore&) = delete;
|
||||
CSemaphore(CSemaphore&&) = delete;
|
||||
CSemaphore& operator=(const CSemaphore&) = delete;
|
||||
CSemaphore& operator=(CSemaphore&&) = delete;
|
||||
|
||||
void wait() noexcept
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
condition.wait(lock, [&]() { return value >= 1; });
|
||||
value--;
|
||||
}
|
||||
|
||||
bool try_wait()
|
||||
bool try_wait() noexcept
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
if (value < 1)
|
||||
if (value < 1) {
|
||||
return false;
|
||||
}
|
||||
value--;
|
||||
return true;
|
||||
}
|
||||
|
||||
void post()
|
||||
void post() noexcept
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
@@ -345,45 +357,64 @@ private:
|
||||
bool fHaveGrant;
|
||||
|
||||
public:
|
||||
void Acquire()
|
||||
void Acquire() noexcept
|
||||
{
|
||||
if (fHaveGrant)
|
||||
if (fHaveGrant) {
|
||||
return;
|
||||
}
|
||||
sem->wait();
|
||||
fHaveGrant = true;
|
||||
}
|
||||
|
||||
void Release()
|
||||
void Release() noexcept
|
||||
{
|
||||
if (!fHaveGrant)
|
||||
if (!fHaveGrant) {
|
||||
return;
|
||||
}
|
||||
sem->post();
|
||||
fHaveGrant = false;
|
||||
}
|
||||
|
||||
bool TryAcquire()
|
||||
bool TryAcquire() noexcept
|
||||
{
|
||||
if (!fHaveGrant && sem->try_wait())
|
||||
if (!fHaveGrant && sem->try_wait()) {
|
||||
fHaveGrant = true;
|
||||
}
|
||||
return fHaveGrant;
|
||||
}
|
||||
|
||||
void MoveTo(CSemaphoreGrant& grant)
|
||||
// Disallow copy.
|
||||
CSemaphoreGrant(const CSemaphoreGrant&) = delete;
|
||||
CSemaphoreGrant& operator=(const CSemaphoreGrant&) = delete;
|
||||
|
||||
// Allow move.
|
||||
CSemaphoreGrant(CSemaphoreGrant&& other) noexcept
|
||||
{
|
||||
grant.Release();
|
||||
grant.sem = sem;
|
||||
grant.fHaveGrant = fHaveGrant;
|
||||
fHaveGrant = false;
|
||||
sem = other.sem;
|
||||
fHaveGrant = other.fHaveGrant;
|
||||
other.fHaveGrant = false;
|
||||
other.sem = nullptr;
|
||||
}
|
||||
|
||||
CSemaphoreGrant() : sem(nullptr), fHaveGrant(false) {}
|
||||
|
||||
explicit CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false)
|
||||
CSemaphoreGrant& operator=(CSemaphoreGrant&& other) noexcept
|
||||
{
|
||||
if (fTry)
|
||||
Release();
|
||||
sem = other.sem;
|
||||
fHaveGrant = other.fHaveGrant;
|
||||
other.fHaveGrant = false;
|
||||
other.sem = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSemaphoreGrant() noexcept : sem(nullptr), fHaveGrant(false) {}
|
||||
|
||||
explicit CSemaphoreGrant(CSemaphore& sema, bool fTry = false) noexcept : sem(&sema), fHaveGrant(false)
|
||||
{
|
||||
if (fTry) {
|
||||
TryAcquire();
|
||||
else
|
||||
} else {
|
||||
Acquire();
|
||||
}
|
||||
}
|
||||
|
||||
~CSemaphoreGrant()
|
||||
@@ -391,7 +422,7 @@ public:
|
||||
Release();
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return fHaveGrant;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user