Libevent.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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;
  15. /**
  16. * libevent eventloop
  17. */
  18. class Libevent implements EventInterface
  19. {
  20. /**
  21. * Event base.
  22. * @var resource
  23. */
  24. protected $_eventBase = null;
  25. /**
  26. * All listeners for read/write event.
  27. * @var array
  28. */
  29. protected $_allEvents = array();
  30. /**
  31. * Event listeners of signal.
  32. * @var array
  33. */
  34. protected $_eventSignal = array();
  35. /**
  36. * All timer event listeners.
  37. * [func, args, event, flag, time_interval]
  38. * @var array
  39. */
  40. protected $_eventTimer = array();
  41. /**
  42. * construct
  43. */
  44. public function __construct()
  45. {
  46. $this->_eventBase = event_base_new();
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function add($fd, $flag, $func, $args=array())
  52. {
  53. switch($flag)
  54. {
  55. case self::EV_SIGNAL:
  56. $fd_key = (int)$fd;
  57. $real_flag = EV_SIGNAL | EV_PERSIST;
  58. $this->_eventSignal[$fd_key] = event_new();
  59. if(!event_set($this->_eventSignal[$fd_key], $fd, $real_flag, $func, null))
  60. {
  61. return false;
  62. }
  63. if(!event_base_set($this->_eventSignal[$fd_key], $this->_eventBase))
  64. {
  65. return false;
  66. }
  67. if(!event_add($this->_eventSignal[$fd_key]))
  68. {
  69. return false;
  70. }
  71. return true;
  72. case self::EV_TIMER:
  73. case self::EV_TIMER_ONCE:
  74. $event = event_new();
  75. $timer_id = (int)$event;
  76. if(!event_set($event, 0, EV_TIMEOUT, array($this, 'timerCallback'), $timer_id))
  77. {
  78. return false;
  79. }
  80. if(!event_base_set($event, $this->_eventBase))
  81. {
  82. return false;
  83. }
  84. $time_interval = $fd*1000000;
  85. if(!event_add($event, $time_interval))
  86. {
  87. return false;
  88. }
  89. $this->_eventTimer[$timer_id] = array($func, (array)$args, $event, $flag, $time_interval);
  90. return $timer_id;
  91. default :
  92. $fd_key = (int)$fd;
  93. $real_flag = $flag === self::EV_READ ? EV_READ | EV_PERSIST : EV_WRITE | EV_PERSIST;
  94. $event = event_new();
  95. if(!event_set($event, $fd, $real_flag, $func, null))
  96. {
  97. return false;
  98. }
  99. if(!event_base_set($event, $this->_eventBase))
  100. {
  101. return false;
  102. }
  103. if(!event_add($event))
  104. {
  105. return false;
  106. }
  107. $this->_allEvents[$fd_key][$flag] = $event;
  108. return true;
  109. }
  110. }
  111. /**
  112. * {@inheritdoc}
  113. */
  114. public function del($fd ,$flag)
  115. {
  116. switch($flag)
  117. {
  118. case self::EV_READ:
  119. case self::EV_WRITE:
  120. $fd_key = (int)$fd;
  121. if(isset($this->_allEvents[$fd_key][$flag]))
  122. {
  123. event_del($this->_allEvents[$fd_key][$flag]);
  124. unset($this->_allEvents[$fd_key][$flag]);
  125. }
  126. if(empty($this->_allEvents[$fd_key]))
  127. {
  128. unset($this->_allEvents[$fd_key]);
  129. }
  130. break;
  131. case self::EV_SIGNAL:
  132. $fd_key = (int)$fd;
  133. if(isset($this->_eventSignal[$fd_key]))
  134. {
  135. event_del($this->_eventSignal[$fd_key]);
  136. unset($this->_eventSignal[$fd_key]);
  137. }
  138. break;
  139. case self::EV_TIMER:
  140. case self::EV_TIMER_ONCE:
  141. // 这里 fd 为timerid
  142. if(isset($this->_eventTimer[$fd]))
  143. {
  144. event_del($this->_eventTimer[$fd][2]);
  145. unset($this->_eventTimer[$fd]);
  146. }
  147. break;
  148. }
  149. return true;
  150. }
  151. /**
  152. * Timer callback.
  153. * @param mixed $_null1
  154. * @param int $_null2
  155. * @param mixed $timer_id
  156. */
  157. protected function timerCallback($_null1, $_null2, $timer_id)
  158. {
  159. if($this->_eventTimer[$timer_id][3] === self::EV_TIMER)
  160. {
  161. event_add($this->_eventTimer[$timer_id][2], $this->_eventTimer[$timer_id][4]);
  162. }
  163. try
  164. {
  165. call_user_func_array($this->_eventTimer[$timer_id][0], $this->_eventTimer[$timer_id][1]);
  166. }
  167. catch(\Exception $e)
  168. {
  169. echo $e;
  170. exit(250);
  171. }
  172. if(isset($this->_eventTimer[$timer_id]) && $this->_eventTimer[$timer_id][3] === self::EV_TIMER_ONCE)
  173. {
  174. $this->del($timer_id, self::EV_TIMER_ONCE);
  175. }
  176. }
  177. /**
  178. * {@inheritdoc}
  179. */
  180. public function clearAllTimer()
  181. {
  182. foreach($this->_eventTimer as $task_data)
  183. {
  184. event_del($task_data[2]);
  185. }
  186. $this->_eventTimer = array();
  187. }
  188. /**
  189. * {@inheritdoc}
  190. */
  191. public function loop()
  192. {
  193. event_base_loop($this->_eventBase);
  194. }
  195. }