MCPcopy Index your code
hub / github.com/php/frankenphp / drainWorkerThreads

Function drainWorkerThreads

worker.go:178–231  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

176}
177
178func drainWorkerThreads() (drainedThreads []*phpThread) {
179 var ready sync.WaitGroup
180
181 for _, worker := range workers {
182 worker.threadMutex.RLock()
183 ready.Add(len(worker.threads))
184
185 for _, thread := range worker.threads {
186 if !thread.state.RequestSafeStateChange(state.Restarting) {
187 ready.Done()
188
189 // no state change allowed == thread is shutting down
190 // we'll proceed to restart all other threads anyway
191 continue
192 }
193
194 thread.handler.drain()
195 close(thread.drainChan)
196 drainedThreads = append(drainedThreads, thread)
197
198 go func(thread *phpThread) {
199 thread.state.WaitFor(state.Yielding, state.ShuttingDown, state.Done)
200 ready.Done()
201 }(thread)
202 }
203
204 worker.threadMutex.RUnlock()
205 }
206
207 done := make(chan struct{})
208 go func() {
209 ready.Wait()
210 close(done)
211 }()
212
213 select {
214 case <-done:
215 case <-time.After(drainGracePeriod):
216 // Force-kill any thread still stuck in a blocking syscall, then
217 // keep waiting unconditionally. On platforms where force-kill
218 // cannot interrupt the syscall (macOS, Windows non-alertable
219 // Sleep) the thread exits when the syscall completes naturally.
220 for _, thread := range drainedThreads {
221 if !thread.state.Is(state.Yielding) {
222 thread.forceKillMu.RLock()
223 C.frankenphp_force_kill_thread(thread.forceKill)
224 thread.forceKillMu.RUnlock()
225 }
226 }
227 <-done
228 }
229
230 return drainedThreads
231}
232
233// RestartWorkers attempts to restart all workers gracefully.
234// All workers must be restarted at the same time to prevent issues with

Callers 2

DrainWorkersFunction · 0.85
RestartWorkersFunction · 0.85

Calls 4

WaitForMethod · 0.80
IsMethod · 0.80
drainMethod · 0.65

Tested by

no test coverage detected