|
|
nono 1.7.0
/*
* Copyright (C) 2025 Tetsuya Isaki
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//
// rwlock (ただし書き込み優先)
//
#pragma once
#include <condition_variable>
#include <mutex>
class RWLock
{
public:
RWLock()
{
}
void EnterRead()
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]() {
return rw_acquired >= 0 && writer_waiting == 0;
});
rw_acquired++;
}
void LeaveRead()
{
std::lock_guard<std::mutex> lock(mtx);
assert(rw_acquired > 0);
if (--rw_acquired == 0) {
cv.notify_all();
}
}
void EnterWrite()
{
std::unique_lock<std::mutex> lock(mtx);
writer_waiting++;
cv.wait(lock, [this]() {
return rw_acquired == 0;
});
writer_waiting--;
rw_acquired--;
}
void LeaveWrite()
{
std::lock_guard<std::mutex> lock(mtx);
assert(rw_acquired < 0);
rw_acquired = 0;
cv.notify_all();
}
private:
std::mutex mtx {};
std::condition_variable cv {};
// 正なら読み込みロックの数。
// -1 なら書き込みがロック取得中。
int rw_acquired {};
int writer_waiting {};
};
class RWLockGuard_Read
{
public:
explicit RWLockGuard_Read(RWLock& lock_)
: lock(lock_)
{
lock.EnterRead();
}
~RWLockGuard_Read()
{
lock.LeaveRead();
}
private:
RWLock& lock;
};
class RWLockGuard_Write
{
public:
explicit RWLockGuard_Write(RWLock& lock_)
: lock(lock_)
{
lock.EnterWrite();
}
~RWLockGuard_Write()
{
lock.LeaveWrite();
}
private:
RWLock& lock;
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.