Event.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. $class_name = '\\\\Event';
  65. } else {
  66. $class_name = '\Event';
  67. }
  68. $this->_eventClassName = $class_name;
  69. if (\class_exists('\\\\EventBase', false)) {
  70. $class_name = '\\\\EventBase';
  71. } else {
  72. $class_name = '\EventBase';
  73. }
  74. $this->_eventBase = new $class_name();
  75. }
  76. /**
  77. * {@inheritdoc}
  78. */
  79. public function delay(float $delay, $func, $args)
  80. {
  81. $class_name = $this->_eventClassName;
  82. $timer_id = $this->_timerId++;
  83. $event = new $class_name($this->_eventBase, -1, $class_name::TIMEOUT, function () use ($func, $args, $timer_id) {
  84. try {
  85. $this->deleteTimer($timer_id);
  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[$timer_id] = $event;
  95. return $timer_id;
  96. }
  97. /**
  98. * {@inheritdoc}
  99. */
  100. public function deleteTimer($timer_id)
  101. {
  102. if (isset($this->_eventTimer[$timer_id])) {
  103. $this->_eventTimer[$timer_id]->del();
  104. unset($this->_eventTimer[$timer_id]);
  105. return true;
  106. }
  107. return false;
  108. }
  109. /**
  110. * {@inheritdoc}
  111. */
  112. public function repeat(float $interval, $func, $args)
  113. {
  114. $class_name = $this->_eventClassName;
  115. $timer_id = $this->_timerId++;
  116. $event = new $class_name($this->_eventBase, -1, $class_name::TIMEOUT | $class_name::PERSIST, function () use ($func, $args) {
  117. try {
  118. $func(...$args);
  119. } catch (\Throwable $e) {
  120. Worker::stopAll(250, $e);
  121. }
  122. });
  123. if (!$event || !$event->addTimer($interval)) {
  124. return false;
  125. }
  126. $this->_eventTimer[$timer_id] = $event;
  127. return $timer_id;
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. public function onReadable($stream, $func)
  133. {
  134. $class_name = $this->_eventClassName;
  135. $fd_key = (int)$stream;
  136. $event = new $this->_eventClassName($this->_eventBase, $stream, $class_name::READ | $class_name::PERSIST, $func, $stream);
  137. if (!$event || !$event->add()) {
  138. return false;
  139. }
  140. $this->_writeEvents[$fd_key] = $event;
  141. return true;
  142. }
  143. /**
  144. * {@inheritdoc}
  145. */
  146. public function offReadable($stream)
  147. {
  148. $fd_key = (int)$stream;
  149. if (isset($this->_readEvents[$fd_key])) {
  150. $this->_readEvents[$fd_key]->del();
  151. unset($this->_readEvents[$fd_key]);
  152. }
  153. }
  154. /**
  155. * {@inheritdoc}
  156. */
  157. public function onWritable($stream, $func)
  158. {
  159. $class_name = $this->_eventClassName;
  160. $fd_key = (int)$stream;
  161. $event = new $this->_eventClassName($this->_eventBase, $stream, $class_name::WRITE | $class_name::PERSIST, $func, $stream);
  162. if (!$event || !$event->add()) {
  163. return false;
  164. }
  165. $this->_writeEvents[$fd_key] = $event;
  166. return true;
  167. }
  168. /**
  169. * {@inheritdoc}
  170. */
  171. public function offWritable($stream)
  172. {
  173. $fd_key = (int)$stream;
  174. if (isset($this->_writeEvents[$fd_key])) {
  175. $this->_writeEvents[$fd_key]->del();
  176. unset($this->_writeEvents[$fd_key]);
  177. }
  178. }
  179. /**
  180. * {@inheritdoc}
  181. */
  182. public function onSignal($signal, $func)
  183. {
  184. $class_name = $this->_eventClassName;
  185. $fd_key = (int)$signal;
  186. $event = $class_name::signal($this->_eventBase, $signal, $func);
  187. if (!$event || !$event->add()) {
  188. return false;
  189. }
  190. $this->_eventSignal[$fd_key] = $event;
  191. return true;
  192. }
  193. /**
  194. * {@inheritdoc}
  195. */
  196. public function offSignal($signal)
  197. {
  198. $fd_key = (int)$signal;
  199. if (isset($this->_eventSignal[$fd_key])) {
  200. $this->_eventSignal[$fd_key]->del();
  201. unset($this->_eventSignal[$fd_key]);
  202. }
  203. }
  204. /**
  205. * {@inheritdoc}
  206. */
  207. public function deleteAllTimer()
  208. {
  209. foreach ($this->_eventTimer as $event) {
  210. $event->del();
  211. }
  212. $this->_eventTimer = [];
  213. }
  214. /**
  215. * {@inheritdoc}
  216. */
  217. public function run()
  218. {
  219. $this->_eventBase->loop();
  220. }
  221. /**
  222. * {@inheritdoc}
  223. */
  224. public function stop()
  225. {
  226. $this->_eventBase->exit();
  227. }
  228. /**
  229. * {@inheritdoc}
  230. */
  231. public function getTimerCount()
  232. {
  233. return \count($this->_eventTimer);
  234. }
  235. }