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