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

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

unix.superglobalmegacorp.com

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