1
0
mirror of https://github.com/danog/amp.git synced 2024-11-30 04:29:08 +01:00

Fix signal handler in NativeDriver when used with pcntl_async_signals

Fixes #264.
This commit is contained in:
Aaron Piotrowski 2019-02-25 18:05:47 -06:00
parent afb6000f32
commit ef83723a79
No known key found for this signature in database
GPG Key ID: ADD1EF783EDE9EEB
2 changed files with 29 additions and 1 deletions

View File

@ -2,6 +2,7 @@
namespace Amp\Loop; namespace Amp\Loop;
use Amp\CallableMaker;
use Amp\Coroutine; use Amp\Coroutine;
use Amp\Promise; use Amp\Promise;
use React\Promise\PromiseInterface as ReactPromise; use React\Promise\PromiseInterface as ReactPromise;
@ -10,6 +11,8 @@ use function Amp\Promise\rethrow;
class NativeDriver extends Driver class NativeDriver extends Driver
{ {
use CallableMaker;
/** @var resource[] */ /** @var resource[] */
private $readStreams = []; private $readStreams = [];
@ -297,7 +300,7 @@ class NativeDriver extends Driver
case Watcher::SIGNAL: case Watcher::SIGNAL:
if (!isset($this->signalWatchers[$watcher->value])) { if (!isset($this->signalWatchers[$watcher->value])) {
if (!@\pcntl_signal($watcher->value, [$this, 'handleSignal'])) { if (!@\pcntl_signal($watcher->value, $this->callableFromInstanceMethod('handleSignal'))) {
$message = "Failed to register signal handler"; $message = "Failed to register signal handler";
if ($error = \error_get_last()) { if ($error = \error_get_last()) {
$message .= \sprintf("; Errno: %d; %s", $error["type"], $error["message"]); $message .= \sprintf("; Errno: %d; %s", $error["type"], $error["message"]);

View File

@ -2,6 +2,7 @@
namespace Amp\Test\Loop; namespace Amp\Test\Loop;
use Amp\Loop\Driver;
use Amp\Loop\NativeDriver; use Amp\Loop\NativeDriver;
class NativeDriverTest extends DriverTest class NativeDriverTest extends DriverTest
@ -17,4 +18,28 @@ class NativeDriverTest extends DriverTest
{ {
$this->assertNull($this->loop->getHandle()); $this->assertNull($this->loop->getHandle());
} }
/**
* @requires PHP 7.1
*/
public function testAsyncSignals()
{
\pcntl_async_signals(true);
try {
$this->start(function (Driver $loop) use (&$invoked) {
$watcher = $loop->onSignal(SIGUSR1, function () use (&$invoked) {
$invoked = true;
});
$loop->unreference($watcher);
$loop->defer(function () {
\posix_kill(\getmypid(), \SIGUSR1);
});
});
} finally {
\pcntl_async_signals(false);
}
$this->assertTrue($invoked);
}
} }