File tree Expand file tree Collapse file tree 1 file changed +15
-3
lines changed Expand file tree Collapse file tree 1 file changed +15
-3
lines changed Original file line number Diff line number Diff line change @@ -166,7 +166,13 @@ static THE_REGISTRY_SET: Once = Once::new();
166
166
/// configuration.
167
167
pub ( super ) fn global_registry ( ) -> & ' static Arc < Registry > {
168
168
set_global_registry ( default_global_registry)
169
- . or_else ( |err| unsafe { THE_REGISTRY . as_ref ( ) . ok_or ( err) } )
169
+ . or_else ( |err| {
170
+ // SAFETY: we only create a shared reference to `THE_REGISTRY` after the `call_once`
171
+ // that initializes it, and there will be no more mutable accesses at all.
172
+ debug_assert ! ( THE_REGISTRY_SET . is_completed( ) ) ;
173
+ let the_registry = unsafe { & * ptr:: addr_of!( THE_REGISTRY ) } ;
174
+ the_registry. as_ref ( ) . ok_or ( err)
175
+ } )
170
176
. expect ( "The global thread pool has not been initialized." )
171
177
}
172
178
@@ -192,8 +198,14 @@ where
192
198
) ) ;
193
199
194
200
THE_REGISTRY_SET . call_once ( || {
195
- result = registry ( )
196
- . map ( |registry : Arc < Registry > | unsafe { & * THE_REGISTRY . get_or_insert ( registry) } )
201
+ result = registry ( ) . map ( |registry : Arc < Registry > | {
202
+ // SAFETY: this is the only mutable access to `THE_REGISTRY`, thanks to `Once`, and
203
+ // `global_registry()` only takes a shared reference **after** this `call_once`.
204
+ unsafe {
205
+ ptr:: addr_of_mut!( THE_REGISTRY ) . write ( Some ( registry) ) ;
206
+ ( * ptr:: addr_of!( THE_REGISTRY ) ) . as_ref ( ) . unwrap_unchecked ( )
207
+ }
208
+ } )
197
209
} ) ;
198
210
199
211
result
You can’t perform that action at this time.
0 commit comments