diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-16 14:18:41 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-16 14:35:48 +0900 |
| commit | aa2124fe5d0c96078c034a6e4044b7e81acdf692 (patch) | |
| tree | c9b1597fef555220676f6a5ae554dc81579a4269 /crates/shirabe-php-rpc/src/session.rs | |
| parent | b4ab3df2ec85fbe477d7721344a8cd3630b437a1 (diff) | |
| download | php-shirabe-aa2124fe5d0c96078c034a6e4044b7e81acdf692.tar.gz php-shirabe-aa2124fe5d0c96078c034a6e4044b7e81acdf692.tar.zst php-shirabe-aa2124fe5d0c96078c034a6e4044b7e81acdf692.zip | |
feat(php-rpc): replay Rust-side env writes into the PHP worker
The worker is a long-lived child holding the environment it was handed
at spawn, so `@putenv`, the bin dir the event dispatcher prepends to
PATH, and COMPOSER_DEV_MODE never reached the PHP code running in it.
The shim now journals every write to the three storages PHP exposes, and
the outermost rpc_call replays the entries the worker has not seen yet
through __shirabe_sync_env. Replaying the writes rather than pushing a
whole snapshot keeps the worker's own $_SERVER entries intact.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-php-rpc/src/session.rs')
| -rw-r--r-- | crates/shirabe-php-rpc/src/session.rs | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/crates/shirabe-php-rpc/src/session.rs b/crates/shirabe-php-rpc/src/session.rs index 29bd89f3..3e1a817d 100644 --- a/crates/shirabe-php-rpc/src/session.rs +++ b/crates/shirabe-php-rpc/src/session.rs @@ -16,18 +16,19 @@ struct SessionLock { } impl SessionLock { - fn acquire(&self) { + /// Returns whether this acquisition opened the session rather than re-entering one. + fn acquire(&self) -> bool { let mut owner = self.owner.lock().unwrap(); let me = std::thread::current().id(); loop { match *owner { None => { *owner = Some((me, 1)); - return; + return true; } Some((tid, depth)) if tid == me => { *owner = Some((me, depth + 1)); - return; + return false; } Some(_) => { owner = self.cvar.wait(owner).unwrap(); @@ -60,12 +61,20 @@ static SESSION: LazyLock<SessionLock> = LazyLock::new(|| SessionLock { /// RAII guard; acquired once at the outermost `rpc_call`, re-entered (depth += 1, no blocking) /// by nested calls from the same thread. -pub struct SessionGuard; +pub struct SessionGuard { + outermost: bool, +} impl SessionGuard { pub fn enter() -> Self { - SESSION.acquire(); - SessionGuard + let outermost = SESSION.acquire(); + SessionGuard { outermost } + } + + /// Whether this guard opened the session. Work that must happen once per logical call + /// session, before anything else crosses the boundary, keys off this. + pub fn is_outermost(&self) -> bool { + self.outermost } } @@ -81,8 +90,10 @@ mod tests { #[test] fn same_thread_reenters_without_blocking() { - let _outer = SessionGuard::enter(); - let _inner = SessionGuard::enter(); + let outer = SessionGuard::enter(); + let inner = SessionGuard::enter(); + assert!(outer.is_outermost()); + assert!(!inner.is_outermost()); } #[test] |
