rustc_data_structures/
jobserver.rs
1use std::sync::{LazyLock, OnceLock};
2
3pub use jobserver_crate::{Acquired, Client, HelperThread};
4use jobserver_crate::{FromEnv, FromEnvErrorKind};
5
6static GLOBAL_CLIENT: LazyLock<Result<Client, String>> = LazyLock::new(|| {
11 let FromEnv { client, var } = unsafe { Client::from_env_ext(true) };
17
18 let error = match client {
19 Ok(client) => return Ok(client),
20 Err(e) => e,
21 };
22
23 if matches!(
24 error.kind(),
25 FromEnvErrorKind::NoEnvVar
26 | FromEnvErrorKind::NoJobserver
27 | FromEnvErrorKind::NegativeFd
28 | FromEnvErrorKind::Unsupported
29 ) {
30 return Ok(default_client());
31 }
32
33 let (name, value) = var.unwrap();
36 Err(format!(
37 "failed to connect to jobserver from environment variable `{name}={:?}`: {error}",
38 value
39 ))
40});
41
42fn default_client() -> Client {
44 let client = Client::new(32).expect("failed to create jobserver");
48
49 client.acquire_raw().ok();
51
52 client
53}
54
55static GLOBAL_CLIENT_CHECKED: OnceLock<Client> = OnceLock::new();
56
57pub fn initialize_checked(report_warning: impl FnOnce(&'static str)) {
58 let client_checked = match &*GLOBAL_CLIENT {
59 Ok(client) => client.clone(),
60 Err(e) => {
61 report_warning(e);
62 default_client()
63 }
64 };
65 GLOBAL_CLIENT_CHECKED.set(client_checked).ok();
66}
67
68const ACCESS_ERROR: &str = "jobserver check should have been called earlier";
69
70pub fn client() -> Client {
71 GLOBAL_CLIENT_CHECKED.get().expect(ACCESS_ERROR).clone()
72}
73
74pub fn acquire_thread() {
75 GLOBAL_CLIENT_CHECKED.get().expect(ACCESS_ERROR).acquire_raw().ok();
76}
77
78pub fn release_thread() {
79 GLOBAL_CLIENT_CHECKED.get().expect(ACCESS_ERROR).release_raw().ok();
80}