Annotation of nono/lib/rwlock.h, revision 1.1

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: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.