aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-rpc/src/session.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-php-rpc/src/session.rs')
-rw-r--r--crates/shirabe-php-rpc/src/session.rs27
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]