1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
pub use jobserver_crate::Client;
use std::sync::LazyLock;

// We can only call `from_env` once per process

// Note that this is unsafe because it may misinterpret file descriptors
// on Unix as jobserver file descriptors. We hopefully execute this near
// the beginning of the process though to ensure we don't get false
// positives, or in other words we try to execute this before we open
// any file descriptors ourselves.
//
// Pick a "reasonable maximum" if we don't otherwise have
// a jobserver in our environment, capping out at 32 so we
// don't take everything down by hogging the process run queue.
// The fixed number is used to have deterministic compilation
// across machines.
//
// Also note that we stick this in a global because there could be
// multiple rustc instances in this process, and the jobserver is
// per-process.
static GLOBAL_CLIENT: LazyLock<Client> = LazyLock::new(|| unsafe {
    Client::from_env().unwrap_or_else(|| {
        let client = Client::new(32).expect("failed to create jobserver");
        // Acquire a token for the main thread which we can release later
        client.acquire_raw().ok();
        client
    })
});

pub fn client() -> Client {
    GLOBAL_CLIENT.clone()
}

pub fn acquire_thread() {
    GLOBAL_CLIENT.acquire_raw().ok();
}

pub fn release_thread() {
    GLOBAL_CLIENT.release_raw().ok();
}