Skip to content

Commit

Permalink
Rollup merge of #81546 - hyd-dev:libtest-run-out-of-threads, r=Mark-S…
Browse files Browse the repository at this point in the history
…imulacrum

[libtest] Run the test synchronously when hitting thread limit

libtest currently panics if it hits the thread limit. This often results in spurious test failures (<code>thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }'</code> ... `error: test failed, to rerun pass '--lib'`). This PR makes it continue to run the test synchronously if it runs out of threads.

Closes #78165.

``@rustbot`` label: A-libtest T-libs
  • Loading branch information
Dylan-DPC authored Feb 18, 2021
2 parents cb2effd + 43aed74 commit 55ab2e3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
13 changes: 12 additions & 1 deletion library/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,18 @@ pub fn run_test(
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_arch = "wasm32");
if concurrency == Concurrent::Yes && supports_threads {
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
Some(cfg.spawn(runtest).unwrap())
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
let runtest2 = runtest.clone();
match cfg.spawn(move || runtest2.lock().unwrap().take().unwrap()()) {
Ok(handle) => Some(handle),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
// `ErrorKind::WouldBlock` means hitting the thread limit on some
// platforms, so run the test synchronously here instead.
Arc::get_mut(&mut runtest).unwrap().get_mut().unwrap().take().unwrap()();
None
}
Err(e) => panic!("failed to spawn thread to run test: {}", e),
}
} else {
runtest();
None
Expand Down
7 changes: 7 additions & 0 deletions src/test/run-make/libtest-thread-limit/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-include ../../run-make-fulldeps/tools.mk

# only-linux

all:
$(RUSTC) test.rs --test --target $(TARGET)
$(shell ulimit -p 0 && $(call RUN,test))
16 changes: 16 additions & 0 deletions src/test/run-make/libtest-thread-limit/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![feature(once_cell)]

use std::{io::ErrorKind, lazy::SyncOnceCell, thread::{self, Builder, ThreadId}};

static THREAD_ID: SyncOnceCell<ThreadId> = SyncOnceCell::new();

#[test]
fn spawn_thread_would_block() {
assert_eq!(Builder::new().spawn(|| unreachable!()).unwrap_err().kind(), ErrorKind::WouldBlock);
THREAD_ID.set(thread::current().id()).unwrap();
}

#[test]
fn run_in_same_thread() {
assert_eq!(*THREAD_ID.get().unwrap(), thread::current().id());
}

0 comments on commit 55ab2e3

Please sign in to comment.