Skip to content

Commit 10eac24

Browse files
committed
Expose SAPI module
1 parent 116c698 commit 10eac24

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

allowed_bindings.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ bind! {
2727
_emalloc,
2828
_zend_executor_globals,
2929
_sapi_globals_struct,
30+
_sapi_module_struct,
3031
_zend_expected_type,
3132
_zend_expected_type_Z_EXPECTED_ARRAY,
3233
_zend_expected_type_Z_EXPECTED_BOOL,
@@ -243,6 +244,7 @@ bind! {
243244
zend_class_unserialize_deny,
244245
zend_executor_globals,
245246
sapi_globals_struct,
247+
sapi_module_struct,
246248
zend_objects_store_del,
247249
zend_hash_move_forward_ex,
248250
zend_hash_get_current_key_type_ex,
@@ -254,6 +256,7 @@ bind! {
254256
ZEND_ACC_NOT_SERIALIZABLE,
255257
executor_globals,
256258
sapi_globals,
259+
sapi_module,
257260
php_printf,
258261
__zend_malloc,
259262
tsrm_get_ls_cache,

src/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extern "C" {
2727
pub fn ext_php_rs_zend_object_release(obj: *mut zend_object);
2828
pub fn ext_php_rs_executor_globals() -> *mut zend_executor_globals;
2929
pub fn ext_php_rs_sapi_globals() -> *mut sapi_globals_struct;
30+
pub fn ext_php_rs_sapi_module() -> *mut sapi_module_struct;
3031
pub fn ext_php_rs_zend_try_catch(
3132
func: unsafe extern "C" fn(*const c_void) -> *const c_void,
3233
ctx: *const c_void,

src/wrapper.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ sapi_globals_struct *ext_php_rs_sapi_globals() {
5252
#endif
5353
}
5454

55+
sapi_module_struct *ext_php_rs_sapi_module() {
56+
return &sapi_module;
57+
}
58+
5559
bool ext_php_rs_zend_try_catch(void* (*callback)(void *), void *ctx, void **result) {
5660
zend_try {
5761
*result = callback(ctx);

src/wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ void *ext_php_rs_zend_object_alloc(size_t obj_size, zend_class_entry *ce);
3333
void ext_php_rs_zend_object_release(zend_object *obj);
3434
zend_executor_globals *ext_php_rs_executor_globals();;
3535
sapi_globals_struct *ext_php_rs_sapi_globals();
36+
sapi_module_struct *ext_php_rs_sapi_module();
3637
bool ext_php_rs_zend_try_catch(void* (*callback)(void *), void *ctx, void **result);
3738
void ext_php_rs_zend_bailout();

src/zend/globals.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::boxed::ZBox;
1010
use crate::ffi::zend_atomic_bool_store;
1111
use crate::ffi::{
1212
_sapi_globals_struct, _zend_executor_globals, ext_php_rs_executor_globals,
13+
_sapi_module_struct, ext_php_rs_sapi_module,
1314
ext_php_rs_sapi_globals, zend_ini_entry,
1415
};
1516
use crate::types::{ZendHashTable, ZendObject};
@@ -20,6 +21,9 @@ pub type ExecutorGlobals = _zend_executor_globals;
2021
/// Stores global SAPI variables used in the PHP executor.
2122
pub type SapiGlobals = _sapi_globals_struct;
2223

24+
/// Stores the SAPI module used in the PHP executor.
25+
pub type SapiModule = _sapi_module_struct;
26+
2327
impl ExecutorGlobals {
2428
/// Returns a reference to the PHP executor globals.
2529
///
@@ -167,6 +171,40 @@ impl SapiGlobals {
167171
}
168172
}
169173

174+
impl SapiModule {
175+
/// Returns a reference to the PHP SAPI module.
176+
///
177+
/// The executor globals are guarded by a RwLock. There can be multiple
178+
/// immutable references at one time but only ever one mutable reference.
179+
/// Attempting to retrieve the globals while already holding the global
180+
/// guard will lead to a deadlock. Dropping the globals guard will release
181+
/// the lock.
182+
pub fn get() -> GlobalReadGuard<Self> {
183+
// SAFETY: PHP executor globals are statically declared therefore should never
184+
// return an invalid pointer.
185+
let globals = unsafe { ext_php_rs_sapi_module().as_ref() }
186+
.expect("Static executor globals were invalid");
187+
let guard = SAPI_MODULE_LOCK.read();
188+
GlobalReadGuard { globals, guard }
189+
}
190+
191+
/// Returns a mutable reference to the PHP executor globals.
192+
///
193+
/// The executor globals are guarded by a RwLock. There can be multiple
194+
/// immutable references at one time but only ever one mutable reference.
195+
/// Attempting to retrieve the globals while already holding the global
196+
/// guard will lead to a deadlock. Dropping the globals guard will release
197+
/// the lock.
198+
pub fn get_mut() -> GlobalWriteGuard<Self> {
199+
// SAFETY: PHP executor globals are statically declared therefore should never
200+
// return an invalid pointer.
201+
let globals = unsafe { ext_php_rs_sapi_module().as_mut() }
202+
.expect("Static executor globals were invalid");
203+
let guard = SAPI_MODULE_LOCK.write();
204+
GlobalWriteGuard { globals, guard }
205+
}
206+
}
207+
170208
/// Executor globals rwlock.
171209
///
172210
/// PHP provides no indication if the executor globals are being accessed so
@@ -179,6 +217,12 @@ static GLOBALS_LOCK: RwLock<()> = const_rwlock(());
179217
/// this is only effective on the Rust side.
180218
static SAPI_LOCK: RwLock<()> = const_rwlock(());
181219

220+
/// SAPI globals rwlock.
221+
///
222+
/// PHP provides no indication if the executor globals are being accessed so
223+
/// this is only effective on the Rust side.
224+
static SAPI_MODULE_LOCK: RwLock<()> = const_rwlock(());
225+
182226
/// Wrapper guard that contains a reference to a given type `T`. Dropping a
183227
/// guard releases the lock on the relevant rwlock.
184228
pub struct GlobalReadGuard<T: 'static> {

0 commit comments

Comments
 (0)