1
1
//! Types related to the PHP executor, sapi and process globals.
2
2
3
+ use parking_lot:: { ArcRwLockReadGuard , ArcRwLockWriteGuard , RawRwLock , RwLock } ;
3
4
use std:: collections:: HashMap ;
4
5
use std:: ffi:: CStr ;
5
6
use std:: ops:: { Deref , DerefMut } ;
6
7
use std:: slice;
7
8
use std:: str;
8
-
9
- use parking_lot:: { const_rwlock, RwLock , RwLockReadGuard , RwLockWriteGuard } ;
9
+ use std:: sync:: { Arc , LazyLock } ;
10
10
11
11
use crate :: boxed:: ZBox ;
12
12
use crate :: exception:: PhpResult ;
@@ -51,7 +51,15 @@ impl ExecutorGlobals {
51
51
// return an invalid pointer.
52
52
let globals = unsafe { ext_php_rs_executor_globals ( ) . as_ref ( ) }
53
53
. expect ( "Static executor globals were invalid" ) ;
54
- let guard = GLOBALS_LOCK . read ( ) ;
54
+
55
+ cfg_if:: cfg_if! {
56
+ if #[ cfg( php_zts) ] {
57
+ let guard = lock:: GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
58
+ } else {
59
+ let guard = lock:: GLOBALS_LOCK . read_arc( ) ;
60
+ }
61
+ }
62
+
55
63
GlobalReadGuard { globals, guard }
56
64
}
57
65
@@ -67,7 +75,15 @@ impl ExecutorGlobals {
67
75
// return an invalid pointer.
68
76
let globals = unsafe { ext_php_rs_executor_globals ( ) . as_mut ( ) }
69
77
. expect ( "Static executor globals were invalid" ) ;
70
- let guard = GLOBALS_LOCK . write ( ) ;
78
+
79
+ cfg_if:: cfg_if! {
80
+ if #[ cfg( php_zts) ] {
81
+ let guard = lock:: GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
82
+ } else {
83
+ let guard = lock:: GLOBALS_LOCK . write_arc( ) ;
84
+ }
85
+ }
86
+
71
87
GlobalWriteGuard { globals, guard }
72
88
}
73
89
@@ -198,7 +214,7 @@ impl SapiModule {
198
214
// return an invalid pointer.
199
215
let globals = unsafe { ext_php_rs_sapi_module ( ) . as_ref ( ) }
200
216
. expect ( "Static executor globals were invalid" ) ;
201
- let guard = SAPI_MODULE_LOCK . read ( ) ;
217
+ let guard = SAPI_MODULE_LOCK . read_arc ( ) ;
202
218
GlobalReadGuard { globals, guard }
203
219
}
204
220
@@ -214,7 +230,7 @@ impl SapiModule {
214
230
// return an invalid pointer.
215
231
let globals = unsafe { ext_php_rs_sapi_module ( ) . as_mut ( ) }
216
232
. expect ( "Static executor globals were invalid" ) ;
217
- let guard = SAPI_MODULE_LOCK . write ( ) ;
233
+ let guard = SAPI_MODULE_LOCK . write_arc ( ) ;
218
234
GlobalWriteGuard { globals, guard }
219
235
}
220
236
}
@@ -234,7 +250,15 @@ impl ProcessGlobals {
234
250
// SAFETY: PHP executor globals are statically declared therefore should never
235
251
// return an invalid pointer.
236
252
let globals = unsafe { & * ext_php_rs_process_globals ( ) } ;
237
- let guard = PROCESS_GLOBALS_LOCK . read ( ) ;
253
+
254
+ cfg_if:: cfg_if! {
255
+ if #[ cfg( php_zts) ] {
256
+ let guard = lock:: PROCESS_GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
257
+ } else {
258
+ let guard = lock:: PROCESS_GLOBALS_LOCK . read_arc( ) ;
259
+ }
260
+ }
261
+
238
262
GlobalReadGuard { globals, guard }
239
263
}
240
264
@@ -249,7 +273,15 @@ impl ProcessGlobals {
249
273
// SAFETY: PHP executor globals are statically declared therefore should never
250
274
// return an invalid pointer.
251
275
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( php_zts) ] {
279
+ let guard = lock:: PROCESS_GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
280
+ } else {
281
+ let guard = lock:: PROCESS_GLOBALS_LOCK . write_arc( ) ;
282
+ }
283
+ }
284
+
253
285
GlobalWriteGuard { globals, guard }
254
286
}
255
287
@@ -357,7 +389,15 @@ impl SapiGlobals {
357
389
// SAFETY: PHP executor globals are statically declared therefore should never
358
390
// return an invalid pointer.
359
391
let globals = unsafe { & * ext_php_rs_sapi_globals ( ) } ;
360
- let guard = SAPI_GLOBALS_LOCK . read ( ) ;
392
+
393
+ cfg_if:: cfg_if! {
394
+ if #[ cfg( php_zts) ] {
395
+ let guard = lock:: SAPI_GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
396
+ } else {
397
+ let guard = lock:: SAPI_GLOBALS_LOCK . read_arc( ) ;
398
+ }
399
+ }
400
+
361
401
GlobalReadGuard { globals, guard }
362
402
}
363
403
@@ -372,7 +412,15 @@ impl SapiGlobals {
372
412
// SAFETY: PHP executor globals are statically declared therefore should never
373
413
// return an invalid pointer.
374
414
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( php_zts) ] {
418
+ let guard = lock:: SAPI_GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
419
+ } else {
420
+ let guard = lock:: SAPI_GLOBALS_LOCK . write_arc( ) ;
421
+ }
422
+ }
423
+
376
424
GlobalWriteGuard { globals, guard }
377
425
}
378
426
@@ -576,7 +624,15 @@ impl FileGlobals {
576
624
// return an invalid pointer.
577
625
let globals = unsafe { ext_php_rs_file_globals ( ) . as_ref ( ) }
578
626
. expect ( "Static file globals were invalid" ) ;
579
- let guard = FILE_GLOBALS_LOCK . read ( ) ;
627
+
628
+ cfg_if:: cfg_if! {
629
+ if #[ cfg( php_zts) ] {
630
+ let guard = lock:: FILE_GLOBALS_LOCK . with( |l| l. read_arc( ) ) ;
631
+ } else {
632
+ let guard = lock:: FILE_GLOBALS_LOCK . read_arc( ) ;
633
+ }
634
+ }
635
+
580
636
GlobalReadGuard { globals, guard }
581
637
}
582
638
@@ -591,7 +647,15 @@ impl FileGlobals {
591
647
// SAFETY: PHP executor globals are statically declared therefore should never
592
648
// return an invalid pointer.
593
649
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( php_zts) ] {
653
+ let guard = lock:: FILE_GLOBALS_LOCK . with( |l| l. write_arc( ) ) ;
654
+ } else {
655
+ let guard = lock:: FILE_GLOBALS_LOCK . write_arc( ) ;
656
+ }
657
+ }
658
+
595
659
GlobalWriteGuard { globals, guard }
596
660
}
597
661
@@ -605,23 +669,50 @@ impl FileGlobals {
605
669
///
606
670
/// PHP provides no indication if the executor globals are being accessed so
607
671
/// 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
+ }
612
703
613
704
/// SAPI globals rwlock.
614
705
///
615
706
/// PHP provides no indication if the executor globals are being accessed so
616
707
/// 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 ( ( ) ) ) ) ;
618
709
619
710
/// Wrapper guard that contains a reference to a given type `T`. Dropping a
620
711
/// guard releases the lock on the relevant rwlock.
621
712
pub struct GlobalReadGuard < T : ' static > {
622
713
globals : & ' static T ,
623
714
#[ allow( dead_code) ]
624
- guard : RwLockReadGuard < ' static , ( ) > ,
715
+ guard : ArcRwLockReadGuard < RawRwLock , ( ) > ,
625
716
}
626
717
627
718
impl < T > Deref for GlobalReadGuard < T > {
@@ -637,7 +728,7 @@ impl<T> Deref for GlobalReadGuard<T> {
637
728
pub struct GlobalWriteGuard < T : ' static > {
638
729
globals : & ' static mut T ,
639
730
#[ allow( dead_code) ]
640
- guard : RwLockWriteGuard < ' static , ( ) > ,
731
+ guard : ArcRwLockWriteGuard < RawRwLock , ( ) > ,
641
732
}
642
733
643
734
impl < T > Deref for GlobalWriteGuard < T > {
0 commit comments