11//! Types related to the PHP executor, sapi and process globals.
22
3+ use parking_lot:: { ArcRwLockReadGuard , ArcRwLockWriteGuard , RawRwLock , RwLock } ;
34use std:: collections:: HashMap ;
45use std:: ffi:: CStr ;
56use std:: ops:: { Deref , DerefMut } ;
67use std:: slice;
78use std:: str;
8-
9- use parking_lot:: { const_rwlock, RwLock , RwLockReadGuard , RwLockWriteGuard } ;
9+ use std:: sync:: { Arc , LazyLock } ;
1010
1111use crate :: boxed:: ZBox ;
1212use crate :: exception:: PhpResult ;
@@ -51,7 +51,15 @@ impl ExecutorGlobals {
5151 // return an invalid pointer.
5252 let globals = unsafe { ext_php_rs_executor_globals ( ) . as_ref ( ) }
5353 . expect ( "Static executor globals were invalid" ) ;
54- let guard = GLOBALS_LOCK . read ( ) ;
54+
55+ cfg_if:: cfg_if! {
56+ if #[ cfg( php82) ] {
57+ let guard = lock:: GLOBALS_LOCK . read_arc( ) ;
58+ } else {
59+ let guard = lock:: GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
60+ }
61+ }
62+
5563 GlobalReadGuard { globals, guard }
5664 }
5765
@@ -67,7 +75,15 @@ impl ExecutorGlobals {
6775 // return an invalid pointer.
6876 let globals = unsafe { ext_php_rs_executor_globals ( ) . as_mut ( ) }
6977 . expect ( "Static executor globals were invalid" ) ;
70- let guard = GLOBALS_LOCK . write ( ) ;
78+
79+ cfg_if:: cfg_if! {
80+ if #[ cfg( php82) ] {
81+ let guard = lock:: GLOBALS_LOCK . write_arc( ) ;
82+ } else {
83+ let guard = lock:: GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
84+ }
85+ }
86+
7187 GlobalWriteGuard { globals, guard }
7288 }
7389
@@ -198,7 +214,7 @@ impl SapiModule {
198214 // return an invalid pointer.
199215 let globals = unsafe { ext_php_rs_sapi_module ( ) . as_ref ( ) }
200216 . expect ( "Static executor globals were invalid" ) ;
201- let guard = SAPI_MODULE_LOCK . read ( ) ;
217+ let guard = SAPI_MODULE_LOCK . read_arc ( ) ;
202218 GlobalReadGuard { globals, guard }
203219 }
204220
@@ -214,7 +230,7 @@ impl SapiModule {
214230 // return an invalid pointer.
215231 let globals = unsafe { ext_php_rs_sapi_module ( ) . as_mut ( ) }
216232 . expect ( "Static executor globals were invalid" ) ;
217- let guard = SAPI_MODULE_LOCK . write ( ) ;
233+ let guard = SAPI_MODULE_LOCK . write_arc ( ) ;
218234 GlobalWriteGuard { globals, guard }
219235 }
220236}
@@ -234,7 +250,15 @@ impl ProcessGlobals {
234250 // SAFETY: PHP executor globals are statically declared therefore should never
235251 // return an invalid pointer.
236252 let globals = unsafe { & * ext_php_rs_process_globals ( ) } ;
237- let guard = PROCESS_GLOBALS_LOCK . read ( ) ;
253+
254+ cfg_if:: cfg_if! {
255+ if #[ cfg( php82) ] {
256+ let guard = lock:: PROCESS_GLOBALS_LOCK . read_arc( ) ;
257+ } else {
258+ let guard = lock:: PROCESS_GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
259+ }
260+ }
261+
238262 GlobalReadGuard { globals, guard }
239263 }
240264
@@ -249,7 +273,15 @@ impl ProcessGlobals {
249273 // SAFETY: PHP executor globals are statically declared therefore should never
250274 // return an invalid pointer.
251275 let globals = unsafe { & mut * ext_php_rs_process_globals ( ) } ;
252- let guard = PROCESS_GLOBALS_LOCK . write ( ) ;
276+
277+ cfg_if:: cfg_if! {
278+ if #[ cfg( php82) ] {
279+ let guard = lock:: PROCESS_GLOBALS_LOCK . write_arc( ) ;
280+ } else {
281+ let guard = lock:: PROCESS_GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
282+ }
283+ }
284+
253285 GlobalWriteGuard { globals, guard }
254286 }
255287
@@ -357,7 +389,15 @@ impl SapiGlobals {
357389 // SAFETY: PHP executor globals are statically declared therefore should never
358390 // return an invalid pointer.
359391 let globals = unsafe { & * ext_php_rs_sapi_globals ( ) } ;
360- let guard = SAPI_GLOBALS_LOCK . read ( ) ;
392+
393+ cfg_if:: cfg_if! {
394+ if #[ cfg( php82) ] {
395+ let guard = lock:: SAPI_GLOBALS_LOCK . read_arc( ) ;
396+ } else {
397+ let guard = lock:: SAPI_GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
398+ }
399+ }
400+
361401 GlobalReadGuard { globals, guard }
362402 }
363403
@@ -372,7 +412,15 @@ impl SapiGlobals {
372412 // SAFETY: PHP executor globals are statically declared therefore should never
373413 // return an invalid pointer.
374414 let globals = unsafe { & mut * ext_php_rs_sapi_globals ( ) } ;
375- let guard = SAPI_GLOBALS_LOCK . write ( ) ;
415+
416+ cfg_if:: cfg_if! {
417+ if #[ cfg( php82) ] {
418+ let guard = lock:: SAPI_GLOBALS_LOCK . write_arc( ) ;
419+ } else {
420+ let guard = lock:: SAPI_GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
421+ }
422+ }
423+
376424 GlobalWriteGuard { globals, guard }
377425 }
378426
@@ -576,7 +624,15 @@ impl FileGlobals {
576624 // return an invalid pointer.
577625 let globals = unsafe { ext_php_rs_file_globals ( ) . as_ref ( ) }
578626 . expect ( "Static file globals were invalid" ) ;
579- let guard = FILE_GLOBALS_LOCK . read ( ) ;
627+
628+ cfg_if:: cfg_if! {
629+ if #[ cfg( php82) ] {
630+ let guard = lock:: FILE_GLOBALS_LOCK . read_arc( ) ;
631+ } else {
632+ let guard = lock:: FILE_GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
633+ }
634+ }
635+
580636 GlobalReadGuard { globals, guard }
581637 }
582638
@@ -591,7 +647,15 @@ impl FileGlobals {
591647 // SAFETY: PHP executor globals are statically declared therefore should never
592648 // return an invalid pointer.
593649 let globals = unsafe { & mut * ext_php_rs_file_globals ( ) } ;
594- let guard = SAPI_GLOBALS_LOCK . write ( ) ;
650+
651+ cfg_if:: cfg_if! {
652+ if #[ cfg( php82) ] {
653+ let guard = lock:: FILE_GLOBALS_LOCK . write_arc( ) ;
654+ } else {
655+ let guard = lock:: FILE_GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
656+ }
657+ }
658+
595659 GlobalWriteGuard { globals, guard }
596660 }
597661
@@ -605,23 +669,50 @@ impl FileGlobals {
605669///
606670/// PHP provides no indication if the executor globals are being accessed so
607671/// this is only effective on the Rust side.
608- static GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
609- static PROCESS_GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
610- static SAPI_GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
611- static FILE_GLOBALS_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
672+ #[ cfg( not( php_zts) ) ]
673+ pub ( crate ) mod lock {
674+ use parking_lot:: RwLock ;
675+ use std:: sync:: { Arc , LazyLock } ;
676+
677+ pub ( crate ) static GLOBALS_LOCK : LazyLock < Arc < RwLock < ( ) > > > =
678+ LazyLock :: new ( || Arc :: new ( RwLock :: new ( ( ) ) ) ) ;
679+ pub ( crate ) static PROCESS_GLOBALS_LOCK : LazyLock < Arc < RwLock < ( ) > > > =
680+ LazyLock :: new ( || Arc :: new ( RwLock :: new ( ( ) ) ) ) ;
681+ pub ( crate ) static SAPI_GLOBALS_LOCK : LazyLock < Arc < RwLock < ( ) > > > =
682+ LazyLock :: new ( || Arc :: new ( RwLock :: new ( ( ) ) ) ) ;
683+ pub ( crate ) static FILE_GLOBALS_LOCK : LazyLock < Arc < RwLock < ( ) > > > =
684+ LazyLock :: new ( || Arc :: new ( RwLock :: new ( ( ) ) ) ) ;
685+ }
686+
687+ /// Executor globals rwlock.
688+ ///
689+ /// PHP provides no indication if the executor globals are being accessed so
690+ /// this is only effective on the Rust side.
691+ #[ cfg( php_zts) ]
692+ pub ( crate ) mod lock {
693+ use parking_lot:: { const_rwlock, RwLock } ;
694+ use std:: sync:: Arc ;
695+
696+ thread_local ! {
697+ pub ( crate ) static GLOBALS_LOCK : Arc <RwLock <( ) >> = Arc :: new( const_rwlock( ( ) ) ) ;
698+ pub ( crate ) static PROCESS_GLOBALS_LOCK : Arc <RwLock <( ) >> = Arc :: new( const_rwlock( ( ) ) ) ;
699+ pub ( crate ) static SAPI_GLOBALS_LOCK : Arc <RwLock <( ) >> = Arc :: new( const_rwlock( ( ) ) ) ;
700+ pub ( crate ) static FILE_GLOBALS_LOCK : Arc <RwLock <( ) >> = Arc :: new( const_rwlock( ( ) ) ) ;
701+ }
702+ }
612703
613704/// SAPI globals rwlock.
614705///
615706/// PHP provides no indication if the executor globals are being accessed so
616707/// this is only effective on the Rust side.
617- static SAPI_MODULE_LOCK : RwLock < ( ) > = const_rwlock ( ( ) ) ;
708+ static SAPI_MODULE_LOCK : LazyLock < Arc < RwLock < ( ) > > > = LazyLock :: new ( || Arc :: new ( RwLock :: new ( ( ) ) ) ) ;
618709
619710/// Wrapper guard that contains a reference to a given type `T`. Dropping a
620711/// guard releases the lock on the relevant rwlock.
621712pub struct GlobalReadGuard < T : ' static > {
622713 globals : & ' static T ,
623714 #[ allow( dead_code) ]
624- guard : RwLockReadGuard < ' static , ( ) > ,
715+ guard : ArcRwLockReadGuard < RawRwLock , ( ) > ,
625716}
626717
627718impl < T > Deref for GlobalReadGuard < T > {
@@ -637,7 +728,7 @@ impl<T> Deref for GlobalReadGuard<T> {
637728pub struct GlobalWriteGuard < T : ' static > {
638729 globals : & ' static mut T ,
639730 #[ allow( dead_code) ]
640- guard : RwLockWriteGuard < ' static , ( ) > ,
731+ guard : ArcRwLockWriteGuard < RawRwLock , ( ) > ,
641732}
642733
643734impl < T > Deref for GlobalWriteGuard < T > {
0 commit comments