1 /**
2     Read-Write Mutually Exclusive Locks
3 
4     Copyright:
5         Copyright © 2023-2025, Kitsunebi Games
6         Copyright © 2023-2025, Inochi2D Project
7     
8     License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9     Authors:   Luna Nielsen
10 */
11 module nulib.threading.rwmutex;
12 import nulib.threading.mutex;
13 import nulib.threading.atomic;
14 import numem;
15 
16 /**
17     A mutex which allows multiple multiple readers to pass
18     while blocking on write.
19 
20     This RWMutex implementation is read-preferring.
21 */
22 class RWMutex : NuObject {
23 private:
24 @nogc:
25     Atomic!uint readers;
26     Mutex readMutex;
27     Mutex writeMutex;
28 
29 public:
30     
31     class Reader {
32     public:
33     @nogc:
34 
35         /**
36             Peforms a reader lock operation.
37         */
38         void lock() {
39             readMutex.lock();
40             readers += 1;
41             if (readers == 1)
42                 writeMutex.lock();
43             readMutex.unlock();
44         }
45 
46         /**
47             Peforms a reader unlock operation.
48         */
49         void unlock() {
50             readMutex.lock();
51             readers -= 1;
52             if (readers == 0)
53                 writeMutex.unlock();
54             readMutex.unlock();
55         }
56 
57     }
58 
59     class Writer {
60     public:
61     @nogc:
62 
63         /**
64             Peforms a writer lock operation.
65         */
66         void lock() {
67             writeMutex.lock();
68         }
69 
70         /**
71             Peforms a writer unlock operation.
72         */
73         void unlock() {
74             writeMutex.unlock();
75         }
76 
77     }
78 
79     /**
80         The reader lock.
81     */
82     Reader reader;
83 
84     /**
85         The writer lock.
86     */
87     Writer writer;
88 
89     /// Destructor
90     ~this() {
91         readers = 0;
92         nogc_delete(readMutex);
93         nogc_delete(writeMutex);
94     }
95 
96     /**
97         Creates a new read-write mutex.
98     */
99     this() {
100         readers = 0;
101         readMutex = nogc_new!Mutex();
102         writeMutex = nogc_new!Mutex();
103     }
104 }