@@ -31,6 +31,9 @@ type RWMutex struct {
31
31
32
32
const rwMutexMaxReaders = 1 << 30
33
33
34
+ // Lock locks rw for writing.
35
+ // If the lock is already locked for reading or writing,
36
+ // Lock blocks until the lock is available.
34
37
func (rw * RWMutex ) Lock () {
35
38
// Exclusive lock for writers.
36
39
rw .writerLock .Lock ()
@@ -56,6 +59,12 @@ func (rw *RWMutex) Lock() {
56
59
rw .writer .Store (0 )
57
60
}
58
61
62
+ // Unlock unlocks rw for writing. It is a run-time error if rw is
63
+ // not locked for writing on entry to Unlock.
64
+ //
65
+ // As with Mutexes, a locked [RWMutex] is not associated with a particular
66
+ // goroutine. One goroutine may [RWMutex.RLock] ([RWMutex.Lock]) a RWMutex and then
67
+ // arrange for another goroutine to [RWMutex.RUnlock] ([RWMutex.Unlock]) it.
59
68
func (rw * RWMutex ) Unlock () {
60
69
// Signal that new readers can lock this mutex.
61
70
waiting := rw .readers .Add (rwMutexMaxReaders )
@@ -68,6 +77,31 @@ func (rw *RWMutex) Unlock() {
68
77
rw .writerLock .Unlock ()
69
78
}
70
79
80
+ // TryLock tries to lock m and reports whether it succeeded.
81
+ //
82
+ // Note that while correct uses of TryLock do exist, they are rare,
83
+ // and use of TryLock is often a sign of a deeper problem
84
+ // in a particular use of mutexes.
85
+ func (rw * RWMutex ) TryLock () bool {
86
+ // Check for active writers
87
+ if ! rw .writerLock .TryLock () {
88
+ return false
89
+ }
90
+ // Have write lock, now check for active readers
91
+ n := uint32 (rwMutexMaxReaders )
92
+ if ! rw .readers .CompareAndSwap (0 , - n ) {
93
+ // Active readers, give up write lock
94
+ rw .writerLock .Unlock ()
95
+ return false
96
+ }
97
+ return true
98
+ }
99
+
100
+ // RLock locks rw for reading.
101
+ //
102
+ // It should not be used for recursive read locking; a blocked Lock
103
+ // call excludes new readers from acquiring the lock. See the
104
+ // documentation on the [RWMutex] type.
71
105
func (rw * RWMutex ) RLock () {
72
106
// Add us as a reader.
73
107
newVal := rw .readers .Add (1 )
@@ -79,6 +113,10 @@ func (rw *RWMutex) RLock() {
79
113
}
80
114
}
81
115
116
+ // RUnlock undoes a single [RWMutex.RLock] call;
117
+ // it does not affect other simultaneous readers.
118
+ // It is a run-time error if rw is not locked for reading
119
+ // on entry to RUnlock.
82
120
func (rw * RWMutex ) RUnlock () {
83
121
// Remove us as a reader.
84
122
one := uint32 (1 )
@@ -98,6 +136,25 @@ func (rw *RWMutex) RUnlock() {
98
136
}
99
137
}
100
138
139
+ // TryRLock tries to lock rw for reading and reports whether it succeeded.
140
+ //
141
+ // Note that while correct uses of TryRLock do exist, they are rare,
142
+ // and use of TryRLock is often a sign of a deeper problem
143
+ // in a particular use of mutexes.
144
+ func (rw * RWMutex ) TryRLock () bool {
145
+ for {
146
+ c := rw .readers .Load ()
147
+ if c < 0 {
148
+ // There is a writer waiting or writing.
149
+ return false
150
+ }
151
+ if rw .readers .CompareAndSwap (c , c + 1 ) {
152
+ // Read lock obtained.
153
+ return true
154
+ }
155
+ }
156
+ }
157
+
101
158
type Locker interface {
102
159
Lock ()
103
160
Unlock ()
0 commit comments