Skip to content

Commit c20ff88

Browse files
committed
Fixed loop->watchers[w->fd] == w and only run listeners that have events
1 parent 5f131fc commit c20ff88

File tree

1 file changed

+47
-31
lines changed

1 file changed

+47
-31
lines changed

src/LibUvLoop.php

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class LibUvLoop implements LoopInterface
1616
private $futureTickQueue;
1717
private $timerEvents;
1818
private $events = [];
19+
private $flags = [];
1920
private $listeners = [];
2021
private $running;
2122
private $streamListener;
@@ -65,10 +66,7 @@ public function removeReadStream($stream)
6566

6667
unset($this->listeners[(int) $stream]['read']);
6768

68-
if (!isset($this->listeners[(int) $stream]['read'])
69-
&& !isset($this->listeners[(int) $stream]['write'])) {
70-
unset($this->events[(int) $stream]);
71-
}
69+
$this->____removeStream($stream);
7270
}
7371

7472
/**
@@ -82,10 +80,7 @@ public function removeWriteStream($stream)
8280

8381
unset($this->listeners[(int) $stream]['write']);
8482

85-
if (!isset($this->listeners[(int) $stream]['read'])
86-
&& !isset($this->listeners[(int) $stream]['write'])) {
87-
unset($this->events[(int) $stream]);
88-
}
83+
$this->____removeStream($stream);
8984
}
9085

9186
/**
@@ -94,12 +89,10 @@ public function removeWriteStream($stream)
9489
public function removeStream($stream)
9590
{
9691
if (isset($this->events[(int) $stream])) {
97-
98-
\uv_poll_stop($this->events[(int) $stream]);
99-
10092
unset($this->listeners[(int) $stream]['read']);
10193
unset($this->listeners[(int) $stream]['write']);
102-
unset($this->events[(int) $stream]);
94+
95+
$this->____removeStream($stream);
10396
}
10497
}
10598

@@ -207,6 +200,39 @@ public function stop()
207200
}
208201

209202
private function addStream($stream)
203+
{
204+
// Run in tick or else things epically fail with loop->watchers[w->fd] == w
205+
$this->futureTick(function () use ($stream) {
206+
if (!isset($this->events[(int) $stream])) {
207+
$this->events[(int) $stream] = \uv_poll_init_socket($this->uv, $stream);
208+
}
209+
210+
$this->pollStream($stream);
211+
});
212+
}
213+
214+
// To do: get latest changes in from react:master so we can use this method name internally
215+
private function ____removeStream($stream)
216+
{
217+
// Run in tick or else things epically fail with loop->watchers[w->fd] == w
218+
$this->futureTick(function () use ($stream) {
219+
if (!isset($this->events[(int) $stream])) {
220+
return;
221+
}
222+
223+
if (!isset($this->listeners[(int) $stream]['read'])
224+
&& !isset($this->listeners[(int) $stream]['write'])) {
225+
\uv_poll_stop($this->events[(int) $stream]);
226+
unset($this->events[(int) $stream]);
227+
unset($this->flags[(int) $stream]);
228+
return;
229+
}
230+
231+
$this->pollStream($stream);
232+
});
233+
}
234+
235+
private function pollStream($stream)
210236
{
211237
$flags = 0;
212238
if (isset($this->listeners[(int) $stream]['read'])) {
@@ -217,14 +243,13 @@ private function addStream($stream)
217243
$flags |= \UV::WRITABLE;
218244
}
219245

220-
if (!isset($this->events[(int) $stream])) {
221-
$event = \uv_poll_init_socket($this->uv, $stream);
222-
$this->events[(int) $stream] = $event;
223-
} else {
224-
$event = $this->events[(int) $stream];
246+
if (isset($this->flags[(int) $stream]) && $this->flags[(int) $stream] == $flags) {
247+
return;
225248
}
226249

227-
\uv_poll_start($event, $flags, $this->streamListener);
250+
$this->flags[(int) $stream] = $flags;
251+
252+
\uv_poll_start($this->events[(int) $stream], $flags, $this->streamListener);
228253
}
229254

230255
/**
@@ -236,24 +261,15 @@ private function createStreamListener()
236261
{
237262
$callback = function ($event, $status, $events, $stream) {
238263
if ($status !== 0) {
239-
240-
$flags = 0;
241-
if (isset($this->listeners[(int) $stream]['read'])) {
242-
$flags |= \UV::READABLE;
243-
}
244-
245-
if (isset($this->listeners[(int) $stream]['write'])) {
246-
$flags |= \UV::WRITABLE;
247-
}
248-
249-
\uv_poll_start($event, $flags, $this->streamListener);
264+
unset($this->flags[(int) $stream]);
265+
$this->pollStream($stream);
250266
}
251267

252-
if (isset($this->listeners[(int) $stream]['read'])) {
268+
if (isset($this->listeners[(int) $stream]['read']) && $events & \UV::READABLE) {
253269
call_user_func($this->listeners[(int) $stream]['read'], $stream);
254270
}
255271

256-
if (isset($this->listeners[(int) $stream]['write'])) {
272+
if (isset($this->listeners[(int) $stream]['write']) && $events & \UV::WRITABLE) {
257273
call_user_func($this->listeners[(int) $stream]['write'], $stream);
258274
}
259275
};

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