From f80ace6d54dea5cfe34cc44a73d59533b7ff5334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 7 May 2019 21:24:38 +0200 Subject: [PATCH] Check PCNTL functions for signal support instead of PCNTL extension This helps avoiding problems when the PCNTL extension is loaded, but (some of) its functions are disabled via PHPs `disable_function` configuration. This is particularly common for the PCNTL functions in CGI environments, e.g. they are disabled by default on Debian- / Ubuntu-based distributions. Previously, even when not attaching any signal listeners, the loop would print a warning on each loop tick: > PHP Warning: pcntl_signal_dispatch() has been disabled for security reasons in {file} on {line} --- src/StreamSelectLoop.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/StreamSelectLoop.php b/src/StreamSelectLoop.php index a11aca3e..3362d3e5 100644 --- a/src/StreamSelectLoop.php +++ b/src/StreamSelectLoop.php @@ -62,18 +62,19 @@ final class StreamSelectLoop implements LoopInterface private $writeListeners = array(); private $running; private $pcntl = false; - private $pcntlActive = false; + private $pcntlPoll = false; private $signals; public function __construct() { $this->futureTickQueue = new FutureTickQueue(); $this->timers = new Timers(); - $this->pcntl = \extension_loaded('pcntl'); - $this->pcntlActive = $this->pcntl && !\function_exists('pcntl_async_signals'); + $this->pcntl = \function_exists('pcntl_signal') && \function_exists('pcntl_signal_dispatch'); + $this->pcntlPoll = $this->pcntl && !\function_exists('pcntl_async_signals'); $this->signals = new SignalsHandler(); - if ($this->pcntl && !$this->pcntlActive) { + // prefer async signals if available (PHP 7.1+) or fall back to dispatching on each tick + if ($this->pcntl && !$this->pcntlPoll) { \pcntl_async_signals(true); } } @@ -228,7 +229,7 @@ private function waitForStreamActivity($timeout) $write = $this->writeStreams; $available = $this->streamSelect($read, $write, $timeout); - if ($this->pcntlActive) { + if ($this->pcntlPoll) { \pcntl_signal_dispatch(); } if (false === $available) {