Skip to content

Commit fb68991

Browse files
committed
feat(sapi): add global module handling
1 parent 1242e4d commit fb68991

File tree

5 files changed

+76
-18
lines changed

5 files changed

+76
-18
lines changed

Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM php:zts-bullseye
2+
3+
# Install rust
4+
RUN apt-get update && apt-get install -y curl clang
5+
6+
# Add app user with uid 1000
7+
RUN useradd -m -u 1000 app
8+
USER app
9+
10+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
11+
12+
ENV PATH="/home/app/.cargo/bin:${PATH}"

allowed_bindings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ bind! {
307307
_zend_bailout,
308308
sapi_startup,
309309
sapi_shutdown,
310+
sapi_module,
310311
php_module_startup,
311312
php_module_shutdown,
312313
php_request_startup,

src/embed/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ use crate::ffi::{
1616
};
1717
use crate::types::{ZendObject, Zval};
1818
use crate::zend::{panic_wrapper, try_catch, ExecutorGlobals};
19-
use parking_lot::{const_rwlock, RwLock};
19+
use parking_lot::{const_mutex, Mutex};
2020
use std::ffi::{c_char, c_void, CString, NulError};
2121
use std::panic::{resume_unwind, RefUnwindSafe};
2222
use std::path::Path;
2323
use std::ptr::null_mut;
24-
2524
pub use ffi::ext_php_rs_sapi_startup;
2625
pub use sapi::SapiModule;
2726

@@ -43,8 +42,6 @@ impl EmbedError {
4342
}
4443
}
4544

46-
static RUN_FN_LOCK: RwLock<()> = const_rwlock(());
47-
4845
impl Embed {
4946
/// Run a php script from a file
5047
///
@@ -135,7 +132,11 @@ impl Embed {
135132
// This is to prevent multiple threads from running php at the same time
136133
// At some point we should detect if php is compiled with thread safety and
137134
// avoid doing that in this case
138-
let _guard = RUN_FN_LOCK.write();
135+
let _guard = {
136+
static RUN_FN_LOCK: Mutex<()> = const_mutex(());
137+
138+
RUN_FN_LOCK.lock()
139+
};
139140

140141
let panic = unsafe {
141142
ext_php_rs_embed_callback(
@@ -206,6 +207,7 @@ impl Embed {
206207

207208
#[cfg(test)]
208209
mod tests {
210+
use crate::ffi::sapi_module;
209211
use super::Embed;
210212

211213
#[test]

src/embed/sapi.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,56 @@
11
//! Builder and objects for creating modules in PHP. A module is the base of a
22
//! PHP extension.
33
4-
use crate::ffi::sapi_module_struct;
4+
use crate::ffi::{sapi_module, sapi_module_struct};
55

66
/// A Zend module entry, also known as an extension.
77
pub type SapiModule = sapi_module_struct;
88

9+
pub fn set_global_module(module: SapiModule) {
10+
// leak the module to the global scope
11+
let module = Box::leak(Box::new(module));
12+
13+
unsafe {
14+
sapi_module = *module;
15+
}
16+
}
17+
18+
pub fn get_global_module() -> Option<&'static SapiModule> {
19+
let module = unsafe { &*&raw const sapi_module };
20+
21+
if module.name.is_null() {
22+
return None;
23+
}
24+
25+
Some(module)
26+
}
27+
928
impl SapiModule {
1029
/// Allocates the module entry on the heap, returning a pointer to the
1130
/// memory location. The caller is responsible for the memory pointed to.
1231
pub fn into_raw(self) -> *mut Self {
1332
Box::into_raw(Box::new(self))
1433
}
34+
35+
pub fn name(&self) -> &str {
36+
unsafe { std::ffi::CStr::from_ptr(self.name).to_str().unwrap() }
37+
}
38+
}
39+
40+
#[cfg(test)]
41+
mod tests {
42+
use crate::embed::Embed;
43+
use super::*;
44+
45+
#[test]
46+
fn test_get_global_module() {
47+
Embed::run(|| {
48+
let module = get_global_module();
49+
50+
assert!(module.is_some());
51+
let module = module.unwrap();
52+
53+
assert_eq!(module.name(), "embed");
54+
})
55+
}
1556
}

src/zend/try_catch.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub unsafe fn bailout() -> ! {
105105
#[cfg(feature = "embed")]
106106
#[cfg(test)]
107107
mod tests {
108-
use crate::embed::Embed;
108+
use crate::embed::{ext_php_rs_sapi_startup, Embed};
109109
use crate::zend::{bailout, try_catch};
110110
use std::ptr::null_mut;
111111

@@ -179,20 +179,22 @@ mod tests {
179179

180180
#[test]
181181
fn test_memory_leak() {
182-
let mut ptr = null_mut();
182+
Embed::run(|| {
183+
let mut ptr = null_mut();
183184

184-
let _ = try_catch(|| {
185-
let mut result = "foo".to_string();
186-
ptr = &mut result;
185+
let _ = try_catch(|| {
186+
let mut result = "foo".to_string();
187+
ptr = &mut result;
187188

188-
unsafe {
189-
bailout();
190-
}
191-
});
189+
unsafe {
190+
bailout();
191+
}
192+
});
192193

193-
// Check that the string is never released
194-
let result = unsafe { &*ptr as &str };
194+
// Check that the string is never released
195+
let result = unsafe { &*ptr as &str };
195196

196-
assert_eq!(result, "foo");
197+
assert_eq!(result, "foo");
198+
});
197199
}
198200
}

0 commit comments

Comments
 (0)