mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 14:45:56 +02:00
Fix (and test) for a deadlock that can happen while waiting for protocol info (#12633)
# Description The local socket PR introduced a `Waitable` type, which could either hold a value or be waited on until a value is available. Unlike a channel, it would always return that value once set. However, one issue with this design was that there was no way to detect whether a value would ever be written. This splits the writer into a different type `WaitableMut`, so that when it is dropped, waiting threads can fail (because they'll never get a value). # Tests + Formatting A test has been added to `stress_internals` to make sure this fails in the right way. - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib`
This commit is contained in:
@ -1,3 +1,5 @@
|
||||
use std::{sync::mpsc, time::Duration};
|
||||
|
||||
use nu_test_support::nu_with_plugins;
|
||||
|
||||
fn ensure_stress_env_vars_unset() {
|
||||
@ -75,6 +77,30 @@ fn test_failing_local_socket_fallback() {
|
||||
assert!(result.out.contains("local_socket_path: None"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exit_before_hello_stdio() {
|
||||
ensure_stress_env_vars_unset();
|
||||
// This can deadlock if not handled properly, so we try several times and timeout
|
||||
for _ in 0..5 {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
std::thread::spawn(move || {
|
||||
let result = nu_with_plugins!(
|
||||
cwd: ".",
|
||||
envs: vec![
|
||||
("STRESS_EXIT_BEFORE_HELLO", "1"),
|
||||
],
|
||||
plugin: ("nu_plugin_stress_internals"),
|
||||
"stress_internals"
|
||||
);
|
||||
let _ = tx.send(result);
|
||||
});
|
||||
let result = rx
|
||||
.recv_timeout(Duration::from_secs(15))
|
||||
.expect("timed out. probably a deadlock");
|
||||
assert!(!result.status.success());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exit_early_stdio() {
|
||||
ensure_stress_env_vars_unset();
|
||||
|
Reference in New Issue
Block a user