|
1 |
| -use jobserver::{Acquired, HelperThread}; |
| 1 | +use jobserver::{Acquired, Client, HelperThread}; |
2 | 2 | use std::{
|
3 | 3 | env,
|
4 | 4 | sync::{
|
@@ -40,15 +40,17 @@ impl JobToken {
|
40 | 40 | /// gives out tokens without exposing whether they're implicit tokens or tokens from jobserver.
|
41 | 41 | /// Furthermore, instead of giving up job tokens, it keeps them around
|
42 | 42 | /// 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 { |
44 | 44 | helper: HelperThread,
|
45 | 45 | tx: Sender<Option<Acquired>>,
|
46 | 46 | rx: Receiver<Option<Acquired>>,
|
47 | 47 | }
|
48 | 48 |
|
49 | 49 | 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> { |
52 | 54 | let (tx, rx) = mpsc::channel();
|
53 | 55 | // Push the implicit token. Since JobTokens only give back what they got,
|
54 | 56 | // there should be at most one global implicit token in the wild.
|
@@ -76,21 +78,27 @@ impl JobTokenServer {
|
76 | 78 | }
|
77 | 79 | }
|
78 | 80 |
|
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 { |
82 | 89 | static INIT: Once = Once::new();
|
83 |
| - static mut JOBSERVER: Option<jobserver::Client> = None; |
| 90 | + static mut JOBSERVER: Option<JobTokenServer> = None; |
84 | 91 |
|
85 | 92 | fn _assert_sync<T: Sync>() {}
|
86 | 93 | _assert_sync::<jobserver::Client>();
|
87 | 94 |
|
88 | 95 | unsafe {
|
89 | 96 | INIT.call_once(|| {
|
90 | 97 | let server = default_jobserver();
|
91 |
| - JOBSERVER = Some(server); |
| 98 | + JOBSERVER = |
| 99 | + Some(JobTokenServer::new_inner(server).expect("Job server initialization failed")); |
92 | 100 | });
|
93 |
| - JOBSERVER.clone().unwrap() |
| 101 | + JOBSERVER.as_ref().unwrap() |
94 | 102 | }
|
95 | 103 | }
|
96 | 104 |
|
|
0 commit comments