80 lines
1.5 KiB
PHP
80 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\Ipc\Interop\Async;
|
|
|
|
use NoccyLabs\Ipc\Signal\SignalHandler;
|
|
|
|
|
|
/**
|
|
* Simple second-granularity timer for asynchronous events
|
|
*
|
|
*/
|
|
class Timer
|
|
{
|
|
private static $timers = null;
|
|
|
|
private $callback;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param callable $callback
|
|
*/
|
|
public function __construct(callable $callback)
|
|
{
|
|
$this->callback = $callback;
|
|
self::registerTimer($this->callback);
|
|
}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
self::clearTimer($this->callback);
|
|
}
|
|
|
|
/**
|
|
* Register a timer callback function
|
|
*
|
|
* @param callable $timer
|
|
* @return void
|
|
*/
|
|
private static function registerTimer(callable $timer)
|
|
{
|
|
if (self::$timers === null) {
|
|
$handler = new SignalHandler(SIGALRM, [ __CLASS__."::onSignal" ]);
|
|
pcntl_alarm(1);
|
|
}
|
|
self::$timers[] = $timer;
|
|
}
|
|
|
|
/**
|
|
* Remove a timer callback function
|
|
*
|
|
* @param callable $timer
|
|
* @return void
|
|
*/
|
|
private static function clearTimer(callable $timer)
|
|
{
|
|
self::$timers = array_filter(self::$timers, function ($t) use ($timer) {
|
|
return $t !== $timer;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle signals when the alarm fires
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function onSignal()
|
|
{
|
|
foreach (self::$timers as $timer) {
|
|
call_user_func($timer);
|
|
}
|
|
pcntl_alarm(1);
|
|
}
|
|
|
|
}
|
|
|