| 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(); |
| } |