Swoole.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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 $_fd = array();
  22. // milisecond
  23. public static $signalDispatchInterval = 200;
  24. // Swoole\Process::signal() is not stable in some version of php and swoole.
  25. // The problem may be caused by using pcntl_signal() and pcntl_fork() and Swoole\Process::signal() together.
  26. protected $_hasSignal = false;
  27. /**
  28. *
  29. * {@inheritdoc}
  30. *
  31. * @see \Workerman\Events\EventInterface::add()
  32. */
  33. public function add($fd, $flag, $func, $args = null)
  34. {
  35. if (! isset($args)) {
  36. $args = array();
  37. }
  38. switch ($flag) {
  39. case self::EV_SIGNAL:
  40. if (isset(static::$signalDispatchInterval)) {
  41. $res = pcntl_signal($fd, $func, false);
  42. if (! $this->_hasSignal && $res) {
  43. Timer::tick(static::$signalDispatchInterval,
  44. function () {
  45. pcntl_signal_dispatch();
  46. });
  47. $this->_hasSignal = true;
  48. }
  49. return $res;
  50. } else {
  51. return Process::signal($fd, $func);
  52. }
  53. case self::EV_TIMER:
  54. case self::EV_TIMER_ONCE:
  55. $method = self::EV_TIMER == $flag ? 'tick' : 'after';
  56. $timer_id = Timer::$method($fd * 1000,
  57. function ($timer_id = null) use ($func, $args) {
  58. call_user_func_array($func, $args);
  59. });
  60. $this->_timer[] = $timer_id;
  61. return $timer_id;
  62. case self::EV_READ:
  63. case self::EV_WRITE:
  64. if ($flag == self::EV_READ) {
  65. $res = Event::add($fd, $func, null, SWOOLE_EVENT_READ);
  66. } else {
  67. $res = Event::add($fd, null, $func, SWOOLE_EVENT_WRITE);
  68. }
  69. if (! in_array((int) $fd, $this->_fd) && $res) {
  70. $this->_fd[] = (int) $fd;
  71. }
  72. return $res;
  73. }
  74. }
  75. /**
  76. *
  77. * {@inheritdoc}
  78. *
  79. * @see \Workerman\Events\EventInterface::del()
  80. */
  81. public function del($fd, $flag)
  82. {
  83. switch ($flag) {
  84. case self::EV_SIGNAL:
  85. if (isset(static::$signalDispatchInterval)) {
  86. return pcntl_signal($fd, SIG_IGN, false);
  87. } else {
  88. return Process::signal($fd, null);
  89. }
  90. case self::EV_TIMER:
  91. case self::EV_TIMER_ONCE:
  92. return Timer::clear($fd);
  93. case self::EV_READ:
  94. case self::EV_WRITE:
  95. $key = array_search((int) $fd, $this->_fd);
  96. if (false !== $key) {
  97. $res = Event::del($fd);
  98. if ($res) {
  99. unset($this->_fd[$key]);
  100. }
  101. return $res;
  102. }
  103. }
  104. }
  105. /**
  106. *
  107. * {@inheritdoc}
  108. *
  109. * @see \Workerman\Events\EventInterface::clearAllTimer()
  110. */
  111. public function clearAllTimer()
  112. {
  113. foreach ($this->_timer as $v) {
  114. Timer::clear($v);
  115. }
  116. $this->_timer = array();
  117. }
  118. /**
  119. *
  120. * {@inheritdoc}
  121. *
  122. * @see \Workerman\Events\EventInterface::loop()
  123. */
  124. public function loop()
  125. {
  126. Event::wait();
  127. }
  128. /**
  129. *
  130. * {@inheritdoc}
  131. *
  132. * @see \Workerman\Events\EventInterface::destroy()
  133. */
  134. public function destroy()
  135. {
  136. Event::exit();
  137. }
  138. /**
  139. *
  140. * {@inheritdoc}
  141. *
  142. * @see \Workerman\Events\EventInterface::getTimerCount()
  143. */
  144. public function getTimerCount()
  145. {
  146. return count($this->_timer);
  147. }
  148. }