ExtEventLoop.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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\React;
  15. use Workerman\Events\EventInterface;
  16. /**
  17. * Class ExtEventLoop
  18. * @package Workerman\Events\React
  19. */
  20. class ExtEventLoop extends \React\EventLoop\ExtEventLoop
  21. {
  22. /**
  23. * Event base.
  24. *
  25. * @var EventBase
  26. */
  27. protected $_eventBase = null;
  28. /**
  29. * All signal Event instances.
  30. *
  31. * @var array
  32. */
  33. protected $_signalEvents = array();
  34. /**
  35. * @var array
  36. */
  37. protected $_timerIdMap = array();
  38. /**
  39. * @var int
  40. */
  41. protected $_timerIdIndex = 0;
  42. /**
  43. * Add event listener to event loop.
  44. *
  45. * @param $fd
  46. * @param $flag
  47. * @param $func
  48. * @param array $args
  49. * @return bool
  50. */
  51. public function add($fd, $flag, $func, $args = array())
  52. {
  53. $args = (array)$args;
  54. switch ($flag) {
  55. case EventInterface::EV_READ:
  56. return $this->addReadStream($fd, $func);
  57. case EventInterface::EV_WRITE:
  58. return $this->addWriteStream($fd, $func);
  59. case EventInterface::EV_SIGNAL:
  60. return $this->addSignal($fd, $func);
  61. case EventInterface::EV_TIMER:
  62. $timer_obj = $this->addPeriodicTimer($fd, function() use ($func, $args) {
  63. call_user_func_array($func, $args);
  64. });
  65. $this->_timerIdMap[++$this->_timerIdIndex] = $timer_obj;
  66. return $this->_timerIdIndex;
  67. case EventInterface::EV_TIMER_ONCE:
  68. $timer_obj = $this->addTimer($fd, function() use ($func, $args) {
  69. call_user_func_array($func, $args);
  70. });
  71. $this->_timerIdMap[++$this->_timerIdIndex] = $timer_obj;
  72. return $this->_timerIdIndex;
  73. }
  74. return false;
  75. }
  76. /**
  77. * Remove event listener from event loop.
  78. *
  79. * @param mixed $fd
  80. * @param int $flag
  81. * @return bool
  82. */
  83. public function del($fd, $flag)
  84. {
  85. switch ($flag) {
  86. case EventInterface::EV_READ:
  87. return $this->removeReadStream($fd);
  88. case EventInterface::EV_WRITE:
  89. return $this->removeWriteStream($fd);
  90. case EventInterface::EV_SIGNAL:
  91. return $this->removeSignal($fd);
  92. case EventInterface::EV_TIMER:
  93. case EventInterface::EV_TIMER_ONCE;
  94. if (isset($this->_timerIdMap[$fd])){
  95. $timer_obj = $this->_timerIdMap[$fd];
  96. unset($this->_timerIdMap[$fd]);
  97. $this->cancelTimer($timer_obj);
  98. return true;
  99. }
  100. }
  101. return false;
  102. }
  103. /**
  104. * Main loop.
  105. *
  106. * @return void
  107. */
  108. public function loop()
  109. {
  110. $this->run();
  111. }
  112. /**
  113. * Construct
  114. */
  115. public function __construct()
  116. {
  117. parent::__construct();
  118. $class = new \ReflectionClass('\React\EventLoop\ExtEventLoop');
  119. $property = $class->getProperty('eventBase');
  120. $property->setAccessible(true);
  121. $this->_eventBase = $property->getValue($this);
  122. }
  123. /**
  124. * Add signal handler.
  125. *
  126. * @param $signal
  127. * @param $callback
  128. * @return bool
  129. */
  130. public function addSignal($signal, $callback)
  131. {
  132. $event = \Event::signal($this->_eventBase, $signal, $callback);
  133. if (!$event||!$event->add()) {
  134. return false;
  135. }
  136. $this->_signalEvents[$signal] = $event;
  137. }
  138. /**
  139. * Remove signal handler.
  140. *
  141. * @param $signal
  142. */
  143. public function removeSignal($signal)
  144. {
  145. if (isset($this->_signalEvents[$signal])) {
  146. $this->_signalEvents[$signal]->del();
  147. unset($this->_signalEvents[$signal]);
  148. }
  149. }
  150. /**
  151. * Destroy loop.
  152. *
  153. * @return void
  154. */
  155. public function destroy()
  156. {
  157. foreach ($this->_signalEvents as $event) {
  158. $event->del();
  159. }
  160. }
  161. }