Select.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace Workerman\Events;
  3. class Select implements EventInterface
  4. {
  5. /**
  6. * all events
  7. * @var array
  8. */
  9. public $_allEvents = array();
  10. /**
  11. * all signal events
  12. * @var array
  13. */
  14. public $_signalEvents = array();
  15. /**
  16. * read fds
  17. * @var array
  18. */
  19. protected $_readFds = array();
  20. /**
  21. * write fds
  22. * @var array
  23. */
  24. protected $_writeFds = array();
  25. /**
  26. * construct
  27. * @return void
  28. */
  29. public function __construct()
  30. {
  31. $this->channel = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
  32. if($this->channel)
  33. {
  34. stream_set_blocking($this->channel[0], 0);
  35. $this->_readFds[0] = $this->channel[0];
  36. }
  37. }
  38. /**
  39. * add
  40. * @see Events\EventInterface::add()
  41. */
  42. public function add($fd, $flag, $func)
  43. {
  44. // key
  45. $fd_key = (int)$fd;
  46. switch ($flag)
  47. {
  48. case self::EV_READ:
  49. $this->_allEvents[$fd_key][$flag] = array($func, $fd);
  50. $this->_readFds[$fd_key] = $fd;
  51. break;
  52. case self::EV_WRITE:
  53. $this->_allEvents[$fd_key][$flag] = array($func, $fd);
  54. $this->_writeFds[$fd_key] = $fd;
  55. break;
  56. case self::EV_SIGNAL:
  57. $this->_signalEvents[$fd_key][$flag] = array($func, $fd);
  58. pcntl_signal($fd, array($this, 'signalHandler'));
  59. break;
  60. }
  61. return true;
  62. }
  63. /**
  64. * signal handler
  65. * @param int $signal
  66. */
  67. public function signalHandler($signal)
  68. {
  69. call_user_func_array($this->_signalEvents[$signal][self::EV_SIGNAL][0], array($signal));
  70. }
  71. /**
  72. * del
  73. * @see Events\EventInterface::del()
  74. */
  75. public function del($fd ,$flag)
  76. {
  77. $fd_key = (int)$fd;
  78. switch ($flag)
  79. {
  80. case self::EV_READ:
  81. unset($this->_allEvents[$fd_key][$flag], $this->_readFds[$fd_key]);
  82. if(empty($this->_allEvents[$fd_key]))
  83. {
  84. unset($this->_allEvents[$fd_key]);
  85. }
  86. break;
  87. case self::EV_WRITE:
  88. unset($this->_allEvents[$fd_key][$flag], $this->_writeFds[$fd_key]);
  89. if(empty($this->_allEvents[$fd_key]))
  90. {
  91. unset($this->_allEvents[$fd_key]);
  92. }
  93. break;
  94. case self::EV_SIGNAL:
  95. unset($this->_signalEvents[$fd_key]);
  96. pcntl_signal($fd, SIG_IGN);
  97. break;
  98. }
  99. return true;
  100. }
  101. /**
  102. * main loop
  103. * @see Events\EventInterface::loop()
  104. */
  105. public function loop()
  106. {
  107. $e = null;
  108. while (1)
  109. {
  110. // calls signal handlers for pending signals
  111. pcntl_signal_dispatch();
  112. //
  113. $read = $this->_readFds;
  114. $write = $this->_writeFds;
  115. // waits for $read and $write to change status
  116. if(!@stream_select($read, $write, $e, 60))
  117. {
  118. // maybe interrupt by sianals, so calls signal handlers for pending signals
  119. pcntl_signal_dispatch();
  120. continue;
  121. }
  122. // read
  123. if($read)
  124. {
  125. foreach($read as $fd)
  126. {
  127. $fd_key = (int) $fd;
  128. if(isset($this->_allEvents[$fd_key][self::EV_READ]))
  129. {
  130. call_user_func_array($this->_allEvents[$fd_key][self::EV_READ][0], array($this->_allEvents[$fd_key][self::EV_READ][1]));
  131. }
  132. }
  133. }
  134. // write
  135. if($write)
  136. {
  137. foreach($write as $fd)
  138. {
  139. $fd_key = (int) $fd;
  140. if(isset($this->_allEvents[$fd_key][self::EV_WRITE]))
  141. {
  142. call_user_func_array($this->_allEvents[$fd_key][self::EV_WRITE][0], array($this->_allEvents[$fd_key][self::EV_WRITE][1]));
  143. }
  144. }
  145. }
  146. }
  147. }
  148. }