Skip to content

Commit d55c382

Browse files
committed
Use shared global JobTokenServer
1 parent 280c673 commit d55c382

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

src/job_token.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use jobserver::{Acquired, HelperThread};
1+
use jobserver::{Acquired, Client, HelperThread};
22
use std::{
33
env,
44
sync::{
@@ -40,15 +40,17 @@ impl JobToken {
4040
/// gives out tokens without exposing whether they're implicit tokens or tokens from jobserver.
4141
/// Furthermore, instead of giving up job tokens, it keeps them around
4242
/// for reuse if we know we're going to request another token after freeing the current one.
43-
pub(crate) struct GlobalJobTokenServer {
43+
pub(crate) struct JobTokenServer {
4444
helper: HelperThread,
4545
tx: Sender<Option<Acquired>>,
4646
rx: Receiver<Option<Acquired>>,
4747
}
4848

4949
impl JobTokenServer {
50-
pub(crate) fn new() -> Result<Self, crate::Error> {
51-
let client = jobserver();
50+
pub(crate) fn new() -> &'static Self {
51+
jobserver()
52+
}
53+
fn new_inner(client: Client) -> Result<Self, crate::Error> {
5254
let (tx, rx) = mpsc::channel();
5355
// Push the implicit token. Since JobTokens only give back what they got,
5456
// there should be at most one global implicit token in the wild.
@@ -76,21 +78,27 @@ impl JobTokenServer {
7678
}
7779
}
7880

79-
/// Returns a suitable `jobserver::Client` used to coordinate
80-
/// parallelism between build scripts.
81-
fn jobserver() -> jobserver::Client {
81+
/// Returns a suitable `JobTokenServer` used to coordinate
82+
/// parallelism between build scripts. A global `JobTokenServer` is used as this ensures
83+
/// that only one implicit job token is used in the wild.
84+
/// Having multiple separate job token servers would lead to each of them assuming that they have control
85+
/// over the implicit job token.
86+
/// As it stands, each caller of `jobserver` can receive an implicit job token and there will be at most
87+
/// one implicit job token in the wild.
88+
fn jobserver() -> &'static JobTokenServer {
8289
static INIT: Once = Once::new();
83-
static mut JOBSERVER: Option<jobserver::Client> = None;
90+
static mut JOBSERVER: Option<JobTokenServer> = None;
8491

8592
fn _assert_sync<T: Sync>() {}
8693
_assert_sync::<jobserver::Client>();
8794

8895
unsafe {
8996
INIT.call_once(|| {
9097
let server = default_jobserver();
91-
JOBSERVER = Some(server);
98+
JOBSERVER =
99+
Some(JobTokenServer::new_inner(server).expect("Job server initialization failed"));
92100
});
93-
JOBSERVER.clone().unwrap()
101+
JOBSERVER.as_ref().unwrap()
94102
}
95103
}
96104

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,7 @@ impl Build {
13061306
}
13071307

13081308
// Limit our parallelism globally with a jobserver.
1309-
let tokens = crate::job_token::JobTokenServer::new()?;
1309+
let tokens = crate::job_token::JobTokenServer::new();
13101310

13111311
// When compiling objects in parallel we do a few dirty tricks to speed
13121312
// things up:

0 commit comments

Comments
 (0)