Skip to content

Commit 0e04c3b

Browse files
committed
fix:A closure invoked by iteration in a function call
1 parent 7adb3c5 commit 0e04c3b

File tree

9 files changed

+312
-105
lines changed

9 files changed

+312
-105
lines changed

example/double_lock/src/main.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
use std::sync::{Arc, Mutex};
2+
use std::thread;
3+
24
fn main() {
35
let mu1 = Arc::new(Mutex::new(1));
6+
let mu2 = mu1.clone();
47
//loop {
5-
let g1 = mu1.lock();
6-
let g2 = mu1.lock();
8+
let g1 = mu1.lock().unwrap();
9+
10+
// let g2 = mu1.lock();
11+
12+
let th1 = thread::spawn(move || {
13+
let mut g2 = mu2.lock().unwrap();
14+
*g2 = 2;
15+
});
716

8-
println!("unreachable!");
17+
th1.join().unwrap();
918
}

example/rayon-deadlock/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

example/rayon-deadlock/Cargo.lock

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/rayon-deadlock/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "rayon-deadlock"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
rayon = "1.0"

example/rayon-deadlock/src/main.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use rayon::prelude::*;
2+
use std::sync::{Arc, Mutex};
3+
4+
fn main() {
5+
let data = Arc::new(Mutex::new(0));
6+
7+
let lock = data.lock().unwrap();
8+
9+
rayon::join(
10+
|| {
11+
let mut guard = data.lock().unwrap();
12+
*guard += 1;
13+
},
14+
|| {
15+
let mut guard = data.lock().unwrap();
16+
*guard += 1;
17+
},
18+
);
19+
}

rust-toolchain.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[toolchain]
2-
channel = "nightly"
2+
channel = "nightly-2024-12-11"
3+
components = ["rustc-dev", "rust-src", "llvm-tools-preview"]

src/graph/callgraph.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub enum CallSiteLocation {
2929
location: Location,
3030
destination: Local, // spawn 返回的 JoinHandle 存储位置
3131
},
32+
RayonJoin,
3233
}
3334

3435
impl CallSiteLocation {
@@ -288,7 +289,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CallSiteCollector<'a, 'tcx> {
288289

289290
if let ty::FnDef(def_id, substs) = *func_ty.kind() {
290291
let fn_path = self.tcx.def_path_str(def_id);
291-
if fn_path.contains("::spawn") {
292+
if fn_path.contains("thread::spawn") {
292293
// 获取第一个参数(闭包)
293294
if let Some(closure_arg) = args.first() {
294295
let closure_ty = match closure_arg.node {
@@ -320,6 +321,30 @@ impl<'a, 'tcx> Visitor<'tcx> for CallSiteCollector<'a, 'tcx> {
320321
}
321322
}
322323

324+
if fn_path.contains("rayon_core::join") {
325+
for arg in args {
326+
if let Operand::Move(place) | Operand::Copy(place) = arg.node {
327+
let place_ty = place.ty(self.body, self.tcx).ty;
328+
if let ty::Closure(closure_def_id, _) | ty::FnDef(closure_def_id, _) =
329+
place_ty.kind()
330+
{
331+
if let Some(callee) = Instance::try_resolve(
332+
self.tcx,
333+
typing_env,
334+
*closure_def_id,
335+
substs,
336+
)
337+
.ok()
338+
.flatten()
339+
{
340+
self.callsites.push((callee, CallSiteLocation::RayonJoin));
341+
}
342+
}
343+
}
344+
}
345+
return;
346+
}
347+
323348
// 处理普通函数调用
324349
if let Some(callee) = Instance::try_resolve(self.tcx, typing_env, def_id, substs)
325350
.ok()

0 commit comments

Comments
 (0)