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();
166166/// configuration.
167167pub ( super ) fn global_registry ( ) -> & ' static Arc < Registry > {
168168 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+ } )
170176 . expect ( "The global thread pool has not been initialized." )
171177}
172178
@@ -192,8 +198,14 @@ where
192198 ) ) ;
193199
194200 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+ } )
197209 } ) ;
198210
199211 result
You can’t perform that action at this time.
0 commit comments