diff --git a/src/Util/PcntlTimeout.php b/src/Util/PcntlTimeout.php index 4fd1ca6..88705f7 100644 --- a/src/Util/PcntlTimeout.php +++ b/src/Util/PcntlTimeout.php @@ -59,21 +59,22 @@ public function __construct(int $timeout) */ public function timeBoxed(callable $code) { - $existingHandler = pcntl_signal_get_handler(\SIGALRM); + if (pcntl_alarm($this->timeout) !== 0) { + throw new LockAcquireException('Existing process alarm is not supported'); + } + + $origSignalHandler = pcntl_signal_get_handler(\SIGALRM); - $signal = pcntl_signal(\SIGALRM, function (): void { + $timeout = $this->timeout; + $signalHandlerFx = static function () use ($timeout): void { throw new DeadlineException(sprintf( 'Timebox hit deadline of %d seconds', - $this->timeout + $timeout )); - }); - if (!$signal) { - throw new LockAcquireException('Could not install signal handler'); - } + }; - $oldAlarm = pcntl_alarm($this->timeout); - if ($oldAlarm !== 0) { - throw new LockAcquireException('Existing alarm was not expected'); + if (!pcntl_signal(\SIGALRM, $signalHandlerFx)) { + throw new LockAcquireException('Failed to install signal handler'); } try { @@ -83,7 +84,7 @@ public function timeBoxed(callable $code) try { pcntl_signal_dispatch(); } finally { - pcntl_signal(\SIGALRM, $existingHandler); + pcntl_signal(\SIGALRM, $origSignalHandler); } } } diff --git a/tests/Util/PcntlTimeoutTest.php b/tests/Util/PcntlTimeoutTest.php index da6d690..9ed8794 100644 --- a/tests/Util/PcntlTimeoutTest.php +++ b/tests/Util/PcntlTimeoutTest.php @@ -48,16 +48,19 @@ public function testShouldNotTimeout(): void */ public function testShouldFailOnExistingAlarm(): void { + $origSignalHandler = pcntl_signal_get_handler(\SIGALRM); try { pcntl_alarm(1); $timeout = new PcntlTimeout(1); $this->expectException(LockAcquireException::class); + $this->expectExceptionMessage('Existing process alarm is not supported'); $timeout->timeBoxed(static function () { sleep(1); }); } finally { pcntl_alarm(0); + self::assertSame($origSignalHandler, pcntl_signal_get_handler(\SIGALRM)); } }