@@ -16,6 +16,7 @@ class LibUvLoop implements LoopInterface
16
16
private $ futureTickQueue ;
17
17
private $ timerEvents ;
18
18
private $ events = [];
19
+ private $ flags = [];
19
20
private $ listeners = [];
20
21
private $ running ;
21
22
private $ streamListener ;
@@ -65,10 +66,7 @@ public function removeReadStream($stream)
65
66
66
67
unset($ this ->listeners [(int ) $ stream ]['read ' ]);
67
68
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 );
72
70
}
73
71
74
72
/**
@@ -82,10 +80,7 @@ public function removeWriteStream($stream)
82
80
83
81
unset($ this ->listeners [(int ) $ stream ]['write ' ]);
84
82
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 );
89
84
}
90
85
91
86
/**
@@ -94,12 +89,10 @@ public function removeWriteStream($stream)
94
89
public function removeStream ($ stream )
95
90
{
96
91
if (isset ($ this ->events [(int ) $ stream ])) {
97
-
98
- \uv_poll_stop ($ this ->events [(int ) $ stream ]);
99
-
100
92
unset($ this ->listeners [(int ) $ stream ]['read ' ]);
101
93
unset($ this ->listeners [(int ) $ stream ]['write ' ]);
102
- unset($ this ->events [(int ) $ stream ]);
94
+
95
+ $ this ->____removeStream ($ stream );
103
96
}
104
97
}
105
98
@@ -207,6 +200,39 @@ public function stop()
207
200
}
208
201
209
202
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 )
210
236
{
211
237
$ flags = 0 ;
212
238
if (isset ($ this ->listeners [(int ) $ stream ]['read ' ])) {
@@ -217,14 +243,13 @@ private function addStream($stream)
217
243
$ flags |= \UV ::WRITABLE ;
218
244
}
219
245
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 ;
225
248
}
226
249
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 );
228
253
}
229
254
230
255
/**
@@ -236,24 +261,15 @@ private function createStreamListener()
236
261
{
237
262
$ callback = function ($ event , $ status , $ events , $ stream ) {
238
263
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 );
250
266
}
251
267
252
- if (isset ($ this ->listeners [(int ) $ stream ]['read ' ])) {
268
+ if (isset ($ this ->listeners [(int ) $ stream ]['read ' ]) && $ events & \ UV :: READABLE ) {
253
269
call_user_func ($ this ->listeners [(int ) $ stream ]['read ' ], $ stream );
254
270
}
255
271
256
- if (isset ($ this ->listeners [(int ) $ stream ]['write ' ])) {
272
+ if (isset ($ this ->listeners [(int ) $ stream ]['write ' ]) && $ events & \ UV :: WRITABLE ) {
257
273
call_user_func ($ this ->listeners [(int ) $ stream ]['write ' ], $ stream );
258
274
}
259
275
};
0 commit comments