Skip to content

Commit 29ae257

Browse files
committed
f allow recursive read locks fully
1 parent 7bf6f3c commit 29ae257

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

lightning/src/debug_sync.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ impl MutexMetadata {
7474
}
7575
}
7676

77-
fn pre_lock(this: &Arc<MutexMetadata>, read: bool) {
77+
// Returns whether we were a recursive lock (only relevant for read)
78+
fn _pre_lock(this: &Arc<MutexMetadata>, read: bool) -> bool {
79+
let mut inserted = false;
7880
MUTEXES_HELD.with(|held| {
7981
// For each mutex which is currently locked, check that no mutex's locked-before
8082
// set includes the mutex we're about to lock, which would imply a lockorder
@@ -101,9 +103,14 @@ impl MutexMetadata {
101103
this.locked_before.lock().unwrap().insert(Arc::clone(locked));
102104
}
103105
held.borrow_mut().insert(Arc::clone(this));
106+
inserted = true;
104107
});
108+
inserted
105109
}
106110

111+
fn pre_lock(this: &Arc<MutexMetadata>) { Self::_pre_lock(this, false); }
112+
fn pre_read_lock(this: &Arc<MutexMetadata>) -> bool { Self::_pre_lock(this, true) }
113+
107114
fn try_locked(this: &Arc<MutexMetadata>) {
108115
MUTEXES_HELD.with(|held| {
109116
// Since a try-lock will simply fail if the lock is held already, we do not
@@ -167,7 +174,7 @@ impl<T> Mutex<T> {
167174
}
168175

169176
pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
170-
MutexMetadata::pre_lock(&self.deps, false);
177+
MutexMetadata::pre_lock(&self.deps);
171178
self.inner.lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ())
172179
}
173180

@@ -187,6 +194,7 @@ pub struct RwLock<T: Sized> {
187194

188195
pub struct RwLockReadGuard<'a, T: Sized + 'a> {
189196
mutex: &'a RwLock<T>,
197+
first_lock :bool,
190198
lock: StdRwLockReadGuard<'a, T>,
191199
}
192200

@@ -205,6 +213,7 @@ impl<T: Sized> Deref for RwLockReadGuard<'_, T> {
205213

206214
impl<T: Sized> Drop for RwLockReadGuard<'_, T> {
207215
fn drop(&mut self) {
216+
if !self.first_lock { return; }
208217
MUTEXES_HELD.with(|held| {
209218
held.borrow_mut().remove(&self.mutex.deps);
210219
});
@@ -239,12 +248,12 @@ impl<T> RwLock<T> {
239248
}
240249

241250
pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
242-
MutexMetadata::pre_lock(&self.deps, true);
243-
self.inner.read().map(|lock| RwLockReadGuard { mutex: self, lock }).map_err(|_| ())
251+
let first_lock = MutexMetadata::pre_read_lock(&self.deps);
252+
self.inner.read().map(|lock| RwLockReadGuard { mutex: self, lock, first_lock }).map_err(|_| ())
244253
}
245254

246255
pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
247-
MutexMetadata::pre_lock(&self.deps, false);
256+
MutexMetadata::pre_lock(&self.deps);
248257
self.inner.write().map(|lock| RwLockWriteGuard { mutex: self, lock }).map_err(|_| ())
249258
}
250259

0 commit comments

Comments
 (0)