Skip to content

Commit a8ab844

Browse files
committed
Reduced method dispatching somewhat.
1 parent ada50c5 commit a8ab844

File tree

3 files changed

+74
-122
lines changed

3 files changed

+74
-122
lines changed

AbstractNextTickLoop.php

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public function nextTick(callable $listener)
3838
*/
3939
public function tick()
4040
{
41+
$this->nextTickQueue->tick();
42+
4143
$this->tickLogic(false);
4244
}
4345

@@ -49,7 +51,11 @@ public function run()
4951
$this->explicitlyStopped = false;
5052

5153
while ($this->isRunning()) {
52-
$this->tickLogic(true);
54+
$this->nextTickQueue->tick();
55+
56+
$this->tickLogic(
57+
$this->nextTickQueue->isEmpty()
58+
);
5359
}
5460
}
5561

@@ -80,24 +86,12 @@ protected function isRunning()
8086
return !$this->isEmpty();
8187
}
8288

83-
/**
84-
* Perform the low-level tick logic.
85-
*/
86-
protected function tickLogic($blocking)
87-
{
88-
$this->nextTickQueue->tick();
89-
90-
$this->flushEvents(
91-
$blocking && $this->nextTickQueue->isEmpty()
92-
);
93-
}
94-
9589
/**
9690
* Flush any timer and IO events.
9791
*
9892
* @param boolean $blocking True if loop should block waiting for next event.
9993
*/
100-
abstract protected function flushEvents($blocking);
94+
abstract protected function tickLogic($blocking);
10195

10296
/**
10397
* Check if the loop has any pending timers or streams.

ExtEventLoop.php

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,11 @@ public function cancelTimer(TimerInterface $timer)
154154
{
155155
if ($this->isTimerActive($timer)) {
156156
$entry = $this->timerEvents[$timer];
157+
157158
$this->timerEvents->detach($timer);
159+
158160
$entry->event->free();
161+
159162
$this->keepAlive[] = $entry->callback;
160163
}
161164
}
@@ -177,7 +180,7 @@ public function isTimerActive(TimerInterface $timer)
177180
*
178181
* @param boolean $blocking True if loop should block waiting for next event.
179182
*/
180-
protected function flushEvents($blocking)
183+
protected function tickLogic($blocking)
181184
{
182185
$flags = EventBase::LOOP_ONCE;
183186

@@ -201,44 +204,6 @@ protected function isEmpty()
201204
&& 0 === count($this->streamEvents);
202205
}
203206

204-
/**
205-
* Dispatch a timer event.
206-
*
207-
* @param TimerInterface $timer
208-
*/
209-
protected function onTimerTick(TimerInterface $timer)
210-
{
211-
call_user_func($timer->getCallback(), $timer);
212-
213-
// Clean-up one shot timers ...
214-
if ($this->isTimerActive($timer) && !$timer->isPeriodic()) {
215-
$this->cancelTimer($timer);
216-
}
217-
}
218-
219-
/**
220-
* Dispatch a stream event.
221-
*
222-
* @param stdClass $entry The entry from $this->streamEvents
223-
* @param stream $stream
224-
* @param integer $flags Bitwise flags indicating event type (Event::READ/Event::WRITE)
225-
*/
226-
protected function onStreamEvent($entry, $stream, $flags)
227-
{
228-
foreach ([Event::READ, Event::WRITE] as $flag) {
229-
if (
230-
$flag === ($flags & $flag) &&
231-
is_callable($entry->listeners[$flag])
232-
) {
233-
call_user_func(
234-
$entry->listeners[$flag],
235-
$stream,
236-
$this
237-
);
238-
}
239-
}
240-
}
241-
242207
/**
243208
* Schedule a timer for execution.
244209
*
@@ -254,7 +219,12 @@ protected function scheduleTimer(TimerInterface $timer)
254219

255220
$entry = new stdClass;
256221
$entry->callback = function () use ($timer) {
257-
$this->onTimerTick($timer);
222+
call_user_func($timer->getCallback(), $timer);
223+
224+
// Clean-up one shot timers ...
225+
if ($this->isTimerActive($timer) && !$timer->isPeriodic()) {
226+
$this->cancelTimer($timer);
227+
}
258228
};
259229

260230
$entry->event = new Event(
@@ -284,16 +254,28 @@ protected function addStreamEvent($stream, $flag, $listener)
284254
$entry = $this->streamEvents[$key];
285255
} else {
286256
$entry = new stdClass;
287-
$entry->callback = function ($stream, $flags, $loop) use ($entry) {
288-
$this->onStreamEvent($entry, $stream, $flags);
289-
};
290257
$entry->event = null;
291258
$entry->flags = 0;
292259
$entry->listeners = [
293260
Event::READ => null,
294261
Event::WRITE => null,
295262
];
296263

264+
$entry->callback = function ($stream, $flags, $loop) use ($entry) {
265+
foreach ([Event::READ, Event::WRITE] as $flag) {
266+
if (
267+
$flag === ($flags & $flag) &&
268+
is_callable($entry->listeners[$flag])
269+
) {
270+
call_user_func(
271+
$entry->listeners[$flag],
272+
$stream,
273+
$this
274+
);
275+
}
276+
}
277+
};
278+
297279
$this->streamEvents[$key] = $entry;
298280
}
299281

StreamSelectNextTickLoop.php

Lines changed: 41 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,10 @@ public function isTimerActive(TimerInterface $timer)
162162
*
163163
* @param boolean $blocking True if loop should block waiting for next event.
164164
*/
165-
protected function flushEvents($blocking)
165+
protected function tickLogic($blocking)
166166
{
167167
$this->timers->tick();
168+
168169
$this->waitForStreamActivity($blocking);
169170
}
170171

