123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <?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\Lib;
- use Workerman\Events\EventInterface;
- use Exception;
- /**
- * Timer.
- *
- * example:
- * Workerman\Lib\Timer::add($time_interval, callback, array($arg1, $arg2..));
- */
- class Timer
- {
- /**
- * Tasks that based on ALARM signal.
- * [
- * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
- * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
- * ..
- * ]
- *
- * @var array
- */
- protected static $_tasks = array();
- /**
- * event
- *
- * @var \Workerman\Events\EventInterface
- */
- protected static $_event = null;
- /**
- * Init.
- *
- * @param \Workerman\Events\EventInterface $event
- * @return void
- */
- public static function init($event = null)
- {
- if ($event) {
- self::$_event = $event;
- } else {
- if (function_exists('pcntl_signal')) {
- pcntl_signal(SIGALRM, array('\Workerman\Lib\Timer', 'signalHandle'), false);
- }
- }
- }
- /**
- * ALARM signal handler.
- *
- * @return void
- */
- public static function signalHandle()
- {
- if (!self::$_event) {
- pcntl_alarm(1);
- self::tick();
- }
- }
- /**
- * Add a timer.
- *
- * @param float $time_interval
- * @param callable $func
- * @param mixed $args
- * @param bool $persistent
- * @return int/false
- */
- public static function add($time_interval, $func, $args = array(), $persistent = true)
- {
- if ($time_interval <= 0) {
- echo new Exception("bad time_interval");
- return false;
- }
- if (self::$_event) {
- return self::$_event->add($time_interval,
- $persistent ? EventInterface::EV_TIMER : EventInterface::EV_TIMER_ONCE, $func, $args);
- }
- if (!is_callable($func)) {
- echo new Exception("not callable");
- return false;
- }
- if (empty(self::$_tasks)) {
- pcntl_alarm(1);
- }
- $time_now = time();
- $run_time = $time_now + $time_interval;
- if (!isset(self::$_tasks[$run_time])) {
- self::$_tasks[$run_time] = array();
- }
- self::$_tasks[$run_time][] = array($func, (array)$args, $persistent, $time_interval);
- return 1;
- }
- /**
- * Tick.
- *
- * @return void
- */
- public static function tick()
- {
- if (empty(self::$_tasks)) {
- pcntl_alarm(0);
- return;
- }
- $time_now = time();
- foreach (self::$_tasks as $run_time => $task_data) {
- if ($time_now >= $run_time) {
- foreach ($task_data as $index => $one_task) {
- $task_func = $one_task[0];
- $task_args = $one_task[1];
- $persistent = $one_task[2];
- $time_interval = $one_task[3];
- try {
- call_user_func_array($task_func, $task_args);
- } catch (\Exception $e) {
- echo $e;
- }
- if ($persistent) {
- self::add($time_interval, $task_func, $task_args);
- }
- }
- unset(self::$_tasks[$run_time]);
- }
- }
- }
- /**
- * Remove a timer.
- *
- * @param mixed $timer_id
- * @return bool
- */
- public static function del($timer_id)
- {
- if (self::$_event) {
- return self::$_event->del($timer_id, EventInterface::EV_TIMER);
- }
- return false;
- }
- /**
- * Remove all timers.
- *
- * @return void
- */
- public static function delAll()
- {
- self::$_tasks = array();
- pcntl_alarm(0);
- if (self::$_event) {
- self::$_event->clearAllTimer();
- }
- }
- }
|