[php-src] PR #24272: Fix OPcache releasing other threads' SHM locks under ZTS

From: Date: Mon, 12 Oct 2026 13:33:22 +0000
Subject: [php-src] PR #24272: Fix OPcache releasing other threads' SHM locks under ZTS
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39356@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24272 Author: pavimus Prepared with an AI assistant (Claude), which also ran the reproduction and the tests on my machine; I reviewed the result. The text below is AI-generated (quoted, as asked in CONTRIBUTING.md). > While working on GH-8739 for threaded SAPIs we found that Apache with a threaded MPM and > mod_php ZTS crashes during warm-up even without any OPcache restart. This is a small, separate fix. > > accel_unlock_all() runs at the end of every request (and in > RINIT for a "stuck count") and > unlocks the whole lock file (l_start = 0, l_len = 0). ¡ > û>í`d’dçMŽfcntl() record locks belong to the > process, so under ZTS a thread ending its request also releases > > - byte 0, the SHM write lock that another thread of the same process holds inside > zend_shared_alloc_lock() (that thread still holds > zts_lock and keeps writing), and > - byte 2, the restart lock. > > With several multi-threaded processes sharing the cache (Apache event/worker MPM + mod_php ZTS) > another process can then take the write lock, and two processes modify SHM at the same time. > > Evidence (AArch64 Linux, Apache 2.4 event, 3 children x 32 threads, 128M SHM, no restart): > > - A debug counter of threads inside zend_shared_alloc_lock(), > kept in shared memory, saw two > processes writing concurrently in 4 of 5 cold starts; with this change 0 of 5. > - Children crashed before the first restart in 6 of 13 stock runs (SIGSEGV in > accel_find_interned_string() on a garbage string table > position, and in > zend_hash_find_bucket() on a class method table); 0 of 13 > with this change. > > Bytes 0 and 2 are always released by the thread that took them > (zend_shared_alloc_unlock(), > zend_shared_alloc_safe_unlock() in post_deactivate, > accel_restart_leave()), so under ZTS only > the reader lock (byte 1) is released. NTS is unchanged. > > This does not fix the restart race of GH-8739 (threads of the restarting process are still > invisible to the F_GETLK probe); that is a separate PR for > GH-8739, which builds on this commit. 🤖 Generated with [Claude Code](https://claude.com/claude-code)

« previous php.git-pulls (#39356) next »