When trying to launch a thread and the thread limit is reached or there is not enough virtual address space available for another thread, thread::Builder::spawn returns an io::Error of kind WouldBlock.
extern crate libc;
fn main() {
unsafe {
libc::setrlimit(libc::RLIMIT_NPROC, &libc::rlimit { rlim_cur: 0, rlim_max: 0 });
}
let error = std::thread::Builder::new().spawn(|| unreachable!()).unwrap_err();
println!("I/O error kind {:?}: {:?}", error.kind(), error);
}
This prints (on Linux):
I/O error kind WouldBlock: Error { repr: Os { code: 11, message: "Resource temporarily unavailable" } }
WouldBlock means:
The operation needs to block to complete, but the blocking operation was requested to not occur.
This doesn't make a lot of sense in the context of thread creation. Yes, if the create call were to block until the thread/virtual address space limit is no longer reached, this error interpretation would be correct, but I know of no threading API (Windows or Linux) with these semantics.
The source of the problem is that the POSIX errors EAGAIN and EWOULDBLOCK may be defined as the same error value, and Rust chose to always interpret that as EWOULDBLOCK. I'm not sure what course of action I'd suggest to clear up the confusion.
(NB. On Windows, AFAICT there is no way to limit the number of threads, but when running out of virtual address space, CreateThread returns ERROR_NOT_ENOUGH_MEMORY, which gets decoded as kind Other)
When trying to launch a thread and the thread limit is reached or there is not enough virtual address space available for another thread,
thread::Builder::spawnreturns anio::Errorof kindWouldBlock.This prints (on Linux):
WouldBlock means:
This doesn't make a lot of sense in the context of thread creation. Yes, if the create call were to block until the thread/virtual address space limit is no longer reached, this error interpretation would be correct, but I know of no threading API (Windows or Linux) with these semantics.
The source of the problem is that the POSIX errors
EAGAINandEWOULDBLOCKmay be defined as the same error value, and Rust chose to always interpret that asEWOULDBLOCK. I'm not sure what course of action I'd suggest to clear up the confusion.(NB. On Windows, AFAICT there is no way to limit the number of threads, but when running out of virtual address space,
CreateThreadreturnsERROR_NOT_ENOUGH_MEMORY, which gets decoded as kindOther)