ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Loop.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Sabre\Event\Loop;
4 
18 class Loop {
19 
27  function setTimeout(callable $cb, $timeout) {
28 
29  $triggerTime = microtime(true) + ($timeout);
30 
31  if (!$this->timers) {
32  // Special case when the timers array was empty.
33  $this->timers[] = [$triggerTime, $cb];
34  return;
35  }
36 
37  // We need to insert these values in the timers array, but the timers
38  // array must be in reverse-order of trigger times.
39  //
40  // So here we search the array for the insertion point.
41  $index = count($this->timers) - 1;
42  while (true) {
43  if ($triggerTime < $this->timers[$index][0]) {
44  array_splice(
45  $this->timers,
46  $index + 1,
47  0,
48  [[$triggerTime, $cb]]
49  );
50  break;
51  } elseif ($index === 0) {
52  array_unshift($this->timers, [$triggerTime, $cb]);
53  break;
54  }
55  $index--;
56 
57  }
58 
59  }
60 
71  function setInterval(callable $cb, $timeout) {
72 
73  $keepGoing = true;
74  $f = null;
75 
76  $f = function() use ($cb, &$f, $timeout, &$keepGoing) {
77  if ($keepGoing) {
78  $cb();
79  $this->setTimeout($f, $timeout);
80  }
81  };
82  $this->setTimeout($f, $timeout);
83 
84  // Really the only thing that matters is returning the $keepGoing
85  // boolean value.
86  //
87  // We need to pack it in an array to allow returning by reference.
88  // Because I'm worried people will be confused by using a boolean as a
89  // sort of identifier, I added an extra string.
90  return ['I\'m an implementation detail', &$keepGoing];
91 
92  }
93 
100  function clearInterval($intervalId) {
101 
102  $intervalId[1] = false;
103 
104  }
105 
112  function nextTick(callable $cb) {
113 
114  $this->nextTick[] = $cb;
115 
116  }
117 
118 
132  function addReadStream($stream, callable $cb) {
133 
134  $this->readStreams[(int)$stream] = $stream;
135  $this->readCallbacks[(int)$stream] = $cb;
136 
137  }
138 
152  function addWriteStream($stream, callable $cb) {
153 
154  $this->writeStreams[(int)$stream] = $stream;
155  $this->writeCallbacks[(int)$stream] = $cb;
156 
157  }
158 
166 
167  unset(
168  $this->readStreams[(int)$stream],
169  $this->readCallbacks[(int)$stream]
170  );
171 
172  }
173 
181 
182  unset(
183  $this->writeStreams[(int)$stream],
184  $this->writeCallbacks[(int)$stream]
185  );
186 
187  }
188 
189 
198  function run() {
199 
200  $this->running = true;
201 
202  do {
203 
204  $hasEvents = $this->tick(true);
205 
206  } while ($this->running && $hasEvents);
207  $this->running = false;
208 
209  }
210 
226  function tick($block = false) {
227 
228  $this->runNextTicks();
229  $nextTimeout = $this->runTimers();
230 
231  // Calculating how long runStreams should at most wait.
232  if (!$block) {
233  // Don't wait
234  $streamWait = 0;
235  } elseif ($this->nextTick) {
236  // There's a pending 'nextTick'. Don't wait.
237  $streamWait = 0;
238  } elseif (is_numeric($nextTimeout)) {
239  // Wait until the next Timeout should trigger.
240  $streamWait = $nextTimeout;
241  } else {
242  // Wait indefinitely
243  $streamWait = null;
244  }
245 
246  $this->runStreams($streamWait);
247 
248  return ($this->readStreams || $this->writeStreams || $this->nextTick || $this->timers);
249 
250  }
251 
257  function stop() {
258 
259  $this->running = false;
260 
261  }
262 
268  protected function runNextTicks() {
269 
271  $this->nextTick = [];
272 
273  foreach ($nextTick as $cb) {
274  $cb();
275  }
276 
277  }
278 
289  protected function runTimers() {
290 
291  $now = microtime(true);
292  while (($timer = array_pop($this->timers)) && $timer[0] < $now) {
293  $timer[1]();
294  }
295  // Add the last timer back to the array.
296  if ($timer) {
297  $this->timers[] = $timer;
298  return $timer[0] - microtime(true);
299  }
300 
301  }
302 
308  protected function runStreams($timeout) {
309 
310  if ($this->readStreams || $this->writeStreams) {
311 
312  $read = $this->readStreams;
313  $write = $this->writeStreams;
314  $except = null;
315  if (stream_select($read, $write, $except, null, $timeout)) {
316 
317  // See PHP Bug https://bugs.php.net/bug.php?id=62452
318  // Fixed in PHP7
319  foreach ($read as $readStream) {
320  $readCb = $this->readCallbacks[(int)$readStream];
321  $readCb();
322  }
323  foreach ($write as $writeStream) {
324  $writeCb = $this->writeCallbacks[(int)$writeStream];
325  $writeCb();
326  }
327 
328  }
329 
330  } elseif ($this->running && ($this->nextTick || $this->timers)) {
331  usleep($timeout !== null ? $timeout * 1000000 : 200000);
332  }
333 
334  }
335 
341  protected $running = false;
342 
348  protected $timers = [];
349 
355  protected $nextTick = [];
356 
362  protected $readStreams = [];
363 
369  protected $writeStreams = [];
370 
376  protected $readCallbacks = [];
377 
383  protected $writeCallbacks = [];
384 
385 
386 }
clearInterval($intervalId)
Stops a running internval.
Definition: Loop.php:100
removeWriteStream($stream)
Stop watching a stream for writes.
Definition: Loop.php:180
addReadStream($stream, callable $cb)
Adds a read stream.
Definition: Loop.php:132
tick($block=false)
Executes all pending events.
Definition: Loop.php:226
nextTick(callable $cb)
Runs a function immediately at the next iteration of the loop.
Definition: Loop.php:112
setInterval(callable $cb, $timeout)
Executes a function every x seconds.
Definition: Loop.php:71
removeReadStream($stream)
Stop watching a stream for reads.
Definition: Loop.php:165
$index
Definition: metadata.php:60
runTimers()
Runs all pending timers.
Definition: Loop.php:289
$stream
PHP stream implementation.
runNextTicks()
Executes all &#39;nextTick&#39; callbacks.
Definition: Loop.php:268
stop()
Stops a running eventloop.
Definition: Loop.php:257
addWriteStream($stream, callable $cb)
Adds a write stream.
Definition: Loop.php:152
run()
Runs the loop.
Definition: Loop.php:198
setTimeout(callable $cb, $timeout)
Executes a function after x seconds.
Definition: Loop.php:27
runStreams($timeout)
Runs all pending stream events.
Definition: Loop.php:308
A simple eventloop implementation.
Definition: Loop.php:18