From 6241c0e577a83c107e65ec0d13b2f0469f088d67 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Wed, 3 Sep 2014 13:35:11 -0700 Subject: [PATCH 01/18] add support for Ev extension (libev) --- src/ExtEvLoop.php | 228 +++++++++++++++++++++++++++++++++++++ tests/AbstractLoopTest.php | 19 ++++ tests/ExtEvLoopTest.php | 40 +++++++ 3 files changed, 287 insertions(+) create mode 100644 src/ExtEvLoop.php create mode 100644 tests/ExtEvLoopTest.php diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php new file mode 100644 index 00000000..f383c37a --- /dev/null +++ b/src/ExtEvLoop.php @@ -0,0 +1,228 @@ +loop = new \EvLoop(); + $this->timers = new SplObjectStorage(); + $this->nextTickQueue = new NextTickQueue($this); + $this->futureTickQueue = new FutureTickQueue($this); + $this->timers = new SplObjectStorage(); + } + + /** + * Add a readable stream to the event loop + * @param stream $stream PHP stream resource + * @param callable $listener Callback + * @return void + */ + public function addReadStream($stream, callable $listener) + { + $this->addStream($stream, $listener, \Ev::READ); + } + + /** + * Add a writable stream to the event loop + * @param stream $stream PHP stream resource + * @param callable $listener Callback + * @return void + */ + public function addWriteStream($stream, callable $listener) + { + $this->addStream($stream, $listener, \Ev::WRITE); + } + + /** + * Remove a readable stream from the event loop. + * @param stream $stream PHP stream resource + * @return void + */ + public function removeReadStream($stream) + { + $key = (int) $stream; + if(isset($this->readEvents[$key])) { + $this->readEvents[$key]->stop(); + unset($this->readEvents[$key]); + } + } + + /** + * remove a writable stream from the event loop + * @param stream $stream PHP stream resource + * @return void + */ + public function removeWriteStream($stream) + { + $key = (int) $stream; + if(isset($this->writeEvents[$key])) { + $this->writeEvents[(int)$stream]->stop(); + unset($this->writeEvents[(int)$stream]); + } + } + + /** + * remove a stream from the event loop + * @param stream $stream PHP stream + * @return void + */ + public function removeStream($stream) + { + if (isset($this->readEvents[(int)$stream])) { + $this->removeReadStream($stream); + } + + if (isset($this->writeEvents[(int)$stream])) { + $this->removeWriteStream($stream); + } + } + + /** + * Wraps the listener in a callback which will pass the + * stream to the listener then registers the stream with + * the eventloop. + * + * @param stream $stream PHP Stream resource + * @param callable $listener stream callback + * @param bit $flags flag bitmask + */ + private function addStream($stream, callable $listener, $flags) + { + $listener = function ($event) use ($stream, $listener) { + call_user_func($listener, $stream); + }; + + $event = $this->loop->io($stream, $flags, $listener); + + if (($flags & \Ev::READ) === $flags) { + $this->readEvents[(int)$stream] = $event; + } elseif (($flags & \Ev::WRITE) === $flags) { + $this->writeEvents[(int)$stream] = $event; + } + } + + /** + * {@inheritdoc} + */ + public function addTimer($interval, callable $callback) + { + $timer = new Timer($this, $interval, $callback, false); + $this->setupTimer($timer); + + return $timer; + } + + /** + * {@inheritdoc} + */ + public function addPeriodicTimer($interval, callable $callback) + { + $timer = new Timer($this, $interval, $callback, true); + $this->setupTimer($timer); + + return $timer; + } + + /** + * {@inheritdoc} + */ + public function cancelTimer(TimerInterface $timer) + { + if (isset($this->timers[$timer])) { + /* stop EvTimer */ + $this->timers[$timer]->stop(); + $this->timers->detach($timer); + } + } + + /** + * Add timer object as + * @param TimerInterface $timer [description] + * @return [type] [description] + */ + private function setupTimer(TimerInterface $timer) + { + $callback = function () use ($timer) { + call_user_func($timer->getCallback(), $timer); + + if (!$timer->isPeriodic()) { + $timer->cancel(); + } + }; + + $interval = $timer->getInterval(); + + $libevTimer = $this->loop->timer($interval, $interval, $callback); + + $this->timers->attach($timer, $libevTimer); + + return $timer; + } + + public function isTimerActive(TimerInterface $timer) + { + return $this->timers->contains($timer); + } + + + /** + * {@inheritdoc} + */ + public function nextTick(callable $listener) + { + $this->nextTickQueue->add($listener); + } + + /** + * {@inheritdoc} + */ + public function futureTick(callable $listener) + { + $this->futureTickQueue->add($listener); + } + + + public function tick() + { + $this->nextTickQueue->tick(); + $this->futureTickQueue->tick(); + + $flags = \Ev::RUN_ONCE; + if (!$this->running || !$this->nextTickQueue->isEmpty() || !$this->futureTickQueue->isEmpty()) { + $flags |= \Ev::RUN_NOWAIT; + } elseif (!$this->readEvents && !$this->writeEvents && !$this->timers->count()) { + $this->running = false; + return; + } + $this->loop->run($flags); + } + + public function run() + { + $this->running = true; + while($this->running) { + $this->tick(); + } + } + + public function stop() + { + $this->running = false; + } +} diff --git a/tests/AbstractLoopTest.php b/tests/AbstractLoopTest.php index b4095379..ffcb9ea2 100644 --- a/tests/AbstractLoopTest.php +++ b/tests/AbstractLoopTest.php @@ -355,6 +355,25 @@ function () { $this->loop->run(); } + public function testPeriodTimerExecutes() + { + $count = 0; + $this->loop->addPeriodicTimer( + 0.001, + function ($timer) use (&$count) { + echo 'tick'; + $count++; + if($count === 3) { + $timer->cancel(); + } + } + ); + + $this->expectOutputString('tickticktick'); + + $this->loop->run(); + } + public function testFutureTick() { $called = false; diff --git a/tests/ExtEvLoopTest.php b/tests/ExtEvLoopTest.php new file mode 100644 index 00000000..d05dbba3 --- /dev/null +++ b/tests/ExtEvLoopTest.php @@ -0,0 +1,40 @@ +markTestSkipped('ev tests skipped because pecl/ev is not installed.'); + } + + return new ExtEvLoop(); + } + + public function tearDown() + { + if (file_exists($this->file)) { + unlink($this->file); + } + } + + public function createStream() + { + $this->file = tempnam(sys_get_temp_dir(), 'react-'); + + $stream = fopen($this->file, 'r+'); + + return $stream; + } + + public function testEvConstructor() + { + $loop = new ExtEvLoop(); + } +} From 8e847eafafff08db4168c2b9bfb6bc78ae33d467 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Wed, 3 Sep 2014 14:00:56 -0700 Subject: [PATCH 02/18] adding ev extension to travis --- travis-init.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/travis-init.sh b/travis-init.sh index 6df76d72..397e851c 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -20,6 +20,17 @@ if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then popd echo "extension=libevent.so" >> "$(php -r 'echo php_ini_loaded_file();')" + # install 'pecl-ev' PHP extension + git clone http://bitbucket.org/osmanov/pecl-ev.git + # 0.2.10 + pushd pecl-ev + phpize + ./configure + make + make install + popd + echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" + # install 'libev' PHP extension git clone --recursive https://github.com/m4rw3r/php-libev pushd php-libev From b2b68c61b869c87e6250f9a24f5bff6367aa924f Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Wed, 3 Sep 2014 17:39:07 -0700 Subject: [PATCH 03/18] Resolve segfaulting issues with pecl-ev --- .travis.yml | 5 ++++- script.gdb | 3 +++ src/ExtEvLoop.php | 29 +++++++++++++++++++++++++---- tests/AbstractLoopTest.php | 19 ------------------- travis-init.sh | 1 + 5 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 script.gdb diff --git a/.travis.yml b/.travis.yml index 0b94b225..4460f900 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,10 @@ matrix: allow_failures: - php: hhvm +before_script: + - sudo apt-get install gdb + install: ./travis-init.sh script: - - phpunit --coverage-text + - phpunit --coverage-text diff --git a/script.gdb b/script.gdb new file mode 100644 index 00000000..34e270dc --- /dev/null +++ b/script.gdb @@ -0,0 +1,3 @@ +set env MALLOC_CHECK_=3 +run +backtrace full \ No newline at end of file diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php index f383c37a..26235e54 100644 --- a/src/ExtEvLoop.php +++ b/src/ExtEvLoop.php @@ -16,6 +16,7 @@ class ExtEvLoop implements LoopInterface private $timers; private $readEvents = array(); private $writeEvents = array(); + private $running = false; public function __construct() @@ -58,7 +59,7 @@ public function removeReadStream($stream) { $key = (int) $stream; if(isset($this->readEvents[$key])) { - $this->readEvents[$key]->stop(); + $this->readEvents[$key]->stop(); unset($this->readEvents[$key]); } } @@ -72,8 +73,8 @@ public function removeWriteStream($stream) { $key = (int) $stream; if(isset($this->writeEvents[$key])) { - $this->writeEvents[(int)$stream]->stop(); - unset($this->writeEvents[(int)$stream]); + $this->writeEvents[$key]->stop(); + unset($this->writeEvents[$key]); } } @@ -147,7 +148,11 @@ public function cancelTimer(TimerInterface $timer) if (isset($this->timers[$timer])) { /* stop EvTimer */ $this->timers[$timer]->stop(); - $this->timers->detach($timer); + + /* defer timer */ + $this->nextTick(function() use ($timer) { + $this->timers->detach($timer); + }); } } @@ -225,4 +230,20 @@ public function stop() { $this->running = false; } + + public function __destruct() + { + // mannually stop all watchers + foreach($this->timers as $timer) { + $this->timers[$timer]->stop(); + } + + foreach($this->readEvents as $event) { + $event->stop(); + } + + foreach($this->writeEvents as $event) { + $event->stop(); + } + } } diff --git a/tests/AbstractLoopTest.php b/tests/AbstractLoopTest.php index ffcb9ea2..b4095379 100644 --- a/tests/AbstractLoopTest.php +++ b/tests/AbstractLoopTest.php @@ -355,25 +355,6 @@ function () { $this->loop->run(); } - public function testPeriodTimerExecutes() - { - $count = 0; - $this->loop->addPeriodicTimer( - 0.001, - function ($timer) use (&$count) { - echo 'tick'; - $count++; - if($count === 3) { - $timer->cancel(); - } - } - ); - - $this->expectOutputString('tickticktick'); - - $this->loop->run(); - } - public function testFutureTick() { $called = false; diff --git a/travis-init.sh b/travis-init.sh index 397e851c..acd6c98c 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -27,6 +27,7 @@ if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpize ./configure make + # make test make install popd echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" From a496c635bed51378d71fed733629ef15a9fe080c Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Mon, 15 Sep 2014 12:24:05 +0100 Subject: [PATCH 04/18] Docblock fixes - Change `stream` and `numeric` to valid phpdoc internal types - Add some docs to TimerInterface and Timer --- src/ExtEventLoop.php | 8 +++--- src/LibEventLoop.php | 8 +++--- src/LoopInterface.php | 18 +++++++------- src/Timer/Timer.php | 33 +++++++++++++++++++++++++ src/Timer/TimerInterface.php | 47 ++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 17 deletions(-) diff --git a/src/ExtEventLoop.php b/src/ExtEventLoop.php index 40b860ae..48657f96 100644 --- a/src/ExtEventLoop.php +++ b/src/ExtEventLoop.php @@ -236,8 +236,8 @@ private function scheduleTimer(TimerInterface $timer) /** * Create a new ext-event Event object, or update the existing one. * - * @param stream $stream - * @param integer $flag Event::READ or Event::WRITE + * @param resource $stream + * @param integer $flag Event::READ or Event::WRITE */ private function subscribeStreamEvent($stream, $flag) { @@ -263,8 +263,8 @@ private function subscribeStreamEvent($stream, $flag) * Update the ext-event Event object for this stream to stop listening to * the given event type, or remove it entirely if it's no longer needed. * - * @param stream $stream - * @param integer $flag Event::READ or Event::WRITE + * @param resource $stream + * @param integer $flag Event::READ or Event::WRITE */ private function unsubscribeStreamEvent($stream, $flag) { diff --git a/src/LibEventLoop.php b/src/LibEventLoop.php index a55d6104..6fbc8269 100644 --- a/src/LibEventLoop.php +++ b/src/LibEventLoop.php @@ -237,8 +237,8 @@ private function scheduleTimer(TimerInterface $timer) /** * Create a new ext-libevent event resource, or update the existing one. * - * @param stream $stream - * @param integer $flag EV_READ or EV_WRITE + * @param resource $stream + * @param integer $flag EV_READ or EV_WRITE */ private function subscribeStreamEvent($stream, $flag) { @@ -267,8 +267,8 @@ private function subscribeStreamEvent($stream, $flag) * Update the ext-libevent event resource for this stream to stop listening to * the given event type, or remove it entirely if it's no longer needed. * - * @param stream $stream - * @param integer $flag EV_READ or EV_WRITE + * @param resource $stream + * @param integer $flag EV_READ or EV_WRITE */ private function unsubscribeStreamEvent($stream, $flag) { diff --git a/src/LoopInterface.php b/src/LoopInterface.php index 24a80a3d..d046526c 100644 --- a/src/LoopInterface.php +++ b/src/LoopInterface.php @@ -9,7 +9,7 @@ interface LoopInterface /** * Register a listener to be notified when a stream is ready to read. * - * @param stream $stream The PHP stream resource to check. + * @param resource $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. */ public function addReadStream($stream, callable $listener); @@ -17,7 +17,7 @@ public function addReadStream($stream, callable $listener); /** * Register a listener to be notified when a stream is ready to write. * - * @param stream $stream The PHP stream resource to check. + * @param resource $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. */ public function addWriteStream($stream, callable $listener); @@ -25,21 +25,21 @@ public function addWriteStream($stream, callable $listener); /** * Remove the read event listener for the given stream. * - * @param stream $stream The PHP stream resource. + * @param resource $stream The PHP stream resource. */ public function removeReadStream($stream); /** * Remove the write event listener for the given stream. * - * @param stream $stream The PHP stream resource. + * @param resource $stream The PHP stream resource. */ public function removeWriteStream($stream); /** * Remove all listeners for the given stream. * - * @param stream $stream The PHP stream resource. + * @param resource $stream The PHP stream resource. */ public function removeStream($stream); @@ -49,8 +49,8 @@ public function removeStream($stream); * The execution order of timers scheduled to execute at the same time is * not guaranteed. * - * @param numeric $interval The number of seconds to wait before execution. - * @param callable $callback The callback to invoke. + * @param int|float $interval The number of seconds to wait before execution. + * @param callable $callback The callback to invoke. * * @return TimerInterface */ @@ -62,8 +62,8 @@ public function addTimer($interval, callable $callback); * The execution order of timers scheduled to execute at the same time is * not guaranteed. * - * @param numeric $interval The number of seconds to wait before execution. - * @param callable $callback The callback to invoke. + * @param int|float $interval The number of seconds to wait before execution. + * @param callable $callback The callback to invoke. * * @return TimerInterface */ diff --git a/src/Timer/Timer.php b/src/Timer/Timer.php index ac64d2b0..f670ab3c 100644 --- a/src/Timer/Timer.php +++ b/src/Timer/Timer.php @@ -14,6 +14,15 @@ class Timer implements TimerInterface protected $periodic; protected $data; + /** + * Constructor initializes the fields of the Timer + * + * @param LoopInterface $loop The loop with which this timer is associated + * @param float $interval The interval after which this timer will execute, in seconds + * @param callable $callback The callback that will be executed when this timer elapses + * @param bool $periodic Whether the time is periodic + * @param mixed $data Arbitrary data associated with timer + */ public function __construct(LoopInterface $loop, $interval, callable $callback, $periodic = false, $data = null) { if ($interval < self::MIN_INTERVAL) { @@ -27,41 +36,65 @@ public function __construct(LoopInterface $loop, $interval, callable $callback, $this->data = null; } + /** + * {@inheritdoc} + */ public function getLoop() { return $this->loop; } + /** + * {@inheritdoc} + */ public function getInterval() { return $this->interval; } + /** + * {@inheritdoc} + */ public function getCallback() { return $this->callback; } + /** + * {@inheritdoc} + */ public function setData($data) { $this->data = $data; } + /** + * {@inheritdoc} + */ public function getData() { return $this->data; } + /** + * {@inheritdoc} + */ public function isPeriodic() { return $this->periodic; } + /** + * {@inheritdoc} + */ public function isActive() { return $this->loop->isTimerActive($this); } + /** + * {@inheritdoc} + */ public function cancel() { $this->loop->cancelTimer($this); diff --git a/src/Timer/TimerInterface.php b/src/Timer/TimerInterface.php index 5982b314..717943fc 100644 --- a/src/Timer/TimerInterface.php +++ b/src/Timer/TimerInterface.php @@ -2,14 +2,61 @@ namespace React\EventLoop\Timer; +use React\EventLoop\LoopInterface; + interface TimerInterface { + /** + * Get the loop with which this timer is associated + + * @return LoopInterface + */ public function getLoop(); + + /** + * Get the interval after which this timer will execute, in seconds + * + * @return float + */ public function getInterval(); + + /** + * Get the callback that will be executed when this timer elapses + * + * @return callable + */ public function getCallback(); + + /** + * Set arbitrary data associated with timer + * + * @param mixed $data + */ public function setData($data); + + /** + * Get arbitrary data associated with timer + * + * @return mixed + */ public function getData(); + + /** + * Determine whether the time is periodic + * + * @return bool + */ public function isPeriodic(); + + /** + * Determine whether the time is active + * + * @return bool + */ public function isActive(); + + /** + * Cancel this timer + */ public function cancel(); } From 804d13cee75fd1fcd11811417a22b434ad12c21b Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Mon, 27 Oct 2014 15:16:21 +0100 Subject: [PATCH 05/18] Run php-cs on source code. [ci skip] --- src/Factory.php | 4 ++-- tests/ExtEventLoopTest.php | 2 +- tests/Timer/AbstractTimerTest.php | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index 207bc13c..9a481e35 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -9,9 +9,9 @@ public static function create() // @codeCoverageIgnoreStart if (function_exists('event_base_new')) { return new LibEventLoop(); - } else if (class_exists('libev\EventLoop', false)) { + } elseif (class_exists('libev\EventLoop', false)) { return new LibEvLoop; - } else if (class_exists('EventBase', false)) { + } elseif (class_exists('EventBase', false)) { return new ExtEventLoop; } diff --git a/tests/ExtEventLoopTest.php b/tests/ExtEventLoopTest.php index 93408ad9..80daaf24 100644 --- a/tests/ExtEventLoopTest.php +++ b/tests/ExtEventLoopTest.php @@ -17,7 +17,7 @@ public function createLoop($readStreamCompatible = false) } $cfg = null; - if($readStreamCompatible) { + if ($readStreamCompatible) { $cfg = new \EventConfig(); $cfg->requireFeatures(\EventConfig::FEATURE_FDS); } diff --git a/tests/Timer/AbstractTimerTest.php b/tests/Timer/AbstractTimerTest.php index bb26f52e..57689658 100644 --- a/tests/Timer/AbstractTimerTest.php +++ b/tests/Timer/AbstractTimerTest.php @@ -3,7 +3,6 @@ namespace React\Tests\EventLoop\Timer; use React\Tests\EventLoop\TestCase; -use React\EventLoop\Timer\Timers; abstract class AbstractTimerTest extends TestCase { From 126a6bd87f4f2af11fd9300053ba80a1d7a9361b Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Mon, 27 Oct 2014 14:09:07 -0700 Subject: [PATCH 06/18] removing gdb from travis --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4460f900..4bcab5c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,7 @@ matrix: allow_failures: - php: hhvm -before_script: - - sudo apt-get install gdb - install: ./travis-init.sh - + script: - phpunit --coverage-text From 8d12457e74c2920f1d4460c9c6e9c9db801b26d7 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Tue, 28 Oct 2014 11:20:35 +0100 Subject: [PATCH 07/18] Exclude phpunit.xml in .gitignore. [ci skip] --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 987e2a25..81b92580 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ composer.lock +phpunit.xml vendor From e5b0a0b5a89288bd60174c965096acb0679208d2 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Tue, 28 Oct 2014 11:56:47 +0100 Subject: [PATCH 08/18] Minor docblock fix. [ci skip] --- src/Timer/TimerInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Timer/TimerInterface.php b/src/Timer/TimerInterface.php index 717943fc..d066f369 100644 --- a/src/Timer/TimerInterface.php +++ b/src/Timer/TimerInterface.php @@ -8,7 +8,7 @@ interface TimerInterface { /** * Get the loop with which this timer is associated - + * * @return LoopInterface */ public function getLoop(); From 34b51b68606f0045a22a4462c350b99fbd661c31 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Tue, 4 Nov 2014 07:53:04 -0800 Subject: [PATCH 09/18] updates based on code review --- .travis.yml | 2 +- script.gdb | 3 -- src/ExtEvLoop.php | 75 ++++++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 44 deletions(-) delete mode 100644 script.gdb diff --git a/.travis.yml b/.travis.yml index 4bcab5c1..b329be87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ matrix: install: ./travis-init.sh script: - - phpunit --coverage-text + - phpunit --coverage-text diff --git a/script.gdb b/script.gdb deleted file mode 100644 index 34e270dc..00000000 --- a/script.gdb +++ /dev/null @@ -1,3 +0,0 @@ -set env MALLOC_CHECK_=3 -run -backtrace full \ No newline at end of file diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php index 26235e54..95f41880 100644 --- a/src/ExtEvLoop.php +++ b/src/ExtEvLoop.php @@ -12,7 +12,7 @@ class ExtEvLoop implements LoopInterface { private $loop; private $nextTickQueue; - private $futureTickQueue; + private $futureTickQueue; private $timers; private $readEvents = array(); private $writeEvents = array(); @@ -29,10 +29,7 @@ public function __construct() } /** - * Add a readable stream to the event loop - * @param stream $stream PHP stream resource - * @param callable $listener Callback - * @return void + * {@inheritdoc} */ public function addReadStream($stream, callable $listener) { @@ -40,10 +37,7 @@ public function addReadStream($stream, callable $listener) } /** - * Add a writable stream to the event loop - * @param stream $stream PHP stream resource - * @param callable $listener Callback - * @return void + * {@inheritdoc} */ public function addWriteStream($stream, callable $listener) { @@ -51,62 +45,51 @@ public function addWriteStream($stream, callable $listener) } /** - * Remove a readable stream from the event loop. - * @param stream $stream PHP stream resource - * @return void + * {@inheritdoc} */ public function removeReadStream($stream) { $key = (int) $stream; - if(isset($this->readEvents[$key])) { - $this->readEvents[$key]->stop(); + if (isset($this->readEvents[$key])) { + $this->readEvents[$key]->stop(); unset($this->readEvents[$key]); } } /** - * remove a writable stream from the event loop - * @param stream $stream PHP stream resource - * @return void + * {@inheritdoc} */ public function removeWriteStream($stream) { $key = (int) $stream; - if(isset($this->writeEvents[$key])) { + if (isset($this->writeEvents[$key])) { $this->writeEvents[$key]->stop(); unset($this->writeEvents[$key]); } } /** - * remove a stream from the event loop - * @param stream $stream PHP stream - * @return void + * {@inheritdoc} */ public function removeStream($stream) { - if (isset($this->readEvents[(int)$stream])) { - $this->removeReadStream($stream); - } - - if (isset($this->writeEvents[(int)$stream])) { - $this->removeWriteStream($stream); - } + $this->removeReadStream($stream); + $this->removeWriteStream($stream); } /** * Wraps the listener in a callback which will pass the * stream to the listener then registers the stream with * the eventloop. - * - * @param stream $stream PHP Stream resource - * @param callable $listener stream callback - * @param bit $flags flag bitmask + * + * @param resource $stream PHP Stream resource + * @param callable $listener stream callback + * @param int $flags flag bitmask */ private function addStream($stream, callable $listener, $flags) { $listener = function ($event) use ($stream, $listener) { - call_user_func($listener, $stream); + call_user_func($listener, $stream, $this); }; $event = $this->loop->io($stream, $flags, $listener); @@ -151,13 +134,13 @@ public function cancelTimer(TimerInterface $timer) /* defer timer */ $this->nextTick(function() use ($timer) { - $this->timers->detach($timer); + $this->timers->detach($timer); }); } } /** - * Add timer object as + * Add timer object as * @param TimerInterface $timer [description] * @return [type] [description] */ @@ -180,6 +163,9 @@ private function setupTimer(TimerInterface $timer) return $timer; } + /** + * {@inheritdoc} + */ public function isTimerActive(TimerInterface $timer) { return $this->timers->contains($timer); @@ -202,7 +188,9 @@ public function futureTick(callable $listener) $this->futureTickQueue->add($listener); } - + /** + * {@inheritdoc} + */ public function tick() { $this->nextTickQueue->tick(); @@ -218,14 +206,21 @@ public function tick() $this->loop->run($flags); } + /** + * {@inheritdoc} + */ public function run() { $this->running = true; + while($this->running) { $this->tick(); } } + /** + * {@inheritdoc} + */ public function stop() { $this->running = false; @@ -234,15 +229,15 @@ public function stop() public function __destruct() { // mannually stop all watchers - foreach($this->timers as $timer) { - $this->timers[$timer]->stop(); + foreach ($this->timers as $timer) { + $this->timers[$timer]->stop(); } - foreach($this->readEvents as $event) { + foreach ($this->readEvents as $event) { $event->stop(); } - foreach($this->writeEvents as $event) { + foreach ($this->writeEvents as $event) { $event->stop(); } } From 5a643f2c40cabcf3df28a737e0b846340a1bf715 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Wed, 3 Sep 2014 13:35:11 -0700 Subject: [PATCH 10/18] add support for Ev extension (libev) --- src/ExtEvLoop.php | 228 +++++++++++++++++++++++++++++++++++++ tests/AbstractLoopTest.php | 19 ++++ tests/ExtEvLoopTest.php | 40 +++++++ 3 files changed, 287 insertions(+) create mode 100644 src/ExtEvLoop.php create mode 100644 tests/ExtEvLoopTest.php diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php new file mode 100644 index 00000000..f383c37a --- /dev/null +++ b/src/ExtEvLoop.php @@ -0,0 +1,228 @@ +loop = new \EvLoop(); + $this->timers = new SplObjectStorage(); + $this->nextTickQueue = new NextTickQueue($this); + $this->futureTickQueue = new FutureTickQueue($this); + $this->timers = new SplObjectStorage(); + } + + /** + * Add a readable stream to the event loop + * @param stream $stream PHP stream resource + * @param callable $listener Callback + * @return void + */ + public function addReadStream($stream, callable $listener) + { + $this->addStream($stream, $listener, \Ev::READ); + } + + /** + * Add a writable stream to the event loop + * @param stream $stream PHP stream resource + * @param callable $listener Callback + * @return void + */ + public function addWriteStream($stream, callable $listener) + { + $this->addStream($stream, $listener, \Ev::WRITE); + } + + /** + * Remove a readable stream from the event loop. + * @param stream $stream PHP stream resource + * @return void + */ + public function removeReadStream($stream) + { + $key = (int) $stream; + if(isset($this->readEvents[$key])) { + $this->readEvents[$key]->stop(); + unset($this->readEvents[$key]); + } + } + + /** + * remove a writable stream from the event loop + * @param stream $stream PHP stream resource + * @return void + */ + public function removeWriteStream($stream) + { + $key = (int) $stream; + if(isset($this->writeEvents[$key])) { + $this->writeEvents[(int)$stream]->stop(); + unset($this->writeEvents[(int)$stream]); + } + } + + /** + * remove a stream from the event loop + * @param stream $stream PHP stream + * @return void + */ + public function removeStream($stream) + { + if (isset($this->readEvents[(int)$stream])) { + $this->removeReadStream($stream); + } + + if (isset($this->writeEvents[(int)$stream])) { + $this->removeWriteStream($stream); + } + } + + /** + * Wraps the listener in a callback which will pass the + * stream to the listener then registers the stream with + * the eventloop. + * + * @param stream $stream PHP Stream resource + * @param callable $listener stream callback + * @param bit $flags flag bitmask + */ + private function addStream($stream, callable $listener, $flags) + { + $listener = function ($event) use ($stream, $listener) { + call_user_func($listener, $stream); + }; + + $event = $this->loop->io($stream, $flags, $listener); + + if (($flags & \Ev::READ) === $flags) { + $this->readEvents[(int)$stream] = $event; + } elseif (($flags & \Ev::WRITE) === $flags) { + $this->writeEvents[(int)$stream] = $event; + } + } + + /** + * {@inheritdoc} + */ + public function addTimer($interval, callable $callback) + { + $timer = new Timer($this, $interval, $callback, false); + $this->setupTimer($timer); + + return $timer; + } + + /** + * {@inheritdoc} + */ + public function addPeriodicTimer($interval, callable $callback) + { + $timer = new Timer($this, $interval, $callback, true); + $this->setupTimer($timer); + + return $timer; + } + + /** + * {@inheritdoc} + */ + public function cancelTimer(TimerInterface $timer) + { + if (isset($this->timers[$timer])) { + /* stop EvTimer */ + $this->timers[$timer]->stop(); + $this->timers->detach($timer); + } + } + + /** + * Add timer object as + * @param TimerInterface $timer [description] + * @return [type] [description] + */ + private function setupTimer(TimerInterface $timer) + { + $callback = function () use ($timer) { + call_user_func($timer->getCallback(), $timer); + + if (!$timer->isPeriodic()) { + $timer->cancel(); + } + }; + + $interval = $timer->getInterval(); + + $libevTimer = $this->loop->timer($interval, $interval, $callback); + + $this->timers->attach($timer, $libevTimer); + + return $timer; + } + + public function isTimerActive(TimerInterface $timer) + { + return $this->timers->contains($timer); + } + + + /** + * {@inheritdoc} + */ + public function nextTick(callable $listener) + { + $this->nextTickQueue->add($listener); + } + + /** + * {@inheritdoc} + */ + public function futureTick(callable $listener) + { + $this->futureTickQueue->add($listener); + } + + + public function tick() + { + $this->nextTickQueue->tick(); + $this->futureTickQueue->tick(); + + $flags = \Ev::RUN_ONCE; + if (!$this->running || !$this->nextTickQueue->isEmpty() || !$this->futureTickQueue->isEmpty()) { + $flags |= \Ev::RUN_NOWAIT; + } elseif (!$this->readEvents && !$this->writeEvents && !$this->timers->count()) { + $this->running = false; + return; + } + $this->loop->run($flags); + } + + public function run() + { + $this->running = true; + while($this->running) { + $this->tick(); + } + } + + public function stop() + { + $this->running = false; + } +} diff --git a/tests/AbstractLoopTest.php b/tests/AbstractLoopTest.php index b4095379..ffcb9ea2 100644 --- a/tests/AbstractLoopTest.php +++ b/tests/AbstractLoopTest.php @@ -355,6 +355,25 @@ function () { $this->loop->run(); } + public function testPeriodTimerExecutes() + { + $count = 0; + $this->loop->addPeriodicTimer( + 0.001, + function ($timer) use (&$count) { + echo 'tick'; + $count++; + if($count === 3) { + $timer->cancel(); + } + } + ); + + $this->expectOutputString('tickticktick'); + + $this->loop->run(); + } + public function testFutureTick() { $called = false; diff --git a/tests/ExtEvLoopTest.php b/tests/ExtEvLoopTest.php new file mode 100644 index 00000000..d05dbba3 --- /dev/null +++ b/tests/ExtEvLoopTest.php @@ -0,0 +1,40 @@ +markTestSkipped('ev tests skipped because pecl/ev is not installed.'); + } + + return new ExtEvLoop(); + } + + public function tearDown() + { + if (file_exists($this->file)) { + unlink($this->file); + } + } + + public function createStream() + { + $this->file = tempnam(sys_get_temp_dir(), 'react-'); + + $stream = fopen($this->file, 'r+'); + + return $stream; + } + + public function testEvConstructor() + { + $loop = new ExtEvLoop(); + } +} From 7edb3b8f3d26e220a0722701db69ebe9152791e1 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Wed, 3 Sep 2014 14:00:56 -0700 Subject: [PATCH 11/18] adding ev extension to travis --- travis-init.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/travis-init.sh b/travis-init.sh index 63deeb85..162e90ec 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -21,6 +21,17 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && popd echo "extension=libevent.so" >> "$(php -r 'echo php_ini_loaded_file();')" + # install 'pecl-ev' PHP extension + git clone http://bitbucket.org/osmanov/pecl-ev.git + # 0.2.10 + pushd pecl-ev + phpize + ./configure + make + make install + popd + echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" + # install 'libev' PHP extension git clone --recursive https://github.com/m4rw3r/php-libev pushd php-libev From 39aff0d992ae124ad08f4ab3c2cbe3299d47be8f Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Wed, 3 Sep 2014 17:39:07 -0700 Subject: [PATCH 12/18] Resolve segfaulting issues with pecl-ev --- .travis.yml | 5 ++++- script.gdb | 3 +++ src/ExtEvLoop.php | 29 +++++++++++++++++++++++++---- tests/AbstractLoopTest.php | 19 ------------------- travis-init.sh | 1 + 5 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 script.gdb diff --git a/.travis.yml b/.travis.yml index d5118a82..e3ffe967 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,10 @@ matrix: - php: hhvm-nightly fast_finish: true +before_script: + - sudo apt-get install gdb + install: ./travis-init.sh script: - - phpunit --coverage-text + - phpunit --coverage-text diff --git a/script.gdb b/script.gdb new file mode 100644 index 00000000..34e270dc --- /dev/null +++ b/script.gdb @@ -0,0 +1,3 @@ +set env MALLOC_CHECK_=3 +run +backtrace full \ No newline at end of file diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php index f383c37a..26235e54 100644 --- a/src/ExtEvLoop.php +++ b/src/ExtEvLoop.php @@ -16,6 +16,7 @@ class ExtEvLoop implements LoopInterface private $timers; private $readEvents = array(); private $writeEvents = array(); + private $running = false; public function __construct() @@ -58,7 +59,7 @@ public function removeReadStream($stream) { $key = (int) $stream; if(isset($this->readEvents[$key])) { - $this->readEvents[$key]->stop(); + $this->readEvents[$key]->stop(); unset($this->readEvents[$key]); } } @@ -72,8 +73,8 @@ public function removeWriteStream($stream) { $key = (int) $stream; if(isset($this->writeEvents[$key])) { - $this->writeEvents[(int)$stream]->stop(); - unset($this->writeEvents[(int)$stream]); + $this->writeEvents[$key]->stop(); + unset($this->writeEvents[$key]); } } @@ -147,7 +148,11 @@ public function cancelTimer(TimerInterface $timer) if (isset($this->timers[$timer])) { /* stop EvTimer */ $this->timers[$timer]->stop(); - $this->timers->detach($timer); + + /* defer timer */ + $this->nextTick(function() use ($timer) { + $this->timers->detach($timer); + }); } } @@ -225,4 +230,20 @@ public function stop() { $this->running = false; } + + public function __destruct() + { + // mannually stop all watchers + foreach($this->timers as $timer) { + $this->timers[$timer]->stop(); + } + + foreach($this->readEvents as $event) { + $event->stop(); + } + + foreach($this->writeEvents as $event) { + $event->stop(); + } + } } diff --git a/tests/AbstractLoopTest.php b/tests/AbstractLoopTest.php index ffcb9ea2..b4095379 100644 --- a/tests/AbstractLoopTest.php +++ b/tests/AbstractLoopTest.php @@ -355,25 +355,6 @@ function () { $this->loop->run(); } - public function testPeriodTimerExecutes() - { - $count = 0; - $this->loop->addPeriodicTimer( - 0.001, - function ($timer) use (&$count) { - echo 'tick'; - $count++; - if($count === 3) { - $timer->cancel(); - } - } - ); - - $this->expectOutputString('tickticktick'); - - $this->loop->run(); - } - public function testFutureTick() { $called = false; diff --git a/travis-init.sh b/travis-init.sh index 162e90ec..e5fa9c17 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -28,6 +28,7 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && phpize ./configure make + # make test make install popd echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" From b616955c15b2bfe34a34cc8dea5fa8001c1ba1ad Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Mon, 27 Oct 2014 14:09:07 -0700 Subject: [PATCH 13/18] removing gdb from travis --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3ffe967..957d25c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,6 @@ matrix: - php: hhvm-nightly fast_finish: true -before_script: - - sudo apt-get install gdb - install: ./travis-init.sh script: From a643c7ab75118d17854cb98efee34d659b49ac3b Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Tue, 4 Nov 2014 07:53:04 -0800 Subject: [PATCH 14/18] updates based on code review --- .travis.yml | 2 +- script.gdb | 3 -- src/ExtEvLoop.php | 75 ++++++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 44 deletions(-) delete mode 100644 script.gdb diff --git a/.travis.yml b/.travis.yml index 957d25c5..d5118a82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,4 +16,4 @@ matrix: install: ./travis-init.sh script: - - phpunit --coverage-text + - phpunit --coverage-text diff --git a/script.gdb b/script.gdb deleted file mode 100644 index 34e270dc..00000000 --- a/script.gdb +++ /dev/null @@ -1,3 +0,0 @@ -set env MALLOC_CHECK_=3 -run -backtrace full \ No newline at end of file diff --git a/src/ExtEvLoop.php b/src/ExtEvLoop.php index 26235e54..95f41880 100644 --- a/src/ExtEvLoop.php +++ b/src/ExtEvLoop.php @@ -12,7 +12,7 @@ class ExtEvLoop implements LoopInterface { private $loop; private $nextTickQueue; - private $futureTickQueue; + private $futureTickQueue; private $timers; private $readEvents = array(); private $writeEvents = array(); @@ -29,10 +29,7 @@ public function __construct() } /** - * Add a readable stream to the event loop - * @param stream $stream PHP stream resource - * @param callable $listener Callback - * @return void + * {@inheritdoc} */ public function addReadStream($stream, callable $listener) { @@ -40,10 +37,7 @@ public function addReadStream($stream, callable $listener) } /** - * Add a writable stream to the event loop - * @param stream $stream PHP stream resource - * @param callable $listener Callback - * @return void + * {@inheritdoc} */ public function addWriteStream($stream, callable $listener) { @@ -51,62 +45,51 @@ public function addWriteStream($stream, callable $listener) } /** - * Remove a readable stream from the event loop. - * @param stream $stream PHP stream resource - * @return void + * {@inheritdoc} */ public function removeReadStream($stream) { $key = (int) $stream; - if(isset($this->readEvents[$key])) { - $this->readEvents[$key]->stop(); + if (isset($this->readEvents[$key])) { + $this->readEvents[$key]->stop(); unset($this->readEvents[$key]); } } /** - * remove a writable stream from the event loop - * @param stream $stream PHP stream resource - * @return void + * {@inheritdoc} */ public function removeWriteStream($stream) { $key = (int) $stream; - if(isset($this->writeEvents[$key])) { + if (isset($this->writeEvents[$key])) { $this->writeEvents[$key]->stop(); unset($this->writeEvents[$key]); } } /** - * remove a stream from the event loop - * @param stream $stream PHP stream - * @return void + * {@inheritdoc} */ public function removeStream($stream) { - if (isset($this->readEvents[(int)$stream])) { - $this->removeReadStream($stream); - } - - if (isset($this->writeEvents[(int)$stream])) { - $this->removeWriteStream($stream); - } + $this->removeReadStream($stream); + $this->removeWriteStream($stream); } /** * Wraps the listener in a callback which will pass the * stream to the listener then registers the stream with * the eventloop. - * - * @param stream $stream PHP Stream resource - * @param callable $listener stream callback - * @param bit $flags flag bitmask + * + * @param resource $stream PHP Stream resource + * @param callable $listener stream callback + * @param int $flags flag bitmask */ private function addStream($stream, callable $listener, $flags) { $listener = function ($event) use ($stream, $listener) { - call_user_func($listener, $stream); + call_user_func($listener, $stream, $this); }; $event = $this->loop->io($stream, $flags, $listener); @@ -151,13 +134,13 @@ public function cancelTimer(TimerInterface $timer) /* defer timer */ $this->nextTick(function() use ($timer) { - $this->timers->detach($timer); + $this->timers->detach($timer); }); } } /** - * Add timer object as + * Add timer object as * @param TimerInterface $timer [description] * @return [type] [description] */ @@ -180,6 +163,9 @@ private function setupTimer(TimerInterface $timer) return $timer; } + /** + * {@inheritdoc} + */ public function isTimerActive(TimerInterface $timer) { return $this->timers->contains($timer); @@ -202,7 +188,9 @@ public function futureTick(callable $listener) $this->futureTickQueue->add($listener); } - + /** + * {@inheritdoc} + */ public function tick() { $this->nextTickQueue->tick(); @@ -218,14 +206,21 @@ public function tick() $this->loop->run($flags); } + /** + * {@inheritdoc} + */ public function run() { $this->running = true; + while($this->running) { $this->tick(); } } + /** + * {@inheritdoc} + */ public function stop() { $this->running = false; @@ -234,15 +229,15 @@ public function stop() public function __destruct() { // mannually stop all watchers - foreach($this->timers as $timer) { - $this->timers[$timer]->stop(); + foreach ($this->timers as $timer) { + $this->timers[$timer]->stop(); } - foreach($this->readEvents as $event) { + foreach ($this->readEvents as $event) { $event->stop(); } - foreach($this->writeEvents as $event) { + foreach ($this->writeEvents as $event) { $event->stop(); } } From f01422d7b5eaae2451014ea8a6d3bd635b987d46 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Mon, 10 Nov 2014 11:39:26 -0800 Subject: [PATCH 15/18] now that segfault fix has been moved to pecl, use the ev pecl package --- travis-init.sh | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/travis-init.sh b/travis-init.sh index e5fa9c17..e2e06a91 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -11,6 +11,9 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && # install 'event' PHP extension echo "yes" | pecl install event + # install 'ev' PHP extension + echo "yes" | pecl install ev + # install 'libevent' PHP extension curl http://pecl.php.net/get/libevent-0.1.0.tgz | tar -xz pushd libevent-0.1.0 @@ -21,18 +24,6 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && popd echo "extension=libevent.so" >> "$(php -r 'echo php_ini_loaded_file();')" - # install 'pecl-ev' PHP extension - git clone http://bitbucket.org/osmanov/pecl-ev.git - # 0.2.10 - pushd pecl-ev - phpize - ./configure - make - # make test - make install - popd - echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" - # install 'libev' PHP extension git clone --recursive https://github.com/m4rw3r/php-libev pushd php-libev From f8309dae070e1fa730b52864642f1a3b7beddcd0 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Mon, 10 Nov 2014 11:41:10 -0800 Subject: [PATCH 16/18] now that segfault fix has been moved to pecl, use the ev pecl package --- travis-init.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/travis-init.sh b/travis-init.sh index 8069e36c..e2e06a91 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -24,18 +24,6 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && popd echo "extension=libevent.so" >> "$(php -r 'echo php_ini_loaded_file();')" - # install 'pecl-ev' PHP extension - git clone http://bitbucket.org/osmanov/pecl-ev.git - # 0.2.10 - pushd pecl-ev - phpize - ./configure - make - # make test - make install - popd - echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" - # install 'libev' PHP extension git clone --recursive https://github.com/m4rw3r/php-libev pushd php-libev From 525d1cf644af5fb6ea84549c1535470d4e751aee Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Mon, 10 Nov 2014 12:16:27 -0800 Subject: [PATCH 17/18] try to install pecl ev with sudo --- travis-init.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/travis-init.sh b/travis-init.sh index e2e06a91..6f2c8dad 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -12,7 +12,7 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && echo "yes" | pecl install event # install 'ev' PHP extension - echo "yes" | pecl install ev + echo "yes" | sudo pecl install ev # install 'libevent' PHP extension curl http://pecl.php.net/get/libevent-0.1.0.tgz | tar -xz @@ -24,6 +24,18 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && popd echo "extension=libevent.so" >> "$(php -r 'echo php_ini_loaded_file();')" + # install 'pecl-ev' PHP extension + git clone http://bitbucket.org/osmanov/pecl-ev.git + # 0.2.10 + pushd pecl-ev + phpize + ./configure + make + # make test + make install + popd + echo "extension=ev.so" >> "$(php -r 'echo php_ini_loaded_file();')" + # install 'libev' PHP extension git clone --recursive https://github.com/m4rw3r/php-libev pushd php-libev From 9edc3f2fd07bf889fcdbf5bbef4c891b791a035f Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Mon, 10 Nov 2014 12:29:10 -0800 Subject: [PATCH 18/18] reverting back to clone, as pecl install ev is failing --- travis-init.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/travis-init.sh b/travis-init.sh index 6f2c8dad..6aca97b5 100755 --- a/travis-init.sh +++ b/travis-init.sh @@ -11,9 +11,6 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && # install 'event' PHP extension echo "yes" | pecl install event - # install 'ev' PHP extension - echo "yes" | sudo pecl install ev - # install 'libevent' PHP extension curl http://pecl.php.net/get/libevent-0.1.0.tgz | tar -xz pushd libevent-0.1.0 @@ -26,7 +23,7 @@ if [[ "$TRAVIS_PHP_VERSION" != "hhvm" && # install 'pecl-ev' PHP extension git clone http://bitbucket.org/osmanov/pecl-ev.git - # 0.2.10 + # 0.2.12 pushd pecl-ev phpize ./configure pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy