Event.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * This file is part of workerman.
  4. *
  5. * Licensed under The MIT License
  6. * For full copyright and license information, please see the MIT-LICENSE.txt
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @author walkor<walkor@workerman.net>
  10. * @copyright walkor<walkor@workerman.net>
  11. * @link http://www.workerman.net/
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Workerman\Events;
  15. use Workerman\Worker;
  16. /**
  17. * libevent eventloop
  18. */
  19. class Event implements EventInterface
  20. {
  21. /**
  22. * Event base.
  23. * @var object
  24. */
  25. protected $eventBase = null;
  26. /**
  27. * All listeners for read event.
  28. * @var array
  29. */
  30. protected $readEvents = [];
  31. /**
  32. * All listeners for write event.
  33. * @var array
  34. */
  35. protected $writeEvents = [];
  36. /**
  37. * Event listeners of signal.
  38. * @var array
  39. */
  40. protected $eventSignal = [];
  41. /**
  42. * All timer event listeners.
  43. * [func, args, event, flag, time_interval]
  44. * @var array
  45. */
  46. protected $eventTimer = [];
  47. /**
  48. * Timer id.
  49. * @var int
  50. */
  51. protected $timerId = 0;
  52. /**
  53. * Event class name.
  54. * @var string
  55. */
  56. protected $eventClassName = '';
  57. /**
  58. * Construct.
  59. * @return void
  60. */
  61. public function __construct()
  62. {
  63. if (\class_exists('\\\\Event', false)) {
  64. $className = '\\\\Event';
  65. } else {
  66. $className = '\Event';
  67. }
  68. $this->eventClassName = $className;
  69. if (\class_exists('\\\\EventBase', false)) {
  70. $className = '\\\\EventBase';
  71. } else {
  72. $className = '\EventBase';
  73. }
  74. $this->eventBase = new $className();
  75. }
  76. /**
  77. * {@inheritdoc}
  78. */
  79. public function delay(float $delay, $func, $args = [])
  80. {
  81. $className = $this->eventClassName;
  82. $timerId = $this->timerId++;
  83. $event = new $className($this->eventBase, -1, $className::TIMEOUT, function () use ($func, $args, $timerId) {
  84. try {
  85. $this->offDelay($timerId);
  86. $func(...$args);
  87. } catch (\Throwable $e) {
  88. Worker::stopAll(250, $e);
  89. }
  90. });
  91. if (!$event || !$event->addTimer($delay)) {
  92. return false;
  93. }
  94. $this->eventTimer[$timerId] = $event;
  95. return $timerId;
  96. }
  97. /**
  98. * {@inheritdoc}
  99. */
  100. public function offDelay($timerId)
  101. {
  102. if (isset($this->eventTimer[$timerId])) {
  103. $this->eventTimer[$timerId]->del();
  104. unset($this->eventTimer[$timerId]);
  105. return true;
  106. }
  107. return false;
  108. }
  109. /**
  110. * {@inheritdoc}
  111. */
  112. public function offRepeat($timerId)
  113. {
  114. return $this->offDelay($timerId);
  115. }
  116. /**
  117. * {@inheritdoc}
  118. */
  119. public function repeat(float $interval, $func, $args = [])
  120. {
  121. $className = $this->eventClassName;
  122. $timerId = $this->timerId++;
  123. $event = new $className($this->eventBase, -1, $className::TIMEOUT | $className::PERSIST, function () use ($func, $args) {
  124. try {
  125. $func(...$args);
  126. } catch (\Throwable $e) {
  127. Worker::stopAll(250, $e);
  128. }
  129. });
  130. if (!$event || !$event->addTimer($interval)) {
  131. return false;
  132. }
  133. $this->eventTimer[$timerId] = $event;
  134. return $timerId;
  135. }
  136. /**
  137. * {@inheritdoc}
  138. */
  139. public function onReadable($stream, $func)
  140. {
  141. $className = $this->eventClassName;
  142. $fdKey = (int)$stream;
  143. $event = new $this->eventClassName($this->eventBase, $stream, $className::READ | $className::PERSIST, $func, $stream);
  144. if (!$event || !$event->add()) {
  145. return false;
  146. }
  147. $this->writeEvents[$fdKey] = $event;
  148. return true;
  149. }
  150. /**
  151. * {@inheritdoc}
  152. */
  153. public function offReadable($stream)
  154. {
  155. $fdKey = (int)$stream;
  156. if (isset($this->readEvents[$fdKey])) {
  157. $this->readEvents[$fdKey]->del();
  158. unset($this->readEvents[$fdKey]);
  159. }
  160. }
  161. /**
  162. * {@inheritdoc}
  163. */
  164. public function onWritable($stream, $func)
  165. {
  166. $className = $this->eventClassName;
  167. $fdKey = (int)$stream;
  168. $event = new $this->eventClassName($this->eventBase, $stream, $className::WRITE | $className::PERSIST, $func, $stream);
  169. if (!$event || !$event->add()) {
  170. return false;
  171. }
  172. $this->writeEvents[$fdKey] = $event;
  173. return true;
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. public function offWritable($stream)
  179. {
  180. $fdKey = (int)$stream;
  181. if (isset($this->writeEvents[$fdKey])) {
  182. $this->writeEvents[$fdKey]->del();
  183. unset($this->writeEvents[$fdKey]);
  184. }
  185. }
  186. /**
  187. * {@inheritdoc}
  188. */
  189. public function onSignal($signal, $func)
  190. {
  191. $className = $this->eventClassName;
  192. $fdKey = (int)$signal;
  193. $event = $className::signal($this->eventBase, $signal, $func);
  194. if (!$event || !$event->add()) {
  195. return false;
  196. }
  197. $this->eventSignal[$fdKey] = $event;
  198. return true;
  199. }
  200. /**
  201. * {@inheritdoc}
  202. */
  203. public function offSignal($signal)
  204. {
  205. $fdKey = (int)$signal;
  206. if (isset($this->eventSignal[$fdKey])) {
  207. $this->eventSignal[$fdKey]->del();
  208. unset($this->eventSignal[$fdKey]);
  209. }
  210. }
  211. /**
  212. * {@inheritdoc}
  213. */
  214. public function deleteAllTimer()
  215. {
  216. foreach ($this->eventTimer as $event) {
  217. $event->del();
  218. }
  219. $this->eventTimer = [];
  220. }
  221. /**
  222. * {@inheritdoc}
  223. */
  224. public function run()
  225. {
  226. $this->eventBase->loop();
  227. }
  228. /**
  229. * {@inheritdoc}
  230. */
  231. public function stop()
  232. {
  233. $this->eventBase->exit();
  234. }
  235. /**
  236. * {@inheritdoc}
  237. */
  238. public function getTimerCount()
  239. {
  240. return \count($this->eventTimer);
  241. }
  242. }