1
- use jobserver_crate:: { Client , HelperThread , Acquired } ;
1
+ use jobserver_crate:: Client ;
2
2
use 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
- }
87
3
88
4
lazy_static ! {
89
5
// We can only call `from_env` once per process
@@ -105,52 +21,22 @@ lazy_static! {
105
21
// per-process.
106
22
static ref GLOBAL_CLIENT : Client = unsafe {
107
23
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
109
28
} )
110
29
} ;
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
- } ;
122
30
}
123
31
124
32
pub fn client ( ) -> Client {
125
33
GLOBAL_CLIENT . clone ( )
126
34
}
127
35
128
36
pub fn acquire_thread ( ) {
129
- GLOBAL_PROXY . acquire_token ( ) ;
37
+ GLOBAL_CLIENT . acquire_raw ( ) . ok ( ) ;
130
38
}
131
39
132
40
pub 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 ( ) ;
156
42
}
0 commit comments