@@ -8,7 +8,7 @@ use crate::bindings::{
88} ;
99use crate :: zend:: zai_str_from_zstr;
1010use core:: fmt:: { Display , Formatter } ;
11- use core:: mem:: { swap , transmute, MaybeUninit } ;
11+ use core:: mem:: transmute;
1212use core:: ptr;
1313use core:: str:: FromStr ;
1414use libc:: { c_char, c_int} ;
@@ -41,16 +41,25 @@ pub struct SystemSettings {
4141}
4242
4343impl SystemSettings {
44- pub fn disable_all ( & mut self ) {
45- self . profiling_enabled = false ;
46- self . profiling_experimental_features_enabled = false ;
47- self . profiling_endpoint_collection_enabled = false ;
48- self . profiling_experimental_cpu_time_enabled = false ;
49- self . profiling_allocation_enabled = false ;
50- self . profiling_timeline_enabled = false ;
51- self . profiling_exception_enabled = false ;
52- self . profiling_exception_message_enabled = false ;
53- self . profiling_io_enabled = false ;
44+ /// Provides "initial" settings, which are all "off"-like values.
45+ pub const fn initial ( ) -> SystemSettings {
46+ SystemSettings {
47+ profiling_enabled : false ,
48+ profiling_experimental_features_enabled : false ,
49+ profiling_endpoint_collection_enabled : false ,
50+ profiling_experimental_cpu_time_enabled : false ,
51+ profiling_allocation_enabled : false ,
52+ profiling_allocation_sampling_distance : u32:: MAX ,
53+ profiling_timeline_enabled : false ,
54+ profiling_exception_enabled : false ,
55+ profiling_exception_message_enabled : false ,
56+ profiling_wall_time_enabled : false ,
57+ profiling_io_enabled : false ,
58+ output_pprof : None ,
59+ profiling_exception_sampling_distance : u32:: MAX ,
60+ profiling_log_level : LevelFilter :: Off ,
61+ uri : AgentEndpoint :: Socket ( Cow :: Borrowed ( AgentEndpoint :: DEFAULT_UNIX_SOCKET_PATH ) ) ,
62+ }
5463 }
5564
5665 /// # Safety
@@ -83,15 +92,16 @@ impl SystemSettings {
8392 }
8493}
8594
86- static mut SYSTEM_SETTINGS : MaybeUninit < SystemSettings > = MaybeUninit :: uninit ( ) ;
95+ static mut SYSTEM_SETTINGS : SystemSettings = SystemSettings :: initial ( ) ;
8796
8897impl SystemSettings {
89- /// # Safety
90- /// Must be called after [first_rinit] and before [shutdown].
91- pub unsafe fn get ( ) -> ptr:: NonNull < SystemSettings > {
92- // SAFETY: required by this function's own safety requirements.
93- let addr = unsafe { ( * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ) . assume_init_mut ( ) } ;
94- ptr:: NonNull :: from ( addr)
98+ /// Returns the "current" system settings, which are always memory-safe
99+ /// but may point to "initial" values rather than the configured ones,
100+ /// depending on what point in the lifecycle we're at.
101+ pub const fn get ( ) -> ptr:: NonNull < SystemSettings > {
102+ let addr = ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ;
103+ // SAFETY: it's derived from a static variable, it's not null.
104+ unsafe { ptr:: NonNull :: new_unchecked ( addr) }
95105 }
96106
97107 /// # Safety
@@ -110,10 +120,6 @@ impl SystemSettings {
110120 }
111121 }
112122
113- // Initialize the lazy lock holding the env var for new origin
114- // detection in a safe place.
115- _ = std:: sync:: LazyLock :: force ( & libdd_common:: entity_id:: DD_EXTERNAL_ENV ) ;
116-
117123 // Work around version-specific issues.
118124 #[ cfg( not( php_zend_mm_set_custom_handlers_ex) ) ]
119125 if allocation:: allocation_le83:: first_rinit_should_disable_due_to_jit ( ) {
@@ -123,54 +129,21 @@ impl SystemSettings {
123129 if allocation:: allocation_ge84:: first_rinit_should_disable_due_to_jit ( ) {
124130 system_settings. profiling_allocation_enabled = false ;
125131 }
126- swap (
127- & mut system_settings,
128- ( * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ) . assume_init_mut ( ) ,
129- ) ;
130- }
131132
132- /// # Safety
133- /// Must be called exactly once each startup in either minit or startup,
134- /// whether profiling is enabled or not.
135- unsafe fn on_startup ( ) {
136- ( * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ) . write ( INITIAL_SYSTEM_SETTINGS . clone ( ) ) ;
133+ ptr:: addr_of_mut!( SYSTEM_SETTINGS ) . swap ( & mut system_settings) ;
137134 }
138135
139136 /// # Safety
140137 /// Must be called exactly once per shutdown in either mshutdown or
141138 /// shutdown, before zai config is shutdown.
142139 unsafe fn on_shutdown ( ) {
143- let system_settings = ( * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ) . assume_init_mut ( ) ;
144- * system_settings = SystemSettings {
145- profiling_enabled : false ,
146- profiling_experimental_features_enabled : false ,
147- profiling_endpoint_collection_enabled : false ,
148- profiling_experimental_cpu_time_enabled : false ,
149- profiling_allocation_enabled : false ,
150- profiling_allocation_sampling_distance : 0 ,
151- profiling_timeline_enabled : false ,
152- profiling_exception_enabled : false ,
153- profiling_exception_message_enabled : false ,
154- profiling_wall_time_enabled : false ,
155- profiling_io_enabled : false ,
156- output_pprof : None ,
157- profiling_exception_sampling_distance : 0 ,
158- profiling_log_level : LevelFilter :: Off ,
159- uri : Default :: default ( ) ,
160- } ;
140+ let system_settings = & mut * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ;
141+ * system_settings = SystemSettings :: initial ( ) ;
161142 }
162143
163144 unsafe fn on_fork_in_child ( ) {
164- let system_settings = ( * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ) . assume_init_mut ( ) ;
165- system_settings. profiling_enabled = false ;
166- system_settings. profiling_experimental_features_enabled = false ;
167- system_settings. profiling_endpoint_collection_enabled = false ;
168- system_settings. profiling_experimental_cpu_time_enabled = false ;
169- system_settings. profiling_allocation_enabled = false ;
170- system_settings. profiling_timeline_enabled = false ;
171- system_settings. profiling_exception_enabled = false ;
172- system_settings. profiling_exception_message_enabled = false ;
173- system_settings. profiling_io_enabled = false ;
145+ let system_settings = & mut * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ;
146+ * system_settings = SystemSettings :: initial ( ) ;
174147 }
175148}
176149
@@ -448,55 +421,24 @@ impl ConfigId {
448421 }
449422}
450423
451- lazy_static:: lazy_static! {
452- /// In some SAPIs, full configuration is not known until the first request
453- /// is served. This is ripe for edge cases. Consider this order of events:
454- /// 1. Worker is created.
455- /// 2. No requests are served.
456- /// 3. As the worker shuts down, the timeline profiler will attempt to
457- /// add idle time to timeline.
458- /// What state should the configuration be in?
459- ///
460- /// Since the real configuration was never learned, assume everything is
461- /// disabled, which should cause fewer issues for customers than assuming
462- /// defaults.
463- pub static ref INITIAL_SYSTEM_SETTINGS : SystemSettings = SystemSettings {
464- profiling_enabled: false ,
465- profiling_experimental_features_enabled: false ,
466- profiling_endpoint_collection_enabled: false ,
467- profiling_experimental_cpu_time_enabled: false ,
468- profiling_allocation_enabled: false ,
469- profiling_allocation_sampling_distance: u32 :: MAX ,
470- profiling_timeline_enabled: false ,
471- profiling_exception_enabled: false ,
472- profiling_exception_message_enabled: false ,
473- profiling_wall_time_enabled: false ,
474- profiling_io_enabled: false ,
475- output_pprof: None ,
476- profiling_exception_sampling_distance: u32 :: MAX ,
477- profiling_log_level: LevelFilter :: Off ,
478- uri: Default :: default ( ) ,
479- } ;
480-
481- /// Keep these in sync with the INI defaults.
482- static ref DEFAULT_SYSTEM_SETTINGS : SystemSettings = SystemSettings {
483- profiling_enabled: true ,
484- profiling_experimental_features_enabled: false ,
485- profiling_endpoint_collection_enabled: true ,
486- profiling_experimental_cpu_time_enabled: true ,
487- profiling_allocation_enabled: true ,
488- profiling_allocation_sampling_distance: 1024 * 4096 ,
489- profiling_timeline_enabled: true ,
490- profiling_exception_enabled: true ,
491- profiling_exception_message_enabled: false ,
492- profiling_wall_time_enabled: true ,
493- profiling_io_enabled: false ,
494- output_pprof: None ,
495- profiling_exception_sampling_distance: 100 ,
496- profiling_log_level: LevelFilter :: Off ,
497- uri: Default :: default ( ) ,
498- } ;
499- }
424+ /// Keep these in sync with the INI defaults.
425+ static DEFAULT_SYSTEM_SETTINGS : SystemSettings = SystemSettings {
426+ profiling_enabled : true ,
427+ profiling_experimental_features_enabled : false ,
428+ profiling_endpoint_collection_enabled : true ,
429+ profiling_experimental_cpu_time_enabled : true ,
430+ profiling_allocation_enabled : true ,
431+ profiling_allocation_sampling_distance : 1024 * 4096 ,
432+ profiling_timeline_enabled : true ,
433+ profiling_exception_enabled : true ,
434+ profiling_exception_message_enabled : false ,
435+ profiling_wall_time_enabled : true ,
436+ profiling_io_enabled : false ,
437+ output_pprof : None ,
438+ profiling_exception_sampling_distance : 100 ,
439+ profiling_log_level : LevelFilter :: Off ,
440+ uri : AgentEndpoint :: Socket ( Cow :: Borrowed ( AgentEndpoint :: DEFAULT_UNIX_SOCKET_PATH ) ) ,
441+ } ;
500442
501443/// # Safety
502444/// This function must only be called after config has been initialized in
@@ -1244,7 +1186,8 @@ pub(crate) fn minit(module_number: libc::c_int) {
12441186 ) ;
12451187 assert ! ( tmp) ; // It's literally return true in the source.
12461188
1247- SystemSettings :: on_startup ( ) ;
1189+ let system_settings = & mut * ptr:: addr_of_mut!( SYSTEM_SETTINGS ) ;
1190+ * system_settings = SystemSettings :: initial ( ) ;
12481191 }
12491192}
12501193
@@ -1268,6 +1211,7 @@ pub(crate) unsafe fn on_fork_in_child() {
12681211#[ cfg( test) ]
12691212mod tests {
12701213 use super :: * ;
1214+ use core:: mem:: MaybeUninit ;
12711215 use libc:: memcmp;
12721216
12731217 #[ test]
0 commit comments