RestartWorkers attempts to restart all workers gracefully. All workers must be restarted at the same time to prevent issues with opcache resetting. Blocks until every worker thread has yielded; force-kill is armed after a grace period to wake threads parked in blocking syscalls so a stuck sleep does
()
| 237 | // blocking syscalls so a stuck sleep doesn't make this hang for the |
| 238 | // full duration of the syscall. |
| 239 | func RestartWorkers() { |
| 240 | // disallow scaling threads while restarting workers |
| 241 | scalingMu.Lock() |
| 242 | defer scalingMu.Unlock() |
| 243 | |
| 244 | threadsToRestart := drainWorkerThreads() |
| 245 | |
| 246 | for _, thread := range threadsToRestart { |
| 247 | thread.drainChan = make(chan struct{}) |
| 248 | thread.state.Set(state.Ready) |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | func (worker *worker) attachThread(thread *phpThread) { |
| 253 | worker.threadMutex.Lock() |