From 8b7aaad7d65779b1d6497436b4e7da52f53d159c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Dec 2020 12:57:30 +0100 Subject: Try SIGTERM before SIGKILL in opcache restart SIGTERM is subject to HANDLE_BLOCK_INTERRUPTIONS(), which will allow code to exit critical sections before it gets terminated. Closes GH-6493. --- ext/opcache/ZendAccelerator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 7cc301013b..189cfca279 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -774,14 +774,15 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) /* so that other process won't try to force while we are busy cleaning up */ ZCSG(force_restart_time) = 0; while (mem_usage_check->l_pid > 0) { - /* Clear previous errno, reset success and tries */ + /* Try SIGTERM first, switch to SIGKILL if not successful. */ + int signal = SIGTERM; errno = 0; success = 0; tries = 10; while (tries--) { zend_accel_error(ACCEL_LOG_WARNING, "Attempting to kill locker %d", mem_usage_check->l_pid); - if (kill(mem_usage_check->l_pid, SIGKILL)) { + if (kill(mem_usage_check->l_pid, signal)) { if (errno == ESRCH) { /* Process died before the signal was sent */ success = 1; @@ -800,6 +801,8 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) break; } usleep(10000); + /* If SIGTERM was not sufficient, use SIGKILL. */ + signal = SIGKILL; } if (!success) { /* errno is not ESRCH or we ran out of tries to kill the locker */ -- cgit v1.2.1