LibEventLoop.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 LibEventLoop
  18. * @package Workerman\Events\React
  19. */
  20. class LibEventLoop extends \React\EventLoop\LibEventLoop
  21. {
  22. /**
  23. * Event base.
  24. *
  25. * @var event_base resource
  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_id = ++$this->_timerIdIndex;
  63. $timer_obj = $this->addPeriodicTimer($fd, function() use ($func, $args) {
  64. call_user_func_array($func, $args);
  65. });
  66. $this->_timerIdMap[$timer_id] = $timer_obj;
  67. return $timer_id;
  68. case EventInterface::EV_TIMER_ONCE:
  69. $timer_id = ++$this->_timerIdIndex;
  70. $timer_obj = $this->addTimer($fd, function() use ($func, $args, $timer_id) {
  71. unset($this->_timerIdMap[$timer_id]);
  72. call_user_func_array($func, $args);
  73. });
  74. $this->_timerIdMap[$timer_id] = $timer_obj;
  75. return $timer_id;
  76. }
  77. return false;
  78. }
  79. /**
  80. * Remove event listener from event loop.
  81. *
  82. * @param mixed $fd
  83. * @param int $flag
  84. * @return bool
  85. */
  86. public function del($fd, $flag)
  87. {
  88. switch ($flag) {
  89. case EventInterface::EV_READ:
  90. return $this->removeReadStream($fd);
  91. case EventInterface::EV_WRITE:
  92. return $this->removeWriteStream($fd);
  93. case EventInterface::EV_SIGNAL:
  94. return $this->removeSignal($fd);
  95. case EventInterface::EV_TIMER:
  96. case EventInterface::EV_TIMER_ONCE;
  97. if (isset($this->_timerIdMap[$fd])){
  98. $timer_obj = $this->_timerIdMap[$fd];
  99. unset($this->_timerIdMap[$fd]);
  100. $this->cancelTimer($timer_obj);
  101. return true;
  102. }
  103. }
  104. return false;
  105. }
  106. /**
  107. * Main loop.
  108. *
  109. * @return void
  110. */
  111. public function loop()
  112. {
  113. $this->run();
  114. }
  115. /**
  116. * Construct.
  117. */
  118. public function __construct()
  119. {
  120. parent::__construct();
  121. $class = new \ReflectionClass('\React\EventLoop\LibEventLoop');
  122. $property = $class->getProperty('eventBase');
  123. $property->setAccessible(true);
  124. $this->_eventBase = $property->getValue($this);
  125. }
  126. /**
  127. * Add signal handler.
  128. *
  129. * @param $signal
  130. * @param $callback
  131. * @return bool
  132. */
  133. public function addSignal($signal, $callback)
  134. {
  135. $event = event_new();
  136. $this->_signalEvents[$signal] = $event;
  137. event_set($event, $signal, EV_SIGNAL | EV_PERSIST, $callback);
  138. event_base_set($event, $this->_eventBase);
  139. event_add($event);
  140. }
  141. /**
  142. * Remove signal handler.
  143. *
  144. * @param $signal
  145. */
  146. public function removeSignal($signal)
  147. {
  148. if (isset($this->_signalEvents[$signal])) {
  149. $event = $this->_signalEvents[$signal];
  150. event_del($event);
  151. unset($this->_signalEvents[$signal]);
  152. }
  153. }
  154. /**
  155. * Destroy loop.
  156. *
  157. * @return void
  158. */
  159. public function destroy()
  160. {
  161. foreach ($this->_signalEvents as $event) {
  162. event_del($event);
  163. }
  164. }
  165. /**
  166. * Get timer count.
  167. *
  168. * @return integer
  169. */
  170. public function getTimerCount()
  171. {
  172. return count($this->_timerIdMap);
  173. }
  174. }