1- use  jobserver_crate:: { Client ,   HelperThread ,   Acquired } ; 
1+ use  jobserver_crate:: Client ; 
22use  lazy_static:: lazy_static; 
3- use  std:: sync:: { Condvar ,  Arc ,  Mutex } ; 
4- use  std:: mem; 
5- 
6- #[ derive( Default ) ]  
7- struct  LockedProxyData  { 
8-     /// The number of free thread tokens, this may include the implicit token given to the process 
9- free :  usize , 
10- 
11-     /// The number of threads waiting for a token 
12- waiters :  usize , 
13- 
14-     /// The number of tokens we requested from the server 
15- requested :  usize , 
16- 
17-     /// Stored tokens which will be dropped when we no longer need them 
18- tokens :  Vec < Acquired > , 
19- } 
20- 
21- impl  LockedProxyData  { 
22-     fn  request_token ( & mut  self ,  thread :  & Mutex < HelperThread > )  { 
23-         self . requested  += 1 ; 
24-         thread. lock ( ) . unwrap ( ) . request_token ( ) ; 
25-     } 
26- 
27-     fn  release_token ( & mut  self ,  cond_var :  & Condvar )  { 
28-         if  self . waiters  > 0  { 
29-             self . free  += 1 ; 
30-             cond_var. notify_one ( ) ; 
31-         }  else  { 
32-             if  self . tokens . is_empty ( )  { 
33-                 // We are returning the implicit token 
34-                 self . free  += 1 ; 
35-             }  else  { 
36-                 // Return a real token to the server 
37-                 self . tokens . pop ( ) . unwrap ( ) ; 
38-             } 
39-         } 
40-     } 
41- 
42-     fn  take_token ( & mut  self ,  thread :  & Mutex < HelperThread > )  -> bool  { 
43-         if  self . free  > 0  { 
44-             self . free  -= 1 ; 
45-             self . waiters  -= 1 ; 
46- 
47-             // We stole some token reqested by someone else 
48-             // Request another one 
49-             if  self . requested  + self . free  < self . waiters  { 
50-                 self . request_token ( thread) ; 
51-             } 
52- 
53-             true 
54-         }  else  { 
55-             false 
56-         } 
57-     } 
58- 
59-     fn  new_requested_token ( & mut  self ,  token :  Acquired ,  cond_var :  & Condvar )  { 
60-         self . requested  -= 1 ; 
61- 
62-         // Does anything need this token? 
63-         if  self . waiters  > 0  { 
64-             self . free  += 1 ; 
65-             self . tokens . push ( token) ; 
66-             cond_var. notify_one ( ) ; 
67-         }  else  { 
68-             // Otherwise we'll just drop it 
69-             mem:: drop ( token) ; 
70-         } 
71-     } 
72- } 
73- 
74- #[ derive( Default ) ]  
75- struct  ProxyData  { 
76-     lock :  Mutex < LockedProxyData > , 
77-     cond_var :  Condvar , 
78- } 
79- 
80- /// A helper type which makes managing jobserver tokens easier. 
81- /// It also allows you to treat the implicit token given to the process 
82- /// in the same manner as requested tokens. 
83- struct  Proxy  { 
84-     thread :  Mutex < HelperThread > , 
85-     data :  Arc < ProxyData > , 
86- } 
873
884lazy_static !  { 
895    // We can only call `from_env` once per process 
@@ -105,52 +21,22 @@ lazy_static! {
10521    // per-process. 
10622    static  ref GLOBAL_CLIENT :  Client  = unsafe  { 
10723        Client :: from_env( ) . unwrap_or_else( || { 
108-             Client :: new( 32 ) . expect( "failed to create jobserver" ) 
24+             let  client = Client :: new( 32 ) . expect( "failed to create jobserver" ) ; 
25+             // Acquire a token for the main thread which we can release later 
26+             client. acquire_raw( ) . ok( ) ; 
27+             client
10928        } ) 
11029    } ; 
111- 
112-     static  ref GLOBAL_PROXY :  Proxy  = { 
113-         let  data = Arc :: new( ProxyData :: default ( ) ) ; 
114- 
115-         Proxy  { 
116-             data:  data. clone( ) , 
117-             thread:  Mutex :: new( client( ) . into_helper_thread( move |token| { 
118-                 data. lock. lock( ) . unwrap( ) . new_requested_token( token. unwrap( ) ,  & data. cond_var) ; 
119-             } ) . unwrap( ) ) , 
120-         } 
121-     } ; 
12230} 
12331
12432pub  fn  client ( )  -> Client  { 
12533    GLOBAL_CLIENT . clone ( ) 
12634} 
12735
12836pub  fn  acquire_thread ( )  { 
129-     GLOBAL_PROXY . acquire_token ( ) ; 
37+     GLOBAL_CLIENT . acquire_raw ( ) . ok ( ) ; 
13038} 
13139
13240pub  fn  release_thread ( )  { 
133-     GLOBAL_PROXY . release_token ( ) ; 
134- } 
135- 
136- impl  Proxy  { 
137-     fn  release_token ( & self )  { 
138-         self . data . lock . lock ( ) . unwrap ( ) . release_token ( & self . data . cond_var ) ; 
139-     } 
140- 
141-     fn  acquire_token ( & self )  { 
142-         let  mut  data = self . data . lock . lock ( ) . unwrap ( ) ; 
143-         data. waiters  += 1 ; 
144-         if  data. take_token ( & self . thread )  { 
145-             return ; 
146-         } 
147-         // Request a token for us 
148-         data. request_token ( & self . thread ) ; 
149-         loop  { 
150-             data = self . data . cond_var . wait ( data) . unwrap ( ) ; 
151-             if  data. take_token ( & self . thread )  { 
152-                 return ; 
153-             } 
154-         } 
155-     } 
41+     GLOBAL_CLIENT . release_raw ( ) . ok ( ) ; 
15642} 
0 commit comments