From 357a153a2ecdfddeccdbc5920e0254d5d19fd937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 11 Feb 2026 15:42:57 +0100 Subject: [PATCH] chore: cs improvements --- caddy/admin.go | 6 ++++-- internal/state/state.go | 6 ++++-- phpthread.go | 9 +++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/caddy/admin.go b/caddy/admin.go index ec6d7d7c51..8515f11326 100644 --- a/caddy/admin.go +++ b/caddy/admin.go @@ -3,12 +3,14 @@ package caddy import ( "encoding/json" "fmt" + "net/http" + "github.com/caddyserver/caddy/v2" "github.com/dunglas/frankenphp" - "net/http" ) -type FrankenPHPAdmin struct{} +type FrankenPHPAdmin struct { +} // if the id starts with "admin.api" the module will register AdminRoutes via module.Routes() func (FrankenPHPAdmin) CaddyModule() caddy.ModuleInfo { diff --git a/internal/state/state.go b/internal/state/state.go index 62d14e503f..6457c2dde2 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -141,13 +141,15 @@ func (ts *ThreadState) notifySubscribers(nextState State) { ts.subscribers = ts.subscribers[:n] } -// block until the thread reaches a certain state +// WaitFor blocks until the thread reaches a certain state func (ts *ThreadState) WaitFor(states ...State) { ts.mu.Lock() if slices.Contains(states, ts.currentState) { ts.mu.Unlock() + return } + sub := stateSubscriber{ states: states, ch: make(chan struct{}), @@ -157,7 +159,7 @@ func (ts *ThreadState) WaitFor(states ...State) { <-sub.ch } -// safely request a state change from a different goroutine +// RequestSafeStateChange safely requests a state change from a different goroutine func (ts *ThreadState) RequestSafeStateChange(nextState State) bool { ts.mu.Lock() switch ts.currentState { diff --git a/phpthread.go b/phpthread.go index 5ff15b645f..90007cbe17 100644 --- a/phpthread.go +++ b/phpthread.go @@ -25,7 +25,7 @@ type phpThread struct { sandboxedEnv map[string]*C.zend_string } -// interface that defines how the callbacks from the C thread should be handled +// threadHandler defines how the callbacks from the C thread should be handled type threadHandler interface { name() string beforeScriptExecution() string @@ -68,6 +68,7 @@ func (thread *phpThread) shutdown() { if !thread.state.RequestSafeStateChange(state.ShuttingDown) { // already shutting down or done, wait for the C thread to finish thread.state.WaitFor(state.Done, state.Reserved) + return } @@ -81,17 +82,19 @@ func (thread *phpThread) shutdown() { } } -// change the thread handler safely +// setHandler changes the thread handler safely // must be called from outside the PHP thread func (thread *phpThread) setHandler(handler threadHandler) { thread.handlerMu.Lock() defer thread.handlerMu.Unlock() + if !thread.state.RequestSafeStateChange(state.TransitionRequested) { // no state change allowed == shutdown or done return } close(thread.drainChan) + thread.state.WaitFor(state.TransitionInProgress) thread.handler = handler thread.drainChan = make(chan struct{}) @@ -125,6 +128,7 @@ func (thread *phpThread) name() string { thread.handlerMu.RLock() name := thread.handler.name() thread.handlerMu.RUnlock() + return name } @@ -135,6 +139,7 @@ func (thread *phpThread) pinString(s string) *C.char { if sData == nil { return nil } + thread.Pin(sData) return (*C.char)(unsafe.Pointer(sData))