Annotation of nono/lib/rwlock.h, revision 1.1.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.