@@ -12,6 +12,7 @@ use crate::ffi::{
1212 ext_php_rs_sapi_globals, php_core_globals, sapi_globals_struct, sapi_header_struct,
1313 sapi_headers_struct, sapi_request_info, zend_is_auto_global, TRACK_VARS_COOKIE , TRACK_VARS_ENV ,
1414 TRACK_VARS_FILES , TRACK_VARS_GET , TRACK_VARS_POST , TRACK_VARS_REQUEST , TRACK_VARS_SERVER ,
15+ php_file_globals, file_globals
1516} ;
1617
1718use crate :: types:: { ZendHashTable , ZendObject , ZendStr } ;
@@ -358,13 +359,53 @@ impl SapiRequestInfo {
358359 }
359360}
360361
362+ /// Stores global variables used in the SAPI.
363+ pub type FileGlobals = php_file_globals ;
364+
365+ impl FileGlobals {
366+ /// Returns a reference to the PHP process globals.
367+ ///
368+ /// The process globals are guarded by a RwLock. There can be multiple
369+ /// immutable references at one time but only ever one mutable reference.
370+ /// Attempting to retrieve the globals while already holding the global
371+ /// guard will lead to a deadlock. Dropping the globals guard will release
372+ /// the lock.
373+ pub fn get ( ) -> GlobalReadGuard < Self > {
374+ // SAFETY: PHP executor globals are statically declared therefore should never
375+ // return an invalid pointer.
376+ let globals = unsafe { & file_globals } ;
377+ let guard = FILE_GLOBALS_LOCK . read ( ) ;
378+ GlobalReadGuard { globals, guard }
379+ }
380+
381+ /// Returns a mutable reference to the PHP executor globals.
382+ ///
383+ /// The executor globals are guarded by a RwLock. There can be multiple
384+ /// immutable references at one time but only ever one mutable reference.
385+ /// Attempting to retrieve the globals while already holding the global
386+ /// guard will lead to a deadlock. Dropping the globals guard will release
387+ /// the lock.
388+ pub fn get_mut ( ) -> GlobalWriteGuard < Self > {
389+ // SAFETY: PHP executor globals are statically declared therefore should never
390+ // return an invalid pointer.
391+ let globals = unsafe { & mut file_globals } ;
392+ let guard = SAPI_GLOBALS_LOCK . write ( ) ;
393+ GlobalWriteGuard { globals, guard }
394+ }
395+
396+ pub fn stream_wrappers ( & self ) -> Option < & ' static ZendHashTable > {
397+ unsafe { self . stream_wrappers . as_ref ( ) }
398+ }
399+ }
400+
361401/// Executor globals rwlock.
362402///
363403/// PHP provides no indication if the executor globals are being accessed so
364404/// this is only effective on the Rust side.
365405static GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
366406static PROCESS_GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
367407static SAPI_GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
408+ static FILE_GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
368409
369410/// Wrapper guard that contains a reference to a given type `T`. Dropping a
370411/// guard releases the lock on the relevant rwlock.
0 commit comments