Swoole.php 4.2 KB

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