Swoole.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 Ares<aresrr#qq.com>
  10. * @link http://www.workerman.net/
  11. * @link https://github.com/ares333/Workerman
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Workerman\Events;
  15. use Swoole\Event;
  16. use Swoole\Timer;
  17. use Swoole\Process;
  18. class Swoole implements EventInterface
  19. {
  20. protected $_timer = array();
  21. protected $_timerOnceMap = array();
  22. protected $_fd = array();
  23. // milisecond
  24. public static $signalDispatchInterval = 200;
  25. protected $_hasSignal = false;
  26. /**
  27. *
  28. * {@inheritdoc}
  29. *
  30. * @see \Workerman\Events\EventInterface::add()
  31. */
  32. public function add($fd, $flag, $func, $args = null)
  33. {
  34. if (! isset($args)) {
  35. $args = array();
  36. }
  37. switch ($flag) {
  38. case self::EV_SIGNAL:
  39. $res = pcntl_signal($fd, $func, false);
  40. if (! $this->_hasSignal && $res) {
  41. Timer::tick(static::$signalDispatchInterval,
  42. function () {
  43. pcntl_signal_dispatch();
  44. });
  45. $this->_hasSignal = true;
  46. }
  47. return $res;
  48. case self::EV_TIMER:
  49. case self::EV_TIMER_ONCE:
  50. $method = self::EV_TIMER == $flag ? 'tick' : 'after';
  51. $mapId = count($this->_timerOnceMap);
  52. $timer_id = Timer::$method($fd * 1000,
  53. function ($timer_id = null) use ($func, $args, $mapId) {
  54. call_user_func_array($func, $args);
  55. // EV_TIMER_ONCE
  56. if (! isset($timer_id)) {
  57. //may be deleted in $func
  58. if (array_key_exists($mapId, $this->_timerOnceMap)) {
  59. $timer_id = $this->_timerOnceMap[$mapId];
  60. unset($this->_timer[$timer_id],
  61. $this->_timerOnceMap[$mapId]);
  62. }
  63. }
  64. });
  65. if ($flag == self::EV_TIMER_ONCE) {
  66. $this->_timerOnceMap[$mapId] = $timer_id;
  67. $this->_timer[$timer_id] = $mapId;
  68. } else {
  69. $this->_timer[$timer_id] = null;
  70. }
  71. return $timer_id;
  72. case self::EV_READ:
  73. case self::EV_WRITE:
  74. if ($flag == self::EV_READ) {
  75. $res = Event::add($fd, $func, null, SWOOLE_EVENT_READ);
  76. } else {
  77. $res = Event::add($fd, null, $func, SWOOLE_EVENT_WRITE);
  78. }
  79. if (! in_array((int) $fd, $this->_fd) && $res) {
  80. $this->_fd[] = (int) $fd;
  81. }
  82. return $res;
  83. }
  84. }
  85. /**
  86. *
  87. * {@inheritdoc}
  88. *
  89. * @see \Workerman\Events\EventInterface::del()
  90. */
  91. public function del($fd, $flag)
  92. {
  93. switch ($flag) {
  94. case self::EV_SIGNAL:
  95. return pcntl_signal($fd, SIG_IGN, false);
  96. case self::EV_TIMER:
  97. case self::EV_TIMER_ONCE:
  98. // already remove in EV_TIMER_ONCE callback.
  99. if (! array_key_exists($fd, $this->_timer)) {
  100. return true;
  101. }
  102. $res = Timer::clear($fd);
  103. if ($res) {
  104. $mapId = $this->_timer[$fd];
  105. if (isset($mapId)) {
  106. unset($this->_timerOnceMap[$mapId]);
  107. }
  108. unset($this->_timer[$fd]);
  109. }
  110. return $res;
  111. case self::EV_READ:
  112. case self::EV_WRITE:
  113. $key = array_search((int) $fd, $this->_fd);
  114. if (false !== $key) {
  115. $res = Event::del($fd);
  116. if ($res) {
  117. unset($this->_fd[$key]);
  118. }
  119. return $res;
  120. }
  121. }
  122. }
  123. /**
  124. *
  125. * {@inheritdoc}
  126. *
  127. * @see \Workerman\Events\EventInterface::clearAllTimer()
  128. */
  129. public function clearAllTimer()
  130. {
  131. foreach (array_keys($this->_timer) as $v) {
  132. Timer::clear($v);
  133. }
  134. $this->_timer = array();
  135. $this->_timerOnceMap = array();
  136. }
  137. /**
  138. *
  139. * {@inheritdoc}
  140. *
  141. * @see \Workerman\Events\EventInterface::loop()
  142. */
  143. public function loop()
  144. {
  145. Event::wait();
  146. }
  147. /**
  148. *
  149. * {@inheritdoc}
  150. *
  151. * @see \Workerman\Events\EventInterface::destroy()
  152. */
  153. public function destroy()
  154. {
  155. Event::exit();
  156. }
  157. /**
  158. *
  159. * {@inheritdoc}
  160. *
  161. * @see \Workerman\Events\EventInterface::getTimerCount()
  162. */
  163. public function getTimerCount()
  164. {
  165. return count($this->_timer);
  166. }
  167. }