Skip to content

Commit 50070e4

Browse files
committed
fix: avoid deadlock in nested shell calls
1 parent 7587eb5 commit 50070e4

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

crates/common/src/io/macros.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,23 @@ macro_rules! sh_eprintln {
132132
#[macro_export]
133133
macro_rules! __sh_dispatch {
134134
($f:ident $fmt:literal $($args:tt)*) => {
135-
$crate::Shell::$f(&mut *$crate::Shell::get(), ::core::format_args!($fmt $($args)*))
135+
$crate::__sh_dispatch!(@impl $f &mut *$crate::Shell::get(), $fmt $($args)*)
136136
};
137137

138138
($f:ident $shell:expr, $($args:tt)*) => {
139-
$crate::Shell::$f($shell, ::core::format_args!($($args)*))
139+
$crate::__sh_dispatch!(@impl $f $shell, $($args)*)
140140
};
141141

142142
($f:ident $($args:tt)*) => {
143-
$crate::Shell::$f(&mut *$crate::Shell::get(), ::core::format_args!($($args)*))
143+
$crate::__sh_dispatch!(@impl $f &mut *$crate::Shell::get(), $($args)*)
144+
};
145+
146+
// Ensure that the global shell lock is held for as little time as possible.
147+
// Also avoids deadlocks in case of nested calls.
148+
(@impl $f:ident $shell:expr, $($args:tt)*) => {
149+
match ::core::format_args!($($args)*) {
150+
fmt => $crate::Shell::$f($shell, fmt),
151+
}
144152
};
145153
}
146154

@@ -168,6 +176,11 @@ mod tests {
168176
sh_eprintln!("eprintln")?;
169177
sh_eprintln!("eprintln {}", "arg")?;
170178

179+
sh_println!("{:?}", {
180+
sh_println!("hi")?;
181+
"nested"
182+
})?;
183+
171184
Ok(())
172185
}
173186

0 commit comments

Comments
 (0)