|
|
@@ -0,0 +1,262 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ * This file is part of workerman.
|
|
|
+ *
|
|
|
+ * Licensed under The MIT License
|
|
|
+ * For full copyright and license information, please see the MIT-LICENSE.txt
|
|
|
+ * Redistributions of files must retain the above copyright notice.
|
|
|
+ *
|
|
|
+ * @author walkor<walkor@workerman.net>
|
|
|
+ * @copyright walkor<walkor@workerman.net>
|
|
|
+ * @link http://www.workerman.net/
|
|
|
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
|
|
|
+ */
|
|
|
+namespace Workerman\Events\React;
|
|
|
+use Workerman\Events\EventInterface;
|
|
|
+use React\EventLoop\TimerInterface;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Class StreamSelectLoop
|
|
|
+ * @package Workerman\Events\React
|
|
|
+ */
|
|
|
+class Base implements \React\EventLoop\LoopInterface
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $_timerIdMap = array();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @var int
|
|
|
+ */
|
|
|
+ protected $_timerIdIndex = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $_signalHandlerMap = array();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @var \React\EventLoop\LoopInterface
|
|
|
+ */
|
|
|
+ protected $_eventLoop = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Base constructor.
|
|
|
+ */
|
|
|
+ public function __construct()
|
|
|
+ {
|
|
|
+ $this->_eventLoop = new \React\EventLoop\StreamSelectLoop();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Add event listener to event loop.
|
|
|
+ *
|
|
|
+ * @param $fd
|
|
|
+ * @param $flag
|
|
|
+ * @param $func
|
|
|
+ * @param array $args
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function add($fd, $flag, $func, $args = array())
|
|
|
+ {
|
|
|
+ $args = (array)$args;
|
|
|
+ switch ($flag) {
|
|
|
+ case EventInterface::EV_READ:
|
|
|
+ return $this->addReadStream($fd, $func);
|
|
|
+ case EventInterface::EV_WRITE:
|
|
|
+ return $this->addWriteStream($fd, $func);
|
|
|
+ case EventInterface::EV_SIGNAL:
|
|
|
+ if (isset($this->_signalHandlerMap[$fd])) {
|
|
|
+ $this->removeSignal($fd, $this->_signalHandlerMap[$fd]);
|
|
|
+ }
|
|
|
+ $this->_signalHandlerMap[$fd] = $func;
|
|
|
+ return $this->addSignal($fd, $func);
|
|
|
+ case EventInterface::EV_TIMER:
|
|
|
+ $timer_obj = $this->addPeriodicTimer($fd, function() use ($func, $args) {
|
|
|
+ call_user_func_array($func, $args);
|
|
|
+ });
|
|
|
+ $this->_timerIdMap[++$this->_timerIdIndex] = $timer_obj;
|
|
|
+ return $this->_timerIdIndex;
|
|
|
+ case EventInterface::EV_TIMER_ONCE:
|
|
|
+ $index = ++$this->_timerIdIndex;
|
|
|
+ $timer_obj = $this->addTimer($fd, function() use ($func, $args, $index) {
|
|
|
+ $this->del($index,EventInterface::EV_TIMER_ONCE);
|
|
|
+ call_user_func_array($func, $args);
|
|
|
+ });
|
|
|
+ $this->_timerIdMap[$index] = $timer_obj;
|
|
|
+ return $this->_timerIdIndex;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Remove event listener from event loop.
|
|
|
+ *
|
|
|
+ * @param mixed $fd
|
|
|
+ * @param int $flag
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function del($fd, $flag)
|
|
|
+ {
|
|
|
+ switch ($flag) {
|
|
|
+ case EventInterface::EV_READ:
|
|
|
+ return $this->removeReadStream($fd);
|
|
|
+ case EventInterface::EV_WRITE:
|
|
|
+ return $this->removeWriteStream($fd);
|
|
|
+ case EventInterface::EV_SIGNAL:
|
|
|
+ if (!isset($this->_eventLoop[$fd])) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $func = $this->_eventLoop[$fd];
|
|
|
+ unset($this->_eventLoop[$fd]);
|
|
|
+ return $this->removeSignal($fd, $func);
|
|
|
+
|
|
|
+ case EventInterface::EV_TIMER:
|
|
|
+ case EventInterface::EV_TIMER_ONCE:
|
|
|
+ if (isset($this->_timerIdMap[$fd])){
|
|
|
+ $timer_obj = $this->_timerIdMap[$fd];
|
|
|
+ unset($this->_timerIdMap[$fd]);
|
|
|
+ $this->cancelTimer($timer_obj);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Main loop.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function loop()
|
|
|
+ {
|
|
|
+ $this->run();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Destroy loop.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function destroy()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get timer count.
|
|
|
+ *
|
|
|
+ * @return integer
|
|
|
+ */
|
|
|
+ public function getTimerCount()
|
|
|
+ {
|
|
|
+ return count($this->_timerIdMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param resource $stream
|
|
|
+ * @param callable $listener
|
|
|
+ */
|
|
|
+ public function addReadStream($stream, $listener)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->addReadStream($stream, $listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param resource $stream
|
|
|
+ * @param callable $listener
|
|
|
+ */
|
|
|
+ public function addWriteStream($stream, $listener)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->addWriteStream($stream, $listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param resource $stream
|
|
|
+ */
|
|
|
+ public function removeReadStream($stream)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->removeReadStream($stream);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param resource $stream
|
|
|
+ */
|
|
|
+ public function removeWriteStream($stream)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->removeWriteStream($stream);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param float|int $interval
|
|
|
+ * @param callable $callback
|
|
|
+ * @return \React\EventLoop\Timer\Timer|TimerInterface
|
|
|
+ */
|
|
|
+ public function addTimer($interval, $callback)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->addTimer($interval, $callback);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param float|int $interval
|
|
|
+ * @param callable $callback
|
|
|
+ * @return \React\EventLoop\Timer\Timer|TimerInterface
|
|
|
+ */
|
|
|
+ public function addPeriodicTimer($interval, $callback)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->addPeriodicTimer($interval, $callback);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param TimerInterface $timer
|
|
|
+ */
|
|
|
+ public function cancelTimer(TimerInterface $timer)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->cancelTimer($timer);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param callable $listener
|
|
|
+ */
|
|
|
+ public function futureTick($listener)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->futureTick($listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param int $signal
|
|
|
+ * @param callable $listener
|
|
|
+ */
|
|
|
+ public function addSignal($signal, $listener)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->addSignal($signal, $listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param int $signal
|
|
|
+ * @param callable $listener
|
|
|
+ */
|
|
|
+ public function removeSignal($signal, $listener)
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->removeSignal($signal, $listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Run.
|
|
|
+ */
|
|
|
+ public function run()
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->run();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Stop.
|
|
|
+ */
|
|
|
+ public function stop()
|
|
|
+ {
|
|
|
+ return $this->_eventLoop->stop();
|
|
|
+ }
|
|
|
+}
|