|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2025 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // rwlock (ただし書き込み優先)
9: //
10:
11: #pragma once
12:
13: #include <condition_variable>
14: #include <mutex>
15:
16: class RWLock
17: {
18: public:
19: RWLock()
20: {
21: }
22:
23: void EnterRead()
24: {
25: std::unique_lock<std::mutex> lock(mtx);
26: cv.wait(lock, [this]() {
27: return rw_acquired >= 0 && writer_waiting == 0;
28: });
29: rw_acquired++;
30: }
31:
32: void LeaveRead()
33: {
34: std::lock_guard<std::mutex> lock(mtx);
35: assert(rw_acquired > 0);
36: if (--rw_acquired == 0) {
37: cv.notify_all();
38: }
39: }
40:
41: void EnterWrite()
42: {
43: std::unique_lock<std::mutex> lock(mtx);
44: writer_waiting++;
45: cv.wait(lock, [this]() {
46: return rw_acquired == 0;
47: });
48: writer_waiting--;
49: rw_acquired--;
50: }
51:
52: void LeaveWrite()
53: {
54: std::lock_guard<std::mutex> lock(mtx);
55: assert(rw_acquired < 0);
56: rw_acquired = 0;
57: cv.notify_all();
58: }
59:
60: private:
61: std::mutex mtx {};
62: std::condition_variable cv {};
63:
64: // 正なら読み込みロックの数。
65: // -1 なら書き込みがロック取得中。
66: int rw_acquired {};
67:
68: int writer_waiting {};
69: };
70:
71: class RWLockGuard_Read
72: {
73: public:
74: explicit RWLockGuard_Read(RWLock& lock_)
75: : lock(lock_)
76: {
77: lock.EnterRead();
78: }
79: ~RWLockGuard_Read()
80: {
81: lock.LeaveRead();
82: }
83:
84: private:
85: RWLock& lock;
86: };
87:
88: class RWLockGuard_Write
89: {
90: public:
91: explicit RWLockGuard_Write(RWLock& lock_)
92: : lock(lock_)
93: {
94: lock.EnterWrite();
95: }
96: ~RWLockGuard_Write()
97: {
98: lock.LeaveWrite();
99: }
100:
101: private:
102: RWLock& lock;
103: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.