|
|
1.1.1.2 ! root 1: /* ! 2: * Copyright (C) 2025 Tetsuya Isaki ! 3: * ! 4: * Permission to use, copy, modify, and/or distribute this software for any ! 5: * purpose with or without fee is hereby granted. ! 6: * ! 7: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ! 8: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! 9: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ! 10: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! 11: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! 12: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! 13: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 14: */ 1.1 root 15: 16: // 17: // rwlock (ただし書き込み優先) 18: // 19: 20: #pragma once 21: 22: #include <condition_variable> 23: #include <mutex> 24: 25: class RWLock 26: { 27: public: 28: RWLock() 29: { 30: } 31: 32: void EnterRead() 33: { 34: std::unique_lock<std::mutex> lock(mtx); 35: cv.wait(lock, [this]() { 36: return rw_acquired >= 0 && writer_waiting == 0; 37: }); 38: rw_acquired++; 39: } 40: 41: void LeaveRead() 42: { 43: std::lock_guard<std::mutex> lock(mtx); 44: assert(rw_acquired > 0); 45: if (--rw_acquired == 0) { 46: cv.notify_all(); 47: } 48: } 49: 50: void EnterWrite() 51: { 52: std::unique_lock<std::mutex> lock(mtx); 53: writer_waiting++; 54: cv.wait(lock, [this]() { 55: return rw_acquired == 0; 56: }); 57: writer_waiting--; 58: rw_acquired--; 59: } 60: 61: void LeaveWrite() 62: { 63: std::lock_guard<std::mutex> lock(mtx); 64: assert(rw_acquired < 0); 65: rw_acquired = 0; 66: cv.notify_all(); 67: } 68: 69: private: 70: std::mutex mtx {}; 71: std::condition_variable cv {}; 72: 73: // 正なら読み込みロックの数。 74: // -1 なら書き込みがロック取得中。 75: int rw_acquired {}; 76: 77: int writer_waiting {}; 78: }; 79: 80: class RWLockGuard_Read 81: { 82: public: 83: explicit RWLockGuard_Read(RWLock& lock_) 84: : lock(lock_) 85: { 86: lock.EnterRead(); 87: } 88: ~RWLockGuard_Read() 89: { 90: lock.LeaveRead(); 91: } 92: 93: private: 94: RWLock& lock; 95: }; 96: 97: class RWLockGuard_Write 98: { 99: public: 100: explicit RWLockGuard_Write(RWLock& lock_) 101: : lock(lock_) 102: { 103: lock.EnterWrite(); 104: } 105: ~RWLockGuard_Write() 106: { 107: lock.LeaveWrite(); 108: } 109: 110: private: 111: RWLock& lock; 112: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.