class EventDriver
Hierarchy
- class \Revolt\EventLoop\Internal\AbstractDriver implements \Revolt\EventLoop\Driver
- class \Revolt\EventLoop\Driver\EventDriver extends \Revolt\EventLoop\Internal\AbstractDriver
Expanded class hierarchy of EventDriver
1 file declares its use of EventDriver
- DriverFactory.php in vendor/
revolt/ event-loop/ src/ EventLoop/ DriverFactory.php
File
-
vendor/
revolt/ event-loop/ src/ EventLoop/ Driver/ EventDriver.php, line 17
Namespace
Revolt\EventLoop\DriverView source
final class EventDriver extends AbstractDriver {
/** @var array<string, \Event>|null */
private static ?array $activeSignals = null;
public static function isSupported() : bool {
return \extension_loaded("event");
}
private \EventBase $handle;
/** @var array<string, \Event> */
private array $events = [];
private readonly \Closure $ioCallback;
private readonly \Closure $timerCallback;
private readonly \Closure $signalCallback;
/** @var array<string, \Event> */
private array $signals = [];
public function __construct() {
parent::__construct();
/** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
$this->handle = new \EventBase();
if (self::$activeSignals === null) {
self::$activeSignals =& $this->signals;
}
$this->ioCallback = function ($resource, $what, StreamCallback $callback) : void {
$this->enqueueCallback($callback);
};
$this->timerCallback = function ($resource, $what, TimerCallback $callback) : void {
$this->enqueueCallback($callback);
};
$this->signalCallback = function ($signo, $what, SignalCallback $callback) : void {
$this->enqueueCallback($callback);
};
}
/**
* {@inheritdoc}
*/
public function cancel(string $callbackId) : void {
parent::cancel($callbackId);
if (isset($this->events[$callbackId])) {
$this->events[$callbackId]
->free();
unset($this->events[$callbackId]);
}
}
/**
* @codeCoverageIgnore
*/
public function __destruct() {
foreach ($this->events as $event) {
if ($event !== null) {
// Events may have been nulled in extension depending on destruct order.
$event->free();
}
}
// Unset here, otherwise $event->del() fails with a warning, because __destruct order isn't defined.
// See https://github.com/amphp/amp/issues/159.
$this->events = [];
// Manually free the loop handle to fully release loop resources.
// See https://github.com/amphp/amp/issues/177.
/** @psalm-suppress RedundantPropertyInitializationCheck */
if (isset($this->handle)) {
$this->handle
->free();
unset($this->handle);
}
}
/**
* {@inheritdoc}
*/
public function run() : void {
$active = self::$activeSignals;
\assert($active !== null);
foreach ($active as $event) {
$event->del();
}
self::$activeSignals =& $this->signals;
foreach ($this->signals as $event) {
/** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
$event->add();
}
try {
parent::run();
} finally {
foreach ($this->signals as $event) {
$event->del();
}
self::$activeSignals =& $active;
foreach ($active as $event) {
/** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
$event->add();
}
}
}
/**
* {@inheritdoc}
*/
public function stop() : void {
$this->handle
->stop();
parent::stop();
}
/**
* {@inheritdoc}
*/
public function getHandle() : \EventBase {
return $this->handle;
}
protected function now() : float {
return (double) \hrtime(true) / 1000000000;
}
/**
* {@inheritdoc}
*/
protected function dispatch(bool $blocking) : void {
$this->handle
->loop($blocking ? \EventBase::LOOP_ONCE : \EventBase::LOOP_ONCE | \EventBase::LOOP_NONBLOCK);
}
/**
* {@inheritdoc}
*/
protected function activate(array $callbacks) : void {
$now = $this->now();
foreach ($callbacks as $callback) {
if (!isset($this->events[$id = $callback->id])) {
if ($callback instanceof StreamReadableCallback) {
\assert(\is_resource($callback->stream));
$this->events[$id] = new \Event($this->handle, $callback->stream, \Event::READ | \Event::PERSIST, $this->ioCallback, $callback);
}
elseif ($callback instanceof StreamWritableCallback) {
\assert(\is_resource($callback->stream));
$this->events[$id] = new \Event($this->handle, $callback->stream, \Event::WRITE | \Event::PERSIST, $this->ioCallback, $callback);
}
elseif ($callback instanceof TimerCallback) {
$this->events[$id] = new \Event($this->handle, -1, \Event::TIMEOUT, $this->timerCallback, $callback);
}
elseif ($callback instanceof SignalCallback) {
$this->events[$id] = new \Event($this->handle, $callback->signal, \Event::SIGNAL | \Event::PERSIST, $this->signalCallback, $callback);
}
else {
// @codeCoverageIgnoreStart
throw new \Error("Unknown callback type");
// @codeCoverageIgnoreEnd
}
}
if ($callback instanceof TimerCallback) {
$interval = \min(\max(0, $callback->expiration - $now), \PHP_INT_MAX / 2);
$this->events[$id]
->add($interval > 0 ? $interval : 0);
}
elseif ($callback instanceof SignalCallback) {
$this->signals[$id] = $this->events[$id];
/** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
$this->events[$id]
->add();
}
else {
/** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
$this->events[$id]
->add();
}
}
}
/**
* {@inheritdoc}
*/
protected function deactivate(DriverCallback $callback) : void {
if (isset($this->events[$id = $callback->id])) {
$this->events[$id]
->del();
if ($callback instanceof SignalCallback) {
unset($this->signals[$id]);
}
}
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
AbstractDriver::$callbackFiber | private | property | |||
AbstractDriver::$callbackQueue | private | property | @var \SplQueue<DriverCallback> | ||
AbstractDriver::$callbacks | private | property | @var array<string, DriverCallback> | ||
AbstractDriver::$enableDeferQueue | private | property | @var array<string, DriverCallback> | ||
AbstractDriver::$enableQueue | private | property | @var array<string, DriverCallback> | ||
AbstractDriver::$errorCallback | private | property | |||
AbstractDriver::$errorHandler | private | property | @var null|\Closure(\Throwable):void | ||
AbstractDriver::$fiber | private | property | |||
AbstractDriver::$idle | private | property | |||
AbstractDriver::$internalSuspensionMarker | private | property | |||
AbstractDriver::$interrupt | private | property | @var null|\Closure():mixed | ||
AbstractDriver::$interruptCallback | private | property | |||
AbstractDriver::$microtaskQueue | private | property | @var \SplQueue<array{\Closure, array}> | ||
AbstractDriver::$nextId | private | property | @var string Next callback identifier. | ||
AbstractDriver::$queueCallback | private | property | |||
AbstractDriver::$runCallback | private | property | |||
AbstractDriver::$stopped | private | property | |||
AbstractDriver::$suspensions | private | property | @var \WeakMap<object, \WeakReference<DriverSuspension>> | ||
AbstractDriver::createCallbackFiber | private | function | |||
AbstractDriver::createErrorCallback | private | function | |||
AbstractDriver::createLoopFiber | private | function | |||
AbstractDriver::defer | public | function | Defer the execution of a callback. | Overrides Driver::defer | |
AbstractDriver::delay | public | function | Delay the execution of a callback. | Overrides Driver::delay | |
AbstractDriver::disable | public | function | Disable a callback immediately. | Overrides Driver::disable | |
AbstractDriver::enable | public | function | Enable a callback to be active starting in the next tick. | Overrides Driver::enable | |
AbstractDriver::enqueueCallback | final protected | function | |||
AbstractDriver::error | final protected | function | Invokes the error handler with the given exception. | ||
AbstractDriver::getErrorHandler | public | function | Gets the error handler closure or {@code null} if none is set. | Overrides Driver::getErrorHandler | |
AbstractDriver::getIdentifiers | public | function | Returns all registered non-cancelled callback identifiers. | Overrides Driver::getIdentifiers | |
AbstractDriver::getSuspension | public | function | Returns an object used to suspend and resume execution of the current fiber or {main}. | Overrides Driver::getSuspension | |
AbstractDriver::getType | public | function | Returns the type of the callback identified by the given callback identifier. | Overrides Driver::getType | |
AbstractDriver::invokeCallbacks | private | function | |||
AbstractDriver::invokeInterrupt | private | function | |||
AbstractDriver::invokeMicrotasks | private | function | |||
AbstractDriver::isEmpty | private | function | |||
AbstractDriver::isEnabled | public | function | Returns whether the callback identified by the given callback identifier is currently enabled. | Overrides Driver::isEnabled | |
AbstractDriver::isReferenced | public | function | Returns whether the callback identified by the given callback identifier is currently referenced. | Overrides Driver::isReferenced | |
AbstractDriver::isRunning | public | function | Overrides Driver::isRunning | ||
AbstractDriver::onReadable | public | function | Execute a callback when a stream resource becomes readable or is closed for reading. | Overrides Driver::onReadable | |
AbstractDriver::onSignal | public | function | Execute a callback when a signal is received. | Overrides Driver::onSignal | 1 |
AbstractDriver::onWritable | public | function | Execute a callback when a stream resource becomes writable or is closed for writing. | Overrides Driver::onWritable | |
AbstractDriver::queue | public | function | Queue a microtask. | Overrides Driver::queue | |
AbstractDriver::reference | public | function | Reference a callback. | Overrides Driver::reference | |
AbstractDriver::repeat | public | function | Repeatedly execute a callback. | Overrides Driver::repeat | |
AbstractDriver::setErrorHandler | public | function | Set a callback to be executed when an error occurs. | Overrides Driver::setErrorHandler | |
AbstractDriver::setInterrupt | private | function | |||
AbstractDriver::tick | private | function | Executes a single tick of the event loop. | ||
AbstractDriver::unreference | public | function | Unreference a callback. | Overrides Driver::unreference | |
AbstractDriver::__debugInfo | public | function | Returns some useful information about the event loop. | Overrides Driver::__debugInfo | |
EventDriver::$activeSignals | private static | property | @var array<string, \Event>|null | ||
EventDriver::$events | private | property | @var array<string, \Event> | ||
EventDriver::$handle | private | property | |||
EventDriver::$ioCallback | private | property | |||
EventDriver::$signalCallback | private | property | |||
EventDriver::$signals | private | property | @var array<string, \Event> | ||
EventDriver::$timerCallback | private | property | |||
EventDriver::activate | protected | function | Activates (enables) all the given callbacks. | Overrides AbstractDriver::activate | |
EventDriver::cancel | public | function | Cancel a callback. | Overrides AbstractDriver::cancel | |
EventDriver::deactivate | protected | function | Deactivates (disables) the given callback. | Overrides AbstractDriver::deactivate | |
EventDriver::dispatch | protected | function | Dispatches any pending read/write, timer, and signal events. | Overrides AbstractDriver::dispatch | |
EventDriver::getHandle | public | function | Get the underlying loop handle. | Overrides Driver::getHandle | |
EventDriver::isSupported | public static | function | |||
EventDriver::now | protected | function | Returns the current event loop time in second increments. | Overrides AbstractDriver::now | |
EventDriver::run | public | function | Run the event loop. | Overrides AbstractDriver::run | |
EventDriver::stop | public | function | Stop the event loop. | Overrides AbstractDriver::stop | |
EventDriver::__construct | public | function | Overrides AbstractDriver::__construct | ||
EventDriver::__destruct | public | function | @codeCoverageIgnore |