Skip to content

Commit f3c68a0

Browse files
committed
Add a test to ensure mutexes and rwlocks can't be re-locked
1 parent 960d1b7 commit f3c68a0

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

src/test/run-pass/issue-33770.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::process::{Command, Stdio};
12+
use std::env;
13+
use std::sync::{Mutex, RwLock};
14+
use std::time::Duration;
15+
use std::thread;
16+
17+
fn test_mutex() {
18+
let m = Mutex::new(0);
19+
let _g = m.lock().unwrap();
20+
let _g2 = m.lock().unwrap();
21+
}
22+
23+
fn test_try_mutex() {
24+
let m = Mutex::new(0);
25+
let _g = m.lock().unwrap();
26+
let _g2 = m.try_lock().unwrap();
27+
}
28+
29+
fn test_rwlock_ww() {
30+
let m = RwLock::new(0);
31+
let _g = m.write().unwrap();
32+
let _g2 = m.write().unwrap();
33+
}
34+
35+
fn test_try_rwlock_ww() {
36+
let m = RwLock::new(0);
37+
let _g = m.write().unwrap();
38+
let _g2 = m.try_write().unwrap();
39+
}
40+
41+
fn test_rwlock_rw() {
42+
let m = RwLock::new(0);
43+
let _g = m.read().unwrap();
44+
let _g2 = m.write().unwrap();
45+
}
46+
47+
fn test_try_rwlock_rw() {
48+
let m = RwLock::new(0);
49+
let _g = m.read().unwrap();
50+
let _g2 = m.try_write().unwrap();
51+
}
52+
53+
fn test_rwlock_wr() {
54+
let m = RwLock::new(0);
55+
let _g = m.write().unwrap();
56+
let _g2 = m.read().unwrap();
57+
}
58+
59+
fn test_try_rwlock_wr() {
60+
let m = RwLock::new(0);
61+
let _g = m.write().unwrap();
62+
let _g2 = m.try_read().unwrap();
63+
}
64+
65+
fn main() {
66+
let args: Vec<String> = env::args().collect();
67+
if args.len() > 1 {
68+
match &*args[1] {
69+
"mutex" => test_mutex(),
70+
"try_mutex" => test_try_mutex(),
71+
"rwlock_ww" => test_rwlock_ww(),
72+
"try_rwlock_ww" => test_try_rwlock_ww(),
73+
"rwlock_rw" => test_rwlock_rw(),
74+
"try_rwlock_rw" => test_try_rwlock_rw(),
75+
"rwlock_wr" => test_rwlock_wr(),
76+
"try_rwlock_wr" => test_try_rwlock_wr(),
77+
_ => unreachable!(),
78+
}
79+
// If we reach this point then the test failed
80+
println!("TEST FAILED: {}", args[1]);
81+
} else {
82+
let mut v = vec![];
83+
v.push(Command::new(&args[0]).arg("mutex").stderr(Stdio::null()).spawn().unwrap());
84+
v.push(Command::new(&args[0]).arg("try_mutex").stderr(Stdio::null()).spawn().unwrap());
85+
v.push(Command::new(&args[0]).arg("rwlock_ww").stderr(Stdio::null()).spawn().unwrap());
86+
v.push(Command::new(&args[0]).arg("try_rwlock_ww").stderr(Stdio::null()).spawn().unwrap());
87+
v.push(Command::new(&args[0]).arg("rwlock_rw").stderr(Stdio::null()).spawn().unwrap());
88+
v.push(Command::new(&args[0]).arg("try_rwlock_rw").stderr(Stdio::null()).spawn().unwrap());
89+
v.push(Command::new(&args[0]).arg("rwlock_wr").stderr(Stdio::null()).spawn().unwrap());
90+
v.push(Command::new(&args[0]).arg("try_rwlock_wr").stderr(Stdio::null()).spawn().unwrap());
91+
92+
thread::sleep(Duration::new(1, 0));
93+
94+
// Make sure all subprocesses either panicked or were killed because they deadlocked
95+
for mut c in v {
96+
c.kill().ok();
97+
assert!(!c.wait().unwrap().success());
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)