Commit 23bfbd0
committed
ext/pcntl: do not drop queued signals when an exception is pending
pcntl_signal_dispatch() takes the whole queue out of PCNTL_G(head) before it
starts calling handlers, and recycles every entry it walks over. Two paths let
signals disappear that way.
The first one is the interrupt handler. ZEND_VM_FCALL_INTERRUPT_CHECK() runs
right after an internal function returns, before the pending exception is
handled, so pcntl_interrupt_function() reaches the dispatcher with EG(exception)
set. call_user_function() returns without calling anything in that state, the
"if (EG(exception)) break" added by 296fad1 fires on the first entry, and
the drain loop then recycles the entire queue without a single handler having
run. Setting the exception aside for the duration of the dispatch, the way
zend_lookup_class_ex() does around autoloading, lets the handlers run.
The second one is a handler that throws while other signals are queued behind
it: those were recycled too. They now go back to the queue, so the next
dispatch delivers them.
This is reachable from any long blocking internal call that throws on timeout.
pecl/amqp is one: AMQPQueue::consume() throws "Consumer timeout exceed" when
the read timeout expires, which made a Symfony messenger worker built on it
miss every SIGTERM, whatever the timeout was.1 parent 7ef3bfe commit 23bfbd0
3 files changed
Lines changed: 77 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
5 | 9 | | |
6 | 10 | | |
7 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1345 | 1345 | | |
1346 | 1346 | | |
1347 | 1347 | | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
1348 | 1353 | | |
1349 | 1354 | | |
| 1355 | + | |
| 1356 | + | |
1350 | 1357 | | |
1351 | 1358 | | |
1352 | 1359 | | |
| |||
1365 | 1372 | | |
1366 | 1373 | | |
1367 | 1374 | | |
1368 | | - | |
1369 | | - | |
1370 | | - | |
| 1375 | + | |
1371 | 1376 | | |
1372 | 1377 | | |
1373 | 1378 | | |
1374 | 1379 | | |
1375 | 1380 | | |
1376 | 1381 | | |
1377 | 1382 | | |
1378 | | - | |
1379 | 1383 | | |
1380 | | - | |
1381 | | - | |
1382 | | - | |
1383 | | - | |
1384 | | - | |
1385 | | - | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
1386 | 1388 | | |
1387 | 1389 | | |
1388 | | - | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
| 1396 | + | |
| 1397 | + | |
| 1398 | + | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
1389 | 1407 | | |
1390 | 1408 | | |
1391 | 1409 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
0 commit comments