Skip to content

thread::Builder::spawn returns WouldBlock for EAGAIN #46345

Open
@jethrogb

Description

@jethrogb

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-linuxOperating system: LinuxP-lowLow priorityT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions