diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 871d3f4e..7bde850f 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 @@ -44,6 +45,8 @@ jobs: strategy: matrix: php: + - 8.5 + - 8.4 - 8.3 - 8.2 - 8.1 @@ -78,6 +81,7 @@ jobs: strategy: matrix: php: + - 8.5 - 8.4 - 8.3 - 8.2 diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php index 363ad0c4..a069dd18 100644 --- a/src/ExtEvLoop.php +++ b/src/ExtEvLoop.php @@ -141,13 +141,13 @@ public function addTimer($interval, $callback) $callback = function () use ($timer) { \call_user_func($timer->getCallback(), $timer); - if ($this->timers->contains($timer)) { + if ($this->timers->offsetExists($timer)) { $this->cancelTimer($timer); } }; $event = $this->loop->timer($timer->getInterval(), 0.0, $callback); - $this->timers->attach($timer, $event); + $this->timers->offsetSet($timer, $event); return $timer; } @@ -161,7 +161,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; } @@ -174,7 +174,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 d6f24b2a..d18fb16c 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 = []; @@ -153,9 +153,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); } } @@ -238,7 +238,7 @@ private function createTimerCallback() $this->timerCallback = function ($_, $__, $timer) { \call_user_func($timer->getCallback(), $timer); - if (!$timer->isPeriodic() && $this->timerEvents->contains($timer)) { + if (!$timer->isPeriodic() && $this->timerEvents->offsetExists($timer)) { $this->cancelTimer($timer); } }; diff --git a/src/ExtUvLoop.php b/src/ExtUvLoop.php index e9e79524..fd52c354 100644 --- a/src/ExtUvLoop.php +++ b/src/ExtUvLoop.php @@ -117,13 +117,13 @@ public function addTimer($interval, $callback) $callback = function () use ($timer) { \call_user_func($timer->getCallback(), $timer); - if ($this->timers->contains($timer)) { + if ($this->timers->offsetExists($timer)) { $this->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), @@ -147,7 +147,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, @@ -165,7 +165,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); } } @@ -326,9 +326,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 08e2107e..f5b3cd31 100644 --- a/tests/LoopTest.php +++ b/tests/LoopTest.php @@ -42,7 +42,9 @@ public function testStaticAddReadStreamCallsAddReadStreamOnLoopInstance() public function testStaticAddReadStreamWithNoDefaultLoopCallsAddReadStreamOnNewLoopInstance() { $ref = new \ReflectionProperty(Loop::class, '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'); @@ -68,7 +70,9 @@ public function testStaticAddWriteStreamCallsAddWriteStreamOnLoopInstance() public function testStaticAddWriteStreamWithNoDefaultLoopCallsAddWriteStreamOnNewLoopInstance() { $ref = new \ReflectionProperty(Loop::class, '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'); @@ -93,7 +97,9 @@ public function testStaticRemoveReadStreamCallsRemoveReadStreamOnLoopInstance() public function testStaticRemoveReadStreamWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $stream = tmpfile(); @@ -117,7 +123,9 @@ public function testStaticRemoveWriteStreamCallsRemoveWriteStreamOnLoopInstance( public function testStaticRemoveWriteStreamWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $stream = tmpfile(); @@ -145,7 +153,9 @@ public function testStaticAddTimerCallsAddTimerOnLoopInstanceAndReturnsTimerInst public function testStaticAddTimerWithNoDefaultLoopCallsAddTimerOnNewLoopInstance() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $interval = 1.0; @@ -175,7 +185,9 @@ public function testStaticAddPeriodicTimerCallsAddPeriodicTimerOnLoopInstanceAnd public function testStaticAddPeriodicTimerWithNoDefaultLoopCallsAddPeriodicTimerOnNewLoopInstance() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $interval = 1.0; @@ -202,7 +214,9 @@ public function testStaticCancelTimerCallsCancelTimerOnLoopInstance() public function testStaticCancelTimerWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $timer = $this->createMock(TimerInterface::class); @@ -226,7 +240,9 @@ public function testStaticFutureTickCallsFutureTickOnLoopInstance() public function testStaticFutureTickWithNoDefaultLoopCallsFutureTickOnNewLoopInstance() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $listener = function () { }; @@ -255,7 +271,9 @@ public function testStaticAddSignalWithNoDefaultLoopCallsAddSignalOnNewLoopInsta } $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $signal = 1; @@ -285,7 +303,9 @@ public function testStaticRemoveSignalCallsRemoveSignalOnLoopInstance() public function testStaticRemoveSignalWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); $signal = 1; @@ -308,7 +328,9 @@ public function testStaticRunCallsRunOnLoopInstance() public function testStaticRunWithNoDefaultLoopCallsRunsOnNewLoopInstance() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); Loop::run(); @@ -329,7 +351,9 @@ public function testStaticStopCallsStopOnLoopInstance() public function testStaticStopCallWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); Loop::stop(); @@ -344,7 +368,9 @@ public function testStaticStopCallWithNoDefaultLoopIsNoOp() public function unsetLoopFromLoopAccessor() { $ref = new \ReflectionProperty(Loop::class, 'instance'); - $ref->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $ref->setAccessible(true); + } $ref->setValue(null, null); } }