@@ -180,28 +181,47 @@ protected function isEmpty()
180181
&& 0 === count($this->writeStreams);
181182
}
182183

183-
/**
184-
* Get the current time in microseconds.
185-
*
186-
* @return integer
187-
*/
188-
protected function now()
184+
protected function waitForStreamActivity($blocking)
189185
{
190-
return $this->toMicroSeconds(
191-
microtime(true)
192-
);
193-
}
186+
// The $blocking flag takes precedence ...
187+
if (!$blocking) {
188+
$timeout = 0;
194189

195-
/**
196-
* Convert the given time to microseconds.
197-
*
198-
* @param integer|float $seconds
199-
*
200-
* @return integer
201-
*/
202-
protected function toMicroSeconds($seconds)
203-
{
204-
return intval($seconds * 1000000);
190+
// There is a pending timer, only block until it is due ...
191+
} elseif ($scheduledAt = $this->timers->getFirst()) {
192+
$timeout = max(0, $scheduledAt - $this->timers->getTime());
193+
194+
// The only possible event is stream activity, so wait forever ...
195+
} elseif ($this->readStreams || $this->writeStreams) {
196+
$timeout = null;
197+
198+
// There's nothing left to do ...
199+
} else {
200+
return;
201+
}
202+
203+
$read = $this->readStreams;
204+
$write = $this->writeStreams;
205+
206+
$this->streamSelect($read, $write, $timeout);
207+
208+
// Invoke callbacks for read-ready streams ...
209+
foreach ($read as $stream) {
210+
$key = (int) $stream;
211+
212+
if (array_key_exists($key, $this->readListeners)) {
213+
call_user_func($this->readListeners[$key], $stream, $this);
214+
}
215+
}
216+
217+
// Invoke callbacks for write-ready streams ...
218+
foreach ($write as $stream) {
219+
$key = (int) $stream;
220+
221+
if (array_key_exists($key, $this->writeListeners)) {
222+
call_user_func($this->writeListeners[$key], $stream, $this);
223+
}
224+
}
205225
}
206226

207227
/**
@@ -230,48 +250,4 @@ protected function streamSelect(array &$read, array &$write, $timeout)
230250

231251
return 0;
232252
}
233-
234-
protected function waitForStreamActivity($blocking)
235-
{
236-
// The $blocking flag takes precedence ...
237-
if (!$blocking) {
238-
$timeout = 0;
239-
240-
// There is a pending timer, only block until it is due ...
241-
} elseif ($scheduledAt = $this->timers->getFirst()) {
242-
$timeout = max(
243-
0,
244-
$scheduledAt - $this->timers->getTime()
245-
);
246-
247-
// The only possible event is stream activity, so wait forever ...
248-
} elseif ($this->readStreams || $this->writeStreams) {
249-
$timeout = null;
250-
251-
// THere's nothing left to do ...
252-
} else {
253-
return;
254-
}
255-
256-
$read = $this->readStreams;
257-
$write = $this->writeStreams;
258-
259-
$this->streamSelect($read, $write, $timeout);
260-
261-
$this->flushStreamEvents($read, $this->readListeners);
262-
$this->flushStreamEvents($write, $this->writeListeners);
263-
}
264-
265-
protected function flushStreamEvents(array $streams, array &$listeners)
266-
{
267-
foreach ($streams as $stream) {
268-
$key = (int) $stream;
269-
270-
if (!array_key_exists($key, $listeners)) {
271-
continue;
272-
}
273-
274-
call_user_func($listeners[$key], $stream, $this);
275-
}
276-
}
277253
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy