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 @@ -163,7 +163,13 @@ static THE_REGISTRY_SET: Once = Once::new();
163163/// configuration.
164164pub ( super ) fn global_registry ( ) -> & ' static Arc < Registry > {
165165 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+ } )
167173 . expect ( "The global thread pool has not been initialized." )
168174}
169175
@@ -189,8 +195,14 @@ where
189195 ) ) ;
190196
191197 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+ } )
194206 } ) ;
195207
196208 result
You can’t perform that action at this time.
0 commit comments