Skip to content

Commit

Permalink
Don't attempt to cleanup Mutex when threads are deadlocked
Browse files Browse the repository at this point in the history
  • Loading branch information
shelbyd committed Oct 29, 2021
1 parent 0d7f0d5 commit 6751206
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/rt/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ impl Mutex {
// Release the lock flag
state.lock = None;

// Execution has deadlocked, cleanup does not matter.
if !execution.threads.is_active() {
return;
}

state
.synchronize
.sync_store(&mut execution.threads, Release);
Expand Down
38 changes: 38 additions & 0 deletions tests/deadlock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// #![deny(warnings, rust_2018_idioms)]

use loom::sync::Mutex;
use loom::thread;

use std::rc::Rc;

#[test]
#[should_panic]
fn two_mutexes_deadlock() {
loom::model(|| {
let a = Rc::new(Mutex::new(1));
let b = Rc::new(Mutex::new(2));

let th1 = {
let a = a.clone();
let b = b.clone();

thread::spawn(move || {
let a_lock = a.lock().unwrap();
let b_lock = b.lock().unwrap();
assert_eq!(*a_lock + *b_lock, 3);
})
};
let th2 = {
let a = a.clone();
let b = b.clone();

thread::spawn(move || {
let b_lock = b.lock().unwrap();
let a_lock = a.lock().unwrap();
assert_eq!(*a_lock + *b_lock, 3);
})
};
th1.join().unwrap();
th2.join().unwrap();
});
}

0 comments on commit 6751206

Please sign in to comment.