diff --git a/phpthread.go b/phpthread.go index a941de9348..1fdb4f7bc6 100644 --- a/phpthread.go +++ b/phpthread.go @@ -34,6 +34,12 @@ type threadHandler interface { afterScriptExecution(exitStatus int) context() context.Context frankenPHPContext() *frankenPHPContext + // drain is a hook called by drainWorkerThreads right before drainChan is + // closed. Handlers that need to wake up a thread parked in a blocking C + // call (e.g. by closing a stop pipe) plug their signal in here. All + // current handlers are no-ops; this is the seam later handler types use + // without having to modify drainWorkerThreads. + drain() } func newPHPThread(threadIndex int) *phpThread { diff --git a/threadinactive.go b/threadinactive.go index b5d11fcdfc..e6de0b4be5 100644 --- a/threadinactive.go +++ b/threadinactive.go @@ -58,3 +58,5 @@ func (handler *inactiveThread) context() context.Context { func (handler *inactiveThread) name() string { return "Inactive PHP Thread" } + +func (handler *inactiveThread) drain() {} diff --git a/threadregular.go b/threadregular.go index 49db71106b..2f52963726 100644 --- a/threadregular.go +++ b/threadregular.go @@ -83,6 +83,8 @@ func (handler *regularThread) name() string { return "Regular PHP Thread" } +func (handler *regularThread) drain() {} + func (handler *regularThread) waitForRequest() string { // max_requests reached: restart the thread to clean up all ZTS state if maxRequestsPerThread > 0 && handler.requestCount >= maxRequestsPerThread { diff --git a/threadtasks_test.go b/threadtasks_test.go index 2e74b12e93..d6954d161c 100644 --- a/threadtasks_test.go +++ b/threadtasks_test.go @@ -79,6 +79,8 @@ func (handler *taskThread) name() string { return "Task PHP Thread" } +func (handler *taskThread) drain() {} + func (handler *taskThread) waitForTasks() { for { select { diff --git a/threadworker.go b/threadworker.go index 0fb315d1dc..21e1034805 100644 --- a/threadworker.go +++ b/threadworker.go @@ -105,6 +105,8 @@ func (handler *workerThread) name() string { return "Worker PHP Thread - " + handler.worker.fileName } +func (handler *workerThread) drain() {} + func setupWorkerScript(handler *workerThread, worker *worker) { metrics.StartWorker(worker.name) diff --git a/worker.go b/worker.go index c97cc4a3a7..5888c0e462 100644 --- a/worker.go +++ b/worker.go @@ -189,6 +189,7 @@ func drainWorkerThreads() []*phpThread { continue } + thread.handler.drain() close(thread.drainChan) drainedThreads = append(drainedThreads, thread)