@@ -51,6 +51,7 @@ pub fn parallel_prime_caches(
51
51
enum ParallelPrimeCacheWorkerProgress {
52
52
BeginCrate { crate_id : Crate , crate_name : Symbol } ,
53
53
EndCrate { crate_id : Crate } ,
54
+ Cancelled ( Cancelled ) ,
54
55
}
55
56
56
57
// We split off def map computation from other work,
@@ -71,26 +72,32 @@ pub fn parallel_prime_caches(
71
72
progress_sender
72
73
. send ( ParallelPrimeCacheWorkerProgress :: BeginCrate { crate_id, crate_name } ) ?;
73
74
74
- match kind {
75
+ let cancelled = Cancelled :: catch ( || match kind {
75
76
PrimingPhase :: DefMap => _ = db. crate_def_map ( crate_id) ,
76
77
PrimingPhase :: ImportMap => _ = db. import_map ( crate_id) ,
77
78
PrimingPhase :: CrateSymbols => _ = db. crate_symbols ( crate_id. into ( ) ) ,
78
- }
79
+ } ) ;
79
80
80
- progress_sender. send ( ParallelPrimeCacheWorkerProgress :: EndCrate { crate_id } ) ?;
81
+ match cancelled {
82
+ Ok ( ( ) ) => progress_sender
83
+ . send ( ParallelPrimeCacheWorkerProgress :: EndCrate { crate_id } ) ?,
84
+ Err ( cancelled) => progress_sender
85
+ . send ( ParallelPrimeCacheWorkerProgress :: Cancelled ( cancelled) ) ?,
86
+ }
81
87
}
82
88
83
89
Ok :: < _ , crossbeam_channel:: SendError < _ > > ( ( ) )
84
90
} ;
85
91
86
92
for id in 0 ..num_worker_threads {
87
- let worker = prime_caches_worker. clone ( ) ;
88
- let db = db. snapshot ( ) ;
89
-
90
93
stdx:: thread:: Builder :: new ( stdx:: thread:: ThreadIntent :: Worker )
91
94
. allow_leak ( true )
92
95
. name ( format ! ( "PrimeCaches#{id}" ) )
93
- . spawn ( move || Cancelled :: catch ( || worker ( db. snapshot ( ) ) ) )
96
+ . spawn ( {
97
+ let worker = prime_caches_worker. clone ( ) ;
98
+ let db = db. clone ( ) ;
99
+ move || worker ( db)
100
+ } )
94
101
. expect ( "failed to spawn thread" ) ;
95
102
}
96
103
@@ -142,9 +149,14 @@ pub fn parallel_prime_caches(
142
149
continue ;
143
150
}
144
151
Err ( crossbeam_channel:: RecvTimeoutError :: Disconnected ) => {
145
- // our workers may have died from a cancelled task, so we'll check and re-raise here.
146
- db. unwind_if_revision_cancelled ( ) ;
147
- break ;
152
+ // all our workers have exited, mark us as finished and exit
153
+ cb ( ParallelPrimeCachesProgress {
154
+ crates_currently_indexing : vec ! [ ] ,
155
+ crates_done,
156
+ crates_total : crates_done,
157
+ work_type : "Indexing" ,
158
+ } ) ;
159
+ return ;
148
160
}
149
161
} ;
150
162
match worker_progress {
@@ -156,6 +168,10 @@ pub fn parallel_prime_caches(
156
168
crates_to_prime. mark_done ( crate_id) ;
157
169
crates_done += 1 ;
158
170
}
171
+ ParallelPrimeCacheWorkerProgress :: Cancelled ( cancelled) => {
172
+ // Cancelled::throw should probably be public
173
+ std:: panic:: resume_unwind ( Box :: new ( cancelled) ) ;
174
+ }
159
175
} ;
160
176
161
177
let progress = ParallelPrimeCachesProgress {
@@ -186,9 +202,14 @@ pub fn parallel_prime_caches(
186
202
continue ;
187
203
}
188
204
Err ( crossbeam_channel:: RecvTimeoutError :: Disconnected ) => {
189
- // our workers may have died from a cancelled task, so we'll check and re-raise here.
190
- db. unwind_if_revision_cancelled ( ) ;
191
- break ;
205
+ // all our workers have exited, mark us as finished and exit
206
+ cb ( ParallelPrimeCachesProgress {
207
+ crates_currently_indexing : vec ! [ ] ,
208
+ crates_done,
209
+ crates_total : crates_done,
210
+ work_type : "Populating symbols" ,
211
+ } ) ;
212
+ return ;
192
213
}
193
214
} ;
194
215
match worker_progress {
@@ -199,6 +220,10 @@ pub fn parallel_prime_caches(
199
220
crates_currently_indexing. swap_remove ( & crate_id) ;
200
221
crates_done += 1 ;
201
222
}
223
+ ParallelPrimeCacheWorkerProgress :: Cancelled ( cancelled) => {
224
+ // Cancelled::throw should probably be public
225
+ std:: panic:: resume_unwind ( Box :: new ( cancelled) ) ;
226
+ }
202
227
} ;
203
228
204
229
let progress = ParallelPrimeCachesProgress {
0 commit comments