|
|
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.