From bdc6191f89dfd0b0f3b7847b8448451af66d7982 Mon Sep 17 00:00:00 2001 From: Ivan Kalita Date: Mon, 3 Apr 2017 22:47:39 +0300 Subject: [PATCH 1/2] Add StreamSelectLoop test for timer with small interval. --- tests/StreamSelectLoopTest.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/StreamSelectLoopTest.php b/tests/StreamSelectLoopTest.php index 5cb957b7..d2e3e078 100644 --- a/tests/StreamSelectLoopTest.php +++ b/tests/StreamSelectLoopTest.php @@ -4,6 +4,7 @@ use React\EventLoop\LoopInterface; use React\EventLoop\StreamSelectLoop; +use React\EventLoop\Timer\Timer; class StreamSelectLoopTest extends AbstractLoopTest { @@ -145,4 +146,34 @@ protected function forkSendSignal($signal) die(); } } + + /** + * https://github.com/reactphp/event-loop/issues/48 + * + * Tests that timer with very small interval uses at least 1 microsecond + * timeout. + */ + public function testSmallTimerInterval() + { + /** @var StreamSelectLoop|\PHPUnit_Framework_MockObject_MockObject $loop */ + $loop = $this->getMock('React\EventLoop\StreamSelectLoop', ['streamSelect']); + $loop + ->expects($this->at(0)) + ->method('streamSelect') + ->with([], [], 1); + $loop + ->expects($this->at(1)) + ->method('streamSelect') + ->with([], [], 0); + + $callsCount = 0; + $loop->addPeriodicTimer(Timer::MIN_INTERVAL, function() use (&$loop, &$callsCount) { + $callsCount++; + if ($callsCount == 2) { + $loop->stop(); + } + }); + + $loop->run(); + } } From 09cd0bcb4038dea3e84283984a011fc2c32285f0 Mon Sep 17 00:00:00 2001 From: Ivan Kalita Date: Mon, 3 Apr 2017 23:10:33 +0300 Subject: [PATCH 2/2] Add StreamSelectLoop timeout rounding. --- src/StreamSelectLoop.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/StreamSelectLoop.php b/src/StreamSelectLoop.php index da5ddaa4..92fc5787 100644 --- a/src/StreamSelectLoop.php +++ b/src/StreamSelectLoop.php @@ -159,7 +159,11 @@ public function run() if ($timeout < 0) { $timeout = 0; } else { - $timeout *= self::MICROSECONDS_PER_SECOND; + /* + * round() needed to correct float error: + * https://github.com/reactphp/event-loop/issues/48 + */ + $timeout = round($timeout * self::MICROSECONDS_PER_SECOND); } // The only possible event is stream activity, so wait forever ...