init
- 框架初始化 - 安装插件 - 修复PHP8.4报错
This commit is contained in:
189
vendor/workerman/workerman/Events/Ev.php
vendored
Normal file
189
vendor/workerman/workerman/Events/Ev.php
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<?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 有个鬼<42765633@qq.com>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Workerman\Events;
|
||||
|
||||
use Workerman\Worker;
|
||||
use \EvWatcher;
|
||||
|
||||
/**
|
||||
* ev eventloop
|
||||
*/
|
||||
class Ev implements EventInterface
|
||||
{
|
||||
/**
|
||||
* All listeners for read/write event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_allEvents = array();
|
||||
|
||||
/**
|
||||
* Event listeners of signal.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventSignal = array();
|
||||
|
||||
/**
|
||||
* All timer event listeners.
|
||||
* [func, args, event, flag, time_interval]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventTimer = array();
|
||||
|
||||
/**
|
||||
* Timer id.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $_timerId = 1;
|
||||
|
||||
/**
|
||||
* Add a timer.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args = null)
|
||||
{
|
||||
$callback = function ($event, $socket) use ($fd, $func) {
|
||||
try {
|
||||
\call_user_func($func, $fd);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
};
|
||||
switch ($flag) {
|
||||
case self::EV_SIGNAL:
|
||||
$event = new \EvSignal($fd, $callback);
|
||||
$this->_eventSignal[$fd] = $event;
|
||||
return true;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
$repeat = $flag === self::EV_TIMER_ONCE ? 0 : $fd;
|
||||
$param = array($func, (array)$args, $flag, $fd, self::$_timerId);
|
||||
$event = new \EvTimer($fd, $repeat, array($this, 'timerCallback'), $param);
|
||||
$this->_eventTimer[self::$_timerId] = $event;
|
||||
return self::$_timerId++;
|
||||
default :
|
||||
$fd_key = (int)$fd;
|
||||
$real_flag = $flag === self::EV_READ ? \Ev::READ : \Ev::WRITE;
|
||||
$event = new \EvIo($fd, $real_flag, $callback);
|
||||
$this->_allEvents[$fd_key][$flag] = $event;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a timer.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function del($fd, $flag)
|
||||
{
|
||||
switch ($flag) {
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_allEvents[$fd_key][$flag])) {
|
||||
$this->_allEvents[$fd_key][$flag]->stop();
|
||||
unset($this->_allEvents[$fd_key][$flag]);
|
||||
}
|
||||
if (empty($this->_allEvents[$fd_key])) {
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
break;
|
||||
case self::EV_SIGNAL:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_eventSignal[$fd_key])) {
|
||||
$this->_eventSignal[$fd_key]->stop();
|
||||
unset($this->_eventSignal[$fd_key]);
|
||||
}
|
||||
break;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
if (isset($this->_eventTimer[$fd])) {
|
||||
$this->_eventTimer[$fd]->stop();
|
||||
unset($this->_eventTimer[$fd]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer callback.
|
||||
*
|
||||
* @param EvWatcher $event
|
||||
*/
|
||||
public function timerCallback(EvWatcher $event)
|
||||
{
|
||||
$param = $event->data;
|
||||
$timer_id = $param[4];
|
||||
if ($param[2] === self::EV_TIMER_ONCE) {
|
||||
$this->_eventTimer[$timer_id]->stop();
|
||||
unset($this->_eventTimer[$timer_id]);
|
||||
}
|
||||
try {
|
||||
\call_user_func_array($param[0], $param[1]);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all timers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearAllTimer()
|
||||
{
|
||||
foreach ($this->_eventTimer as $event) {
|
||||
$event->stop();
|
||||
}
|
||||
$this->_eventTimer = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main loop.
|
||||
*
|
||||
* @see EventInterface::loop()
|
||||
*/
|
||||
public function loop()
|
||||
{
|
||||
\Ev::run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy loop.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
\Ev::stop(\Ev::BREAK_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timer count.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimerCount()
|
||||
{
|
||||
return \count($this->_eventTimer);
|
||||
}
|
||||
}
|
||||
215
vendor/workerman/workerman/Events/Event.php
vendored
Normal file
215
vendor/workerman/workerman/Events/Event.php
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
<?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 有个鬼<42765633@qq.com>
|
||||
* @copyright 有个鬼<42765633@qq.com>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Workerman\Events;
|
||||
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* libevent eventloop
|
||||
*/
|
||||
class Event implements EventInterface
|
||||
{
|
||||
/**
|
||||
* Event base.
|
||||
* @var object
|
||||
*/
|
||||
protected $_eventBase = null;
|
||||
|
||||
/**
|
||||
* All listeners for read/write event.
|
||||
* @var array
|
||||
*/
|
||||
protected $_allEvents = array();
|
||||
|
||||
/**
|
||||
* Event listeners of signal.
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventSignal = array();
|
||||
|
||||
/**
|
||||
* All timer event listeners.
|
||||
* [func, args, event, flag, time_interval]
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventTimer = array();
|
||||
|
||||
/**
|
||||
* Timer id.
|
||||
* @var int
|
||||
*/
|
||||
protected static $_timerId = 1;
|
||||
|
||||
/**
|
||||
* construct
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (\class_exists('\\\\EventBase', false)) {
|
||||
$class_name = '\\\\EventBase';
|
||||
} else {
|
||||
$class_name = '\EventBase';
|
||||
}
|
||||
$this->_eventBase = new $class_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EventInterface::add()
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args=array())
|
||||
{
|
||||
if (\class_exists('\\\\Event', false)) {
|
||||
$class_name = '\\\\Event';
|
||||
} else {
|
||||
$class_name = '\Event';
|
||||
}
|
||||
switch ($flag) {
|
||||
case self::EV_SIGNAL:
|
||||
|
||||
$fd_key = (int)$fd;
|
||||
$event = $class_name::signal($this->_eventBase, $fd, $func);
|
||||
if (!$event||!$event->add()) {
|
||||
return false;
|
||||
}
|
||||
$this->_eventSignal[$fd_key] = $event;
|
||||
return true;
|
||||
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
|
||||
$param = array($func, (array)$args, $flag, $fd, self::$_timerId);
|
||||
$event = new $class_name($this->_eventBase, -1, $class_name::TIMEOUT|$class_name::PERSIST, array($this, "timerCallback"), $param);
|
||||
if (!$event||!$event->addTimer($fd)) {
|
||||
return false;
|
||||
}
|
||||
$this->_eventTimer[self::$_timerId] = $event;
|
||||
return self::$_timerId++;
|
||||
|
||||
default :
|
||||
$fd_key = (int)$fd;
|
||||
$real_flag = $flag === self::EV_READ ? $class_name::READ | $class_name::PERSIST : $class_name::WRITE | $class_name::PERSIST;
|
||||
$event = new $class_name($this->_eventBase, $fd, $real_flag, $func, $fd);
|
||||
if (!$event||!$event->add()) {
|
||||
return false;
|
||||
}
|
||||
$this->_allEvents[$fd_key][$flag] = $event;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Events\EventInterface::del()
|
||||
*/
|
||||
public function del($fd, $flag)
|
||||
{
|
||||
switch ($flag) {
|
||||
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_allEvents[$fd_key][$flag])) {
|
||||
$this->_allEvents[$fd_key][$flag]->del();
|
||||
unset($this->_allEvents[$fd_key][$flag]);
|
||||
}
|
||||
if (empty($this->_allEvents[$fd_key])) {
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
break;
|
||||
|
||||
case self::EV_SIGNAL:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_eventSignal[$fd_key])) {
|
||||
$this->_eventSignal[$fd_key]->del();
|
||||
unset($this->_eventSignal[$fd_key]);
|
||||
}
|
||||
break;
|
||||
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
if (isset($this->_eventTimer[$fd])) {
|
||||
$this->_eventTimer[$fd]->del();
|
||||
unset($this->_eventTimer[$fd]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer callback.
|
||||
* @param int|null $fd
|
||||
* @param int $what
|
||||
* @param int $timer_id
|
||||
*/
|
||||
public function timerCallback($fd, $what, $param)
|
||||
{
|
||||
$timer_id = $param[4];
|
||||
|
||||
if ($param[2] === self::EV_TIMER_ONCE) {
|
||||
$this->_eventTimer[$timer_id]->del();
|
||||
unset($this->_eventTimer[$timer_id]);
|
||||
}
|
||||
|
||||
try {
|
||||
\call_user_func_array($param[0], $param[1]);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Events\EventInterface::clearAllTimer()
|
||||
* @return void
|
||||
*/
|
||||
public function clearAllTimer()
|
||||
{
|
||||
foreach ($this->_eventTimer as $event) {
|
||||
$event->del();
|
||||
}
|
||||
$this->_eventTimer = array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see EventInterface::loop()
|
||||
*/
|
||||
public function loop()
|
||||
{
|
||||
$this->_eventBase->loop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy loop.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
$this->_eventBase->exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timer count.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimerCount()
|
||||
{
|
||||
return \count($this->_eventTimer);
|
||||
}
|
||||
}
|
||||
107
vendor/workerman/workerman/Events/EventInterface.php
vendored
Normal file
107
vendor/workerman/workerman/Events/EventInterface.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?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;
|
||||
|
||||
interface EventInterface
|
||||
{
|
||||
/**
|
||||
* Read event.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EV_READ = 1;
|
||||
|
||||
/**
|
||||
* Write event.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EV_WRITE = 2;
|
||||
|
||||
/**
|
||||
* Except event
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EV_EXCEPT = 3;
|
||||
|
||||
/**
|
||||
* Signal event.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EV_SIGNAL = 4;
|
||||
|
||||
/**
|
||||
* Timer event.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EV_TIMER = 8;
|
||||
|
||||
/**
|
||||
* Timer once event.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EV_TIMER_ONCE = 16;
|
||||
|
||||
/**
|
||||
* Add event listener to event loop.
|
||||
*
|
||||
* @param mixed $fd
|
||||
* @param int $flag
|
||||
* @param callable $func
|
||||
* @param array $args
|
||||
* @return bool
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args = array());
|
||||
|
||||
/**
|
||||
* Remove event listener from event loop.
|
||||
*
|
||||
* @param mixed $fd
|
||||
* @param int $flag
|
||||
* @return bool
|
||||
*/
|
||||
public function del($fd, $flag);
|
||||
|
||||
/**
|
||||
* Remove all timers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearAllTimer();
|
||||
|
||||
/**
|
||||
* Main loop.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loop();
|
||||
|
||||
/**
|
||||
* Destroy loop.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy();
|
||||
|
||||
/**
|
||||
* Get Timer count.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTimerCount();
|
||||
}
|
||||
225
vendor/workerman/workerman/Events/Libevent.php
vendored
Normal file
225
vendor/workerman/workerman/Events/Libevent.php
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
<?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;
|
||||
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* libevent eventloop
|
||||
*/
|
||||
class Libevent implements EventInterface
|
||||
{
|
||||
/**
|
||||
* Event base.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $_eventBase = null;
|
||||
|
||||
/**
|
||||
* All listeners for read/write event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_allEvents = array();
|
||||
|
||||
/**
|
||||
* Event listeners of signal.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventSignal = array();
|
||||
|
||||
/**
|
||||
* All timer event listeners.
|
||||
* [func, args, event, flag, time_interval]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventTimer = array();
|
||||
|
||||
/**
|
||||
* construct
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_eventBase = \event_base_new();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args = array())
|
||||
{
|
||||
switch ($flag) {
|
||||
case self::EV_SIGNAL:
|
||||
$fd_key = (int)$fd;
|
||||
$real_flag = \EV_SIGNAL | \EV_PERSIST;
|
||||
$this->_eventSignal[$fd_key] = \event_new();
|
||||
if (!\event_set($this->_eventSignal[$fd_key], $fd, $real_flag, $func, null)) {
|
||||
return false;
|
||||
}
|
||||
if (!\event_base_set($this->_eventSignal[$fd_key], $this->_eventBase)) {
|
||||
return false;
|
||||
}
|
||||
if (!\event_add($this->_eventSignal[$fd_key])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
$event = \event_new();
|
||||
$timer_id = (int)$event;
|
||||
if (!\event_set($event, 0, \EV_TIMEOUT, array($this, 'timerCallback'), $timer_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\event_base_set($event, $this->_eventBase)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$time_interval = $fd * 1000000;
|
||||
if (!\event_add($event, $time_interval)) {
|
||||
return false;
|
||||
}
|
||||
$this->_eventTimer[$timer_id] = array($func, (array)$args, $event, $flag, $time_interval);
|
||||
return $timer_id;
|
||||
|
||||
default :
|
||||
$fd_key = (int)$fd;
|
||||
$real_flag = $flag === self::EV_READ ? \EV_READ | \EV_PERSIST : \EV_WRITE | \EV_PERSIST;
|
||||
|
||||
$event = \event_new();
|
||||
|
||||
if (!\event_set($event, $fd, $real_flag, $func, null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\event_base_set($event, $this->_eventBase)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\event_add($event)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_allEvents[$fd_key][$flag] = $event;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function del($fd, $flag)
|
||||
{
|
||||
switch ($flag) {
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_allEvents[$fd_key][$flag])) {
|
||||
\event_del($this->_allEvents[$fd_key][$flag]);
|
||||
unset($this->_allEvents[$fd_key][$flag]);
|
||||
}
|
||||
if (empty($this->_allEvents[$fd_key])) {
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
break;
|
||||
case self::EV_SIGNAL:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_eventSignal[$fd_key])) {
|
||||
\event_del($this->_eventSignal[$fd_key]);
|
||||
unset($this->_eventSignal[$fd_key]);
|
||||
}
|
||||
break;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
// 这里 fd 为timerid
|
||||
if (isset($this->_eventTimer[$fd])) {
|
||||
\event_del($this->_eventTimer[$fd][2]);
|
||||
unset($this->_eventTimer[$fd]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer callback.
|
||||
*
|
||||
* @param mixed $_null1
|
||||
* @param int $_null2
|
||||
* @param mixed $timer_id
|
||||
*/
|
||||
protected function timerCallback($_null1, $_null2, $timer_id)
|
||||
{
|
||||
if ($this->_eventTimer[$timer_id][3] === self::EV_TIMER) {
|
||||
\event_add($this->_eventTimer[$timer_id][2], $this->_eventTimer[$timer_id][4]);
|
||||
}
|
||||
try {
|
||||
\call_user_func_array($this->_eventTimer[$timer_id][0], $this->_eventTimer[$timer_id][1]);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
if (isset($this->_eventTimer[$timer_id]) && $this->_eventTimer[$timer_id][3] === self::EV_TIMER_ONCE) {
|
||||
$this->del($timer_id, self::EV_TIMER_ONCE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clearAllTimer()
|
||||
{
|
||||
foreach ($this->_eventTimer as $task_data) {
|
||||
\event_del($task_data[2]);
|
||||
}
|
||||
$this->_eventTimer = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loop()
|
||||
{
|
||||
\event_base_loop($this->_eventBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy loop.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
foreach ($this->_eventSignal as $event) {
|
||||
\event_del($event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timer count.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimerCount()
|
||||
{
|
||||
return \count($this->_eventTimer);
|
||||
}
|
||||
}
|
||||
|
||||
264
vendor/workerman/workerman/Events/React/Base.php
vendored
Normal file
264
vendor/workerman/workerman/Events/React/Base.php
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
<?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;
|
||||
use React\EventLoop\LoopInterface;
|
||||
|
||||
/**
|
||||
* Class StreamSelectLoop
|
||||
* @package Workerman\Events\React
|
||||
*/
|
||||
class Base implements LoopInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_timerIdMap = array();
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_timerIdIndex = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_signalHandlerMap = array();
|
||||
|
||||
/**
|
||||
* @var LoopInterface
|
||||
*/
|
||||
protected $_eventLoop = null;
|
||||
|
||||
/**
|
||||
* Base constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_eventLoop = new \React\EventLoop\StreamSelectLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add event listener to event loop.
|
||||
*
|
||||
* @param int $fd
|
||||
* @param int $flag
|
||||
* @param callable $func
|
||||
* @param array $args
|
||||
* @return bool
|
||||
*/
|
||||
public function add($fd, $flag, $func, ?array $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();
|
||||
}
|
||||
}
|
||||
27
vendor/workerman/workerman/Events/React/ExtEventLoop.php
vendored
Normal file
27
vendor/workerman/workerman/Events/React/ExtEventLoop.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Class ExtEventLoop
|
||||
* @package Workerman\Events\React
|
||||
*/
|
||||
class ExtEventLoop extends Base
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->_eventLoop = new \React\EventLoop\ExtEventLoop();
|
||||
}
|
||||
}
|
||||
27
vendor/workerman/workerman/Events/React/ExtLibEventLoop.php
vendored
Normal file
27
vendor/workerman/workerman/Events/React/ExtLibEventLoop.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Class ExtLibEventLoop
|
||||
* @package Workerman\Events\React
|
||||
*/
|
||||
class ExtLibEventLoop extends Base
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->_eventLoop = new \React\EventLoop\ExtLibeventLoop();
|
||||
}
|
||||
}
|
||||
26
vendor/workerman/workerman/Events/React/StreamSelectLoop.php
vendored
Normal file
26
vendor/workerman/workerman/Events/React/StreamSelectLoop.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Class StreamSelectLoop
|
||||
* @package Workerman\Events\React
|
||||
*/
|
||||
class StreamSelectLoop extends Base
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->_eventLoop = new \React\EventLoop\StreamSelectLoop();
|
||||
}
|
||||
}
|
||||
357
vendor/workerman/workerman/Events/Select.php
vendored
Normal file
357
vendor/workerman/workerman/Events/Select.php
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
<?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;
|
||||
|
||||
use Throwable;
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* select eventloop
|
||||
*/
|
||||
class Select implements EventInterface
|
||||
{
|
||||
/**
|
||||
* All listeners for read/write event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_allEvents = array();
|
||||
|
||||
/**
|
||||
* Event listeners of signal.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_signalEvents = array();
|
||||
|
||||
/**
|
||||
* Fds waiting for read event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_readFds = array();
|
||||
|
||||
/**
|
||||
* Fds waiting for write event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_writeFds = array();
|
||||
|
||||
/**
|
||||
* Fds waiting for except event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_exceptFds = array();
|
||||
|
||||
/**
|
||||
* Timer scheduler.
|
||||
* {['data':timer_id, 'priority':run_timestamp], ..}
|
||||
*
|
||||
* @var \SplPriorityQueue
|
||||
*/
|
||||
protected $_scheduler = null;
|
||||
|
||||
/**
|
||||
* All timer event listeners.
|
||||
* [[func, args, flag, timer_interval], ..]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventTimer = array();
|
||||
|
||||
/**
|
||||
* Timer id.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_timerId = 1;
|
||||
|
||||
/**
|
||||
* Select timeout.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_selectTimeout = 100000000;
|
||||
|
||||
/**
|
||||
* Paired socket channels
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $channel = array();
|
||||
|
||||
/**
|
||||
* Construct.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Init SplPriorityQueue.
|
||||
$this->_scheduler = new \SplPriorityQueue();
|
||||
$this->_scheduler->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args = array())
|
||||
{
|
||||
switch ($flag) {
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$count = $flag === self::EV_READ ? \count($this->_readFds) : \count($this->_writeFds);
|
||||
if ($count >= 1024) {
|
||||
echo "Warning: system call select exceeded the maximum number of connections 1024, please install event/libevent extension for more connections.\n";
|
||||
} else if (\DIRECTORY_SEPARATOR !== '/' && $count >= 256) {
|
||||
echo "Warning: system call select exceeded the maximum number of connections 256.\n";
|
||||
}
|
||||
$fd_key = (int)$fd;
|
||||
$this->_allEvents[$fd_key][$flag] = array($func, $fd);
|
||||
if ($flag === self::EV_READ) {
|
||||
$this->_readFds[$fd_key] = $fd;
|
||||
} else {
|
||||
$this->_writeFds[$fd_key] = $fd;
|
||||
}
|
||||
break;
|
||||
case self::EV_EXCEPT:
|
||||
$fd_key = (int)$fd;
|
||||
$this->_allEvents[$fd_key][$flag] = array($func, $fd);
|
||||
$this->_exceptFds[$fd_key] = $fd;
|
||||
break;
|
||||
case self::EV_SIGNAL:
|
||||
// Windows not support signal.
|
||||
if(\DIRECTORY_SEPARATOR !== '/') {
|
||||
return false;
|
||||
}
|
||||
$fd_key = (int)$fd;
|
||||
$this->_signalEvents[$fd_key][$flag] = array($func, $fd);
|
||||
\pcntl_signal($fd, array($this, 'signalHandler'));
|
||||
break;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
$timer_id = $this->_timerId++;
|
||||
$run_time = \microtime(true) + $fd;
|
||||
$this->_scheduler->insert($timer_id, -$run_time);
|
||||
$this->_eventTimer[$timer_id] = array($func, (array)$args, $flag, $fd);
|
||||
$select_timeout = ($run_time - \microtime(true)) * 1000000;
|
||||
$select_timeout = $select_timeout <= 0 ? 1 : $select_timeout;
|
||||
if( $this->_selectTimeout > $select_timeout ){
|
||||
$this->_selectTimeout = (int) $select_timeout;
|
||||
}
|
||||
return $timer_id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal handler.
|
||||
*
|
||||
* @param int $signal
|
||||
*/
|
||||
public function signalHandler($signal)
|
||||
{
|
||||
\call_user_func_array($this->_signalEvents[$signal][self::EV_SIGNAL][0], array($signal));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function del($fd, $flag)
|
||||
{
|
||||
$fd_key = (int)$fd;
|
||||
switch ($flag) {
|
||||
case self::EV_READ:
|
||||
unset($this->_allEvents[$fd_key][$flag], $this->_readFds[$fd_key]);
|
||||
if (empty($this->_allEvents[$fd_key])) {
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
return true;
|
||||
case self::EV_WRITE:
|
||||
unset($this->_allEvents[$fd_key][$flag], $this->_writeFds[$fd_key]);
|
||||
if (empty($this->_allEvents[$fd_key])) {
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
return true;
|
||||
case self::EV_EXCEPT:
|
||||
unset($this->_allEvents[$fd_key][$flag], $this->_exceptFds[$fd_key]);
|
||||
if(empty($this->_allEvents[$fd_key]))
|
||||
{
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
return true;
|
||||
case self::EV_SIGNAL:
|
||||
if(\DIRECTORY_SEPARATOR !== '/') {
|
||||
return false;
|
||||
}
|
||||
unset($this->_signalEvents[$fd_key]);
|
||||
\pcntl_signal($fd, SIG_IGN);
|
||||
break;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE;
|
||||
unset($this->_eventTimer[$fd_key]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick for timer.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tick()
|
||||
{
|
||||
$tasks_to_insert = [];
|
||||
while (!$this->_scheduler->isEmpty()) {
|
||||
$scheduler_data = $this->_scheduler->top();
|
||||
$timer_id = $scheduler_data['data'];
|
||||
$next_run_time = -$scheduler_data['priority'];
|
||||
$time_now = \microtime(true);
|
||||
$this->_selectTimeout = (int) (($next_run_time - $time_now) * 1000000);
|
||||
if ($this->_selectTimeout <= 0) {
|
||||
$this->_scheduler->extract();
|
||||
|
||||
if (!isset($this->_eventTimer[$timer_id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// [func, args, flag, timer_interval]
|
||||
$task_data = $this->_eventTimer[$timer_id];
|
||||
if ($task_data[2] === self::EV_TIMER) {
|
||||
$next_run_time = $time_now + $task_data[3];
|
||||
$tasks_to_insert[] = [$timer_id, -$next_run_time];
|
||||
}
|
||||
try {
|
||||
\call_user_func_array($task_data[0], $task_data[1]);
|
||||
} catch (Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
if (isset($this->_eventTimer[$timer_id]) && $task_data[2] === self::EV_TIMER_ONCE) {
|
||||
$this->del($timer_id, self::EV_TIMER_ONCE);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($tasks_to_insert as $item) {
|
||||
$this->_scheduler->insert($item[0], $item[1]);
|
||||
}
|
||||
if (!$this->_scheduler->isEmpty()) {
|
||||
$scheduler_data = $this->_scheduler->top();
|
||||
$next_run_time = -$scheduler_data['priority'];
|
||||
$time_now = \microtime(true);
|
||||
$this->_selectTimeout = \max((int) (($next_run_time - $time_now) * 1000000), 0);
|
||||
return;
|
||||
}
|
||||
$this->_selectTimeout = 100000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clearAllTimer()
|
||||
{
|
||||
$this->_scheduler = new \SplPriorityQueue();
|
||||
$this->_scheduler->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
|
||||
$this->_eventTimer = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loop()
|
||||
{
|
||||
while (1) {
|
||||
if(\DIRECTORY_SEPARATOR === '/') {
|
||||
// Calls signal handlers for pending signals
|
||||
\pcntl_signal_dispatch();
|
||||
}
|
||||
|
||||
$read = $this->_readFds;
|
||||
$write = $this->_writeFds;
|
||||
$except = $this->_exceptFds;
|
||||
$ret = false;
|
||||
|
||||
if ($read || $write || $except) {
|
||||
// Waiting read/write/signal/timeout events.
|
||||
try {
|
||||
$ret = @stream_select($read, $write, $except, 0, $this->_selectTimeout);
|
||||
} catch (\Exception $e) {} catch (\Error $e) {}
|
||||
|
||||
} else {
|
||||
$this->_selectTimeout >= 1 && usleep($this->_selectTimeout);
|
||||
}
|
||||
|
||||
if (!$this->_scheduler->isEmpty()) {
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
if (!$ret) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($read) {
|
||||
foreach ($read as $fd) {
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_allEvents[$fd_key][self::EV_READ])) {
|
||||
\call_user_func_array($this->_allEvents[$fd_key][self::EV_READ][0],
|
||||
array($this->_allEvents[$fd_key][self::EV_READ][1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($write) {
|
||||
foreach ($write as $fd) {
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_allEvents[$fd_key][self::EV_WRITE])) {
|
||||
\call_user_func_array($this->_allEvents[$fd_key][self::EV_WRITE][0],
|
||||
array($this->_allEvents[$fd_key][self::EV_WRITE][1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($except) {
|
||||
foreach($except as $fd) {
|
||||
$fd_key = (int) $fd;
|
||||
if(isset($this->_allEvents[$fd_key][self::EV_EXCEPT])) {
|
||||
\call_user_func_array($this->_allEvents[$fd_key][self::EV_EXCEPT][0],
|
||||
array($this->_allEvents[$fd_key][self::EV_EXCEPT][1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy loop.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timer count.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimerCount()
|
||||
{
|
||||
return \count($this->_eventTimer);
|
||||
}
|
||||
}
|
||||
285
vendor/workerman/workerman/Events/Swoole.php
vendored
Normal file
285
vendor/workerman/workerman/Events/Swoole.php
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
<?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 Ares<aresrr#qq.com>
|
||||
* @link http://www.workerman.net/
|
||||
* @link https://github.com/ares333/Workerman
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Workerman\Events;
|
||||
|
||||
use Workerman\Worker;
|
||||
use Swoole\Event;
|
||||
use Swoole\Timer;
|
||||
use Swoole\Coroutine;
|
||||
|
||||
class Swoole implements EventInterface
|
||||
{
|
||||
|
||||
protected $_timer = array();
|
||||
|
||||
protected $_timerOnceMap = array();
|
||||
|
||||
protected $mapId = 0;
|
||||
|
||||
protected $_fd = array();
|
||||
|
||||
// milisecond
|
||||
public static $signalDispatchInterval = 500;
|
||||
|
||||
protected $_hasSignal = false;
|
||||
|
||||
protected $_readEvents = array();
|
||||
|
||||
protected $_writeEvents = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Workerman\Events\EventInterface::add()
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args = array())
|
||||
{
|
||||
switch ($flag) {
|
||||
case self::EV_SIGNAL:
|
||||
$res = \pcntl_signal($fd, $func, false);
|
||||
if (! $this->_hasSignal && $res) {
|
||||
Timer::tick(static::$signalDispatchInterval,
|
||||
function () {
|
||||
\pcntl_signal_dispatch();
|
||||
});
|
||||
$this->_hasSignal = true;
|
||||
}
|
||||
return $res;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
$method = self::EV_TIMER === $flag ? 'tick' : 'after';
|
||||
if ($this->mapId > \PHP_INT_MAX) {
|
||||
$this->mapId = 0;
|
||||
}
|
||||
$mapId = $this->mapId++;
|
||||
$t = (int)($fd * 1000);
|
||||
if ($t < 1) {
|
||||
$t = 1;
|
||||
}
|
||||
$timer_id = Timer::$method($t,
|
||||
function ($timer_id = null) use ($func, $args, $mapId) {
|
||||
try {
|
||||
\call_user_func_array($func, (array)$args);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
// EV_TIMER_ONCE
|
||||
if (! isset($timer_id)) {
|
||||
// may be deleted in $func
|
||||
if (\array_key_exists($mapId, $this->_timerOnceMap)) {
|
||||
$timer_id = $this->_timerOnceMap[$mapId];
|
||||
unset($this->_timer[$timer_id],
|
||||
$this->_timerOnceMap[$mapId]);
|
||||
}
|
||||
}
|
||||
});
|
||||
if ($flag === self::EV_TIMER_ONCE) {
|
||||
$this->_timerOnceMap[$mapId] = $timer_id;
|
||||
$this->_timer[$timer_id] = $mapId;
|
||||
} else {
|
||||
$this->_timer[$timer_id] = null;
|
||||
}
|
||||
return $timer_id;
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$fd_key = (int) $fd;
|
||||
if ($flag === self::EV_READ) {
|
||||
$this->_readEvents[$fd_key] = $func;
|
||||
} else {
|
||||
$this->_writeEvents[$fd_key] = $func;
|
||||
}
|
||||
if (!isset($this->_fd[$fd_key])) {
|
||||
if ($flag === self::EV_READ) {
|
||||
$res = Event::add($fd, [$this, 'callRead'], null, SWOOLE_EVENT_READ);
|
||||
$fd_type = SWOOLE_EVENT_READ;
|
||||
} else {
|
||||
$res = Event::add($fd, null, $func, SWOOLE_EVENT_WRITE);
|
||||
$fd_type = SWOOLE_EVENT_WRITE;
|
||||
}
|
||||
if ($res) {
|
||||
$this->_fd[$fd_key] = $fd_type;
|
||||
}
|
||||
} else {
|
||||
$fd_val = $this->_fd[$fd_key];
|
||||
$res = true;
|
||||
if ($flag === self::EV_READ) {
|
||||
if (($fd_val & SWOOLE_EVENT_READ) !== SWOOLE_EVENT_READ) {
|
||||
$res = Event::set($fd, $func, null,
|
||||
SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE);
|
||||
$this->_fd[$fd_key] |= SWOOLE_EVENT_READ;
|
||||
}
|
||||
} else {
|
||||
if (($fd_val & SWOOLE_EVENT_WRITE) !== SWOOLE_EVENT_WRITE) {
|
||||
$res = Event::set($fd, null, $func,
|
||||
SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE);
|
||||
$this->_fd[$fd_key] |= SWOOLE_EVENT_WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fd
|
||||
* @return void
|
||||
*/
|
||||
protected function callRead($stream)
|
||||
{
|
||||
$fd = (int) $stream;
|
||||
if (isset($this->_readEvents[$fd])) {
|
||||
try {
|
||||
\call_user_func($this->_readEvents[$fd], $stream);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fd
|
||||
* @return void
|
||||
*/
|
||||
protected function callWrite($stream)
|
||||
{
|
||||
$fd = (int) $stream;
|
||||
if (isset($this->_writeEvents[$fd])) {
|
||||
try {
|
||||
\call_user_func($this->_writeEvents[$fd], $stream);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Workerman\Events\EventInterface::del()
|
||||
*/
|
||||
public function del($fd, $flag)
|
||||
{
|
||||
switch ($flag) {
|
||||
case self::EV_SIGNAL:
|
||||
return \pcntl_signal($fd, SIG_IGN, false);
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
// already remove in EV_TIMER_ONCE callback.
|
||||
if (! \array_key_exists($fd, $this->_timer)) {
|
||||
return true;
|
||||
}
|
||||
$res = Timer::clear($fd);
|
||||
if ($res) {
|
||||
$mapId = $this->_timer[$fd];
|
||||
if (isset($mapId)) {
|
||||
unset($this->_timerOnceMap[$mapId]);
|
||||
}
|
||||
unset($this->_timer[$fd]);
|
||||
}
|
||||
return $res;
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$fd_key = (int) $fd;
|
||||
if ($flag === self::EV_READ) {
|
||||
unset($this->_readEvents[$fd_key]);
|
||||
} elseif ($flag === self::EV_WRITE) {
|
||||
unset($this->_writeEvents[$fd_key]);
|
||||
}
|
||||
if (isset($this->_fd[$fd_key])) {
|
||||
$fd_val = $this->_fd[$fd_key];
|
||||
if ($flag === self::EV_READ) {
|
||||
$flag_remove = ~ SWOOLE_EVENT_READ;
|
||||
} else {
|
||||
$flag_remove = ~ SWOOLE_EVENT_WRITE;
|
||||
}
|
||||
$fd_val &= $flag_remove;
|
||||
if (0 === $fd_val) {
|
||||
$res = Event::del($fd);
|
||||
if ($res) {
|
||||
unset($this->_fd[$fd_key]);
|
||||
}
|
||||
} else {
|
||||
$res = Event::set($fd, null, null, $fd_val);
|
||||
if ($res) {
|
||||
$this->_fd[$fd_key] = $fd_val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$res = true;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Workerman\Events\EventInterface::clearAllTimer()
|
||||
*/
|
||||
public function clearAllTimer()
|
||||
{
|
||||
foreach (array_keys($this->_timer) as $v) {
|
||||
Timer::clear($v);
|
||||
}
|
||||
$this->_timer = array();
|
||||
$this->_timerOnceMap = array();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Workerman\Events\EventInterface::loop()
|
||||
*/
|
||||
public function loop()
|
||||
{
|
||||
Event::wait();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Workerman\Events\EventInterface::destroy()
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
foreach (Coroutine::listCoroutines() as $coroutine) {
|
||||
Coroutine::cancel($coroutine);
|
||||
}
|
||||
// Wait for coroutines to exit
|
||||
usleep(100000);
|
||||
Event::exit();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Workerman\Events\EventInterface::getTimerCount()
|
||||
*/
|
||||
public function getTimerCount()
|
||||
{
|
||||
return \count($this->_timer);
|
||||
}
|
||||
}
|
||||
260
vendor/workerman/workerman/Events/Uv.php
vendored
Normal file
260
vendor/workerman/workerman/Events/Uv.php
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
<?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 爬山虎<blogdaren@163.com>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Workerman\Events;
|
||||
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* libuv eventloop
|
||||
*/
|
||||
class Uv implements EventInterface
|
||||
{
|
||||
/**
|
||||
* Event Loop.
|
||||
* @var object
|
||||
*/
|
||||
protected $_eventLoop = null;
|
||||
|
||||
/**
|
||||
* All listeners for read/write event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_allEvents = array();
|
||||
|
||||
/**
|
||||
* Event listeners of signal.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventSignal = array();
|
||||
|
||||
/**
|
||||
* All timer event listeners.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_eventTimer = array();
|
||||
|
||||
/**
|
||||
* Timer id.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $_timerId = 1;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param object $loop
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(\UVLoop $loop = null)
|
||||
{
|
||||
if(!extension_loaded('uv'))
|
||||
{
|
||||
throw new \Exception(__CLASS__ . ' requires the UV extension, but detected it has NOT been installed yet.');
|
||||
}
|
||||
|
||||
if(empty($loop) || !$loop instanceof \UVLoop)
|
||||
{
|
||||
$this->_eventLoop = \uv_default_loop();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_eventLoop = $loop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a timer
|
||||
*
|
||||
* @param resource $fd
|
||||
* @param int $flag
|
||||
* @param callback $func
|
||||
* @param mixed $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function add($fd, $flag, $func, $args = null)
|
||||
{
|
||||
switch ($flag)
|
||||
{
|
||||
case self::EV_SIGNAL:
|
||||
$signalCallback = function($watcher, $socket)use($func, $fd){
|
||||
try {
|
||||
\call_user_func($func, $fd);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
};
|
||||
$signalWatcher = \uv_signal_init();
|
||||
\uv_signal_start($signalWatcher, $signalCallback, $fd);
|
||||
$this->_eventSignal[$fd] = $signalWatcher;
|
||||
return true;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
$repeat = $flag === self::EV_TIMER_ONCE ? 0 : (int)($fd * 1000);
|
||||
$param = array($func, (array)$args, $flag, $fd, self::$_timerId);
|
||||
$timerWatcher = \uv_timer_init();
|
||||
\uv_timer_start($timerWatcher, ($flag === self::EV_TIMER_ONCE ? (int)($fd * 1000) :1), $repeat, function($watcher)use($param){
|
||||
call_user_func_array([$this, 'timerCallback'], [$param]);
|
||||
});
|
||||
$this->_eventTimer[self::$_timerId] = $timerWatcher;
|
||||
return self::$_timerId++;
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$fd_key = (int)$fd;
|
||||
$ioCallback = function($watcher, $status, $events, $fd)use($func){
|
||||
try {
|
||||
\call_user_func($func, $fd);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
};
|
||||
$ioWatcher = \uv_poll_init($this->_eventLoop, $fd);
|
||||
$real_flag = $flag === self::EV_READ ? \Uv::READABLE : \Uv::WRITABLE;
|
||||
\uv_poll_start($ioWatcher, $real_flag, $ioCallback);
|
||||
$this->_allEvents[$fd_key][$flag] = $ioWatcher;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a timer
|
||||
*
|
||||
* @param resource $fd
|
||||
* @param int $flag
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function del($fd, $flag)
|
||||
{
|
||||
switch ($flag)
|
||||
{
|
||||
case self::EV_READ:
|
||||
case self::EV_WRITE:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_allEvents[$fd_key][$flag])) {
|
||||
$watcher = $this->_allEvents[$fd_key][$flag];
|
||||
\uv_is_active($watcher) && \uv_poll_stop($watcher);
|
||||
unset($this->_allEvents[$fd_key][$flag]);
|
||||
}
|
||||
if (empty($this->_allEvents[$fd_key])) {
|
||||
unset($this->_allEvents[$fd_key]);
|
||||
}
|
||||
break;
|
||||
case self::EV_SIGNAL:
|
||||
$fd_key = (int)$fd;
|
||||
if (isset($this->_eventSignal[$fd_key])) {
|
||||
$watcher = $this->_eventSignal[$fd_key];
|
||||
\uv_is_active($watcher) && \uv_signal_stop($watcher);
|
||||
unset($this->_eventSignal[$fd_key]);
|
||||
}
|
||||
break;
|
||||
case self::EV_TIMER:
|
||||
case self::EV_TIMER_ONCE:
|
||||
if (isset($this->_eventTimer[$fd])) {
|
||||
$watcher = $this->_eventTimer[$fd];
|
||||
\uv_is_active($watcher) && \uv_timer_stop($watcher);
|
||||
unset($this->_eventTimer[$fd]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Timer callback
|
||||
*
|
||||
* @param array $input
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function timerCallback($input)
|
||||
{
|
||||
if(!is_array($input)) return;
|
||||
|
||||
$timer_id = $input[4];
|
||||
|
||||
if ($input[2] === self::EV_TIMER_ONCE)
|
||||
{
|
||||
$watcher = $this->_eventTimer[$timer_id];
|
||||
\uv_is_active($watcher) && \uv_timer_stop($watcher);
|
||||
unset($this->_eventTimer[$timer_id]);
|
||||
}
|
||||
|
||||
try {
|
||||
\call_user_func_array($input[0], $input[1]);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove all timers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearAllTimer()
|
||||
{
|
||||
if(!is_array($this->_eventTimer)) return;
|
||||
|
||||
foreach($this->_eventTimer as $watcher)
|
||||
{
|
||||
\uv_is_active($watcher) && \uv_timer_stop($watcher);
|
||||
}
|
||||
|
||||
$this->_eventTimer = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start loop
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loop()
|
||||
{
|
||||
\Uv_run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy loop
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
!empty($this->_eventLoop) && \uv_loop_delete($this->_eventLoop);
|
||||
$this->_allEvents = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get timer count
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimerCount()
|
||||
{
|
||||
return \count($this->_eventTimer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user