diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc858562..fa78b8cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,7 @@ jobs: strategy: matrix: php: + - 8.5 - 8.4 - 8.3 - 8.2 @@ -49,6 +50,7 @@ jobs: strategy: matrix: php: + - 8.5 - 8.4 - 8.3 - 8.2 @@ -113,6 +115,7 @@ jobs: strategy: matrix: php: + - 8.5 - 8.4 - 8.3 - 8.2 diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php index a3fcec68..7689ff57 100644 --- a/src/ExtEvLoop.php +++ b/src/ExtEvLoop.php @@ -143,13 +143,13 @@ public function addTimer($interval, $callback) $callback = function () use ($timer, $timers, $that) { \call_user_func($timer->getCallback(), $timer); - if ($timers->contains($timer)) { + if ($timers->offsetExists($timer)) { $that->cancelTimer($timer); } }; $event = $this->loop->timer($timer->getInterval(), 0.0, $callback); - $this->timers->attach($timer, $event); + $this->timers->offsetSet($timer, $event); return $timer; } @@ -163,7 +163,7 @@ public function addPeriodicTimer($interval, $callback) }; $event = $this->loop->timer($timer->getInterval(), $timer->getInterval(), $callback); - $this->timers->attach($timer, $event); + $this->timers->offsetSet($timer, $event); return $timer; } @@ -176,7 +176,7 @@ public function cancelTimer(TimerInterface $timer) $event = $this->timers[$timer]; $event->stop(); - $this->timers->detach($timer); + $this->timers->offsetUnset($timer); } public function futureTick($listener) diff --git a/src/ExtEventLoop.php b/src/ExtEventLoop.php index b162a402..2f26d746 100644 --- a/src/ExtEventLoop.php +++ b/src/ExtEventLoop.php @@ -64,7 +64,7 @@ public function __destruct() { // explicitly clear all references to Event objects to prevent SEGFAULTs on Windows foreach ($this->timerEvents as $timer) { - $this->timerEvents->detach($timer); + $this->timerEvents->offsetUnset($timer); } $this->readEvents = array(); @@ -157,9 +157,9 @@ public function addPeriodicTimer($interval, $callback) public function cancelTimer(TimerInterface $timer) { - if ($this->timerEvents->contains($timer)) { + if ($this->timerEvents->offsetExists($timer)) { $this->timerEvents[$timer]->free(); - $this->timerEvents->detach($timer); + $this->timerEvents->offsetUnset($timer); } } @@ -243,7 +243,7 @@ private function createTimerCallback() $this->timerCallback = function ($_, $__, $timer) use ($timers) { \call_user_func($timer->getCallback(), $timer); - if (!$timer->isPeriodic() && $timers->contains($timer)) { + if (!$timer->isPeriodic() && $timers->offsetExists($timer)) { $this->cancelTimer($timer); } }; diff --git a/src/ExtUvLoop.php b/src/ExtUvLoop.php index 4434720d..29aa86b4 100644 --- a/src/ExtUvLoop.php +++ b/src/ExtUvLoop.php @@ -119,13 +119,13 @@ public function addTimer($interval, $callback) $callback = function () use ($timer, $timers, $that) { \call_user_func($timer->getCallback(), $timer); - if ($timers->contains($timer)) { + if ($timers->offsetExists($timer)) { $that->cancelTimer($timer); } }; $event = \uv_timer_init($this->uv); - $this->timers->attach($timer, $event); + $this->timers->offsetSet($timer, $event); \uv_timer_start( $event, $this->convertFloatSecondsToMilliseconds($interval), @@ -149,7 +149,7 @@ public function addPeriodicTimer($interval, $callback) $interval = $this->convertFloatSecondsToMilliseconds($interval); $event = \uv_timer_init($this->uv); - $this->timers->attach($timer, $event); + $this->timers->offsetSet($timer, $event); \uv_timer_start( $event, $interval, @@ -167,7 +167,7 @@ public function cancelTimer(TimerInterface $timer) { if (isset($this->timers[$timer])) { @\uv_timer_stop($this->timers[$timer]); - $this->timers->detach($timer); + $this->timers->offsetUnset($timer); } } @@ -329,9 +329,17 @@ private function convertFloatSecondsToMilliseconds($interval) } $maxValue = (int) (\PHP_INT_MAX / 1000); - $intInterval = (int) $interval; + $intervalOverflow = false; + if (PHP_VERSION_ID > 80499 && $interval >= \PHP_INT_MAX + 1) { + $intervalOverflow = true; + } else { + $intInterval = (int) $interval; + if (($intInterval <= 0 && $interval > 1) || $intInterval >= $maxValue) { + $intervalOverflow = true; + } + } - if (($intInterval <= 0 && $interval > 1) || $intInterval >= $maxValue) { + if ($intervalOverflow) { throw new \InvalidArgumentException( "Interval overflow, value must be lower than '{$maxValue}', but '{$interval}' passed." ); diff --git a/tests/LoopTest.php b/tests/LoopTest.php index 42f85244..25b6e855 100644 --- a/tests/LoopTest.php +++ b/tests/LoopTest.php @@ -64,7 +64,9 @@ public function testStaticAddReadStreamCallsAddReadStreamOnLoopInstance() public function testStaticAddReadStreamWithNoDefaultLoopCallsAddReadStreamOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $stream = stream_socket_server('127.0.0.1:0'); @@ -90,7 +92,9 @@ public function testStaticAddWriteStreamCallsAddWriteStreamOnLoopInstance() public function testStaticAddWriteStreamWithNoDefaultLoopCallsAddWriteStreamOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $stream = stream_socket_server('127.0.0.1:0'); @@ -115,7 +119,9 @@ public function testStaticRemoveReadStreamCallsRemoveReadStreamOnLoopInstance() public function testStaticRemoveReadStreamWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $stream = tmpfile(); @@ -139,7 +145,9 @@ public function testStaticRemoveWriteStreamCallsRemoveWriteStreamOnLoopInstance( public function testStaticRemoveWriteStreamWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $stream = tmpfile(); @@ -167,7 +175,9 @@ public function testStaticAddTimerCallsAddTimerOnLoopInstanceAndReturnsTimerInst public function testStaticAddTimerWithNoDefaultLoopCallsAddTimerOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $interval = 1.0; @@ -197,7 +207,9 @@ public function testStaticAddPeriodicTimerCallsAddPeriodicTimerOnLoopInstanceAnd public function testStaticAddPeriodicTimerWithNoDefaultLoopCallsAddPeriodicTimerOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $interval = 1.0; @@ -224,7 +236,9 @@ public function testStaticCancelTimerCallsCancelTimerOnLoopInstance() public function testStaticCancelTimerWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); @@ -248,7 +262,9 @@ public function testStaticFutureTickCallsFutureTickOnLoopInstance() public function testStaticFutureTickWithNoDefaultLoopCallsFutureTickOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $listener = function () { }; @@ -277,7 +293,9 @@ public function testStaticAddSignalWithNoDefaultLoopCallsAddSignalOnNewLoopInsta } $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $signal = 1; @@ -307,7 +325,9 @@ public function testStaticRemoveSignalCallsRemoveSignalOnLoopInstance() public function testStaticRemoveSignalWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $signal = 1; @@ -330,7 +350,9 @@ public function testStaticRunCallsRunOnLoopInstance() public function testStaticRunWithNoDefaultLoopCallsRunsOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); Loop::run(); @@ -351,7 +373,9 @@ public function testStaticStopCallsStopOnLoopInstance() public function testStaticStopCallWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); Loop::stop(); @@ -366,7 +390,9 @@ public function testStaticStopCallWithNoDefaultLoopIsNoOp() public function unsetLoopFromLoopAccessor() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); } }