@@ -27,11 +27,12 @@ final class ExtEventLoop implements LoopInterface
27
27
private $ timerCallback ;
28
28
private $ timerEvents ;
29
29
private $ streamCallback ;
30
- private $ streamEvents = [];
31
- private $ streamFlags = [];
32
- private $ streamRefs = [];
30
+ private $ readEvents = [];
31
+ private $ writeEvents = [];
33
32
private $ readListeners = [];
34
33
private $ writeListeners = [];
34
+ private $ readRefs = [];
35
+ private $ writeRefs = [];
35
36
private $ running ;
36
37
private $ signals ;
37
38
private $ signalEvents = [];
@@ -70,56 +71,65 @@ function ($signal) {
70
71
public function addReadStream ($ stream , callable $ listener )
71
72
{
72
73
$ key = (int ) $ stream ;
74
+ if (isset ($ this ->readListeners [$ key ])) {
75
+ return ;
76
+ }
73
77
74
- if (!isset ($ this ->readListeners [$ key ])) {
75
- $ this ->readListeners [$ key ] = $ listener ;
76
- $ this ->subscribeStreamEvent ($ stream , Event::READ );
78
+ $ event = new Event ($ this ->eventBase , $ stream , Event::PERSIST | Event::READ , $ this ->streamCallback );
79
+ $ event ->add ();
80
+ $ this ->readEvents [$ key ] = $ event ;
81
+ $ this ->readListeners [$ key ] = $ listener ;
82
+
83
+ // ext-event does not increase refcount on stream resources for PHP 7+
84
+ // manually keep track of stream resource to prevent premature garbage collection
85
+ if (PHP_VERSION_ID >= 70000 ) {
86
+ $ this ->readRefs [$ key ] = $ stream ;
77
87
}
78
88
}
79
89
80
90
public function addWriteStream ($ stream , callable $ listener )
81
91
{
82
92
$ key = (int ) $ stream ;
83
-
84
- if (!isset ($ this ->writeListeners [$ key ])) {
85
- $ this ->writeListeners [$ key ] = $ listener ;
86
- $ this ->subscribeStreamEvent ($ stream , Event::WRITE );
93
+ if (isset ($ this ->writeListeners [$ key ])) {
94
+ return ;
87
95
}
88
- }
89
96
90
- public function removeReadStream ($ stream )
91
- {
92
- $ key = (int ) $ stream ;
97
+ $ event = new Event ($ this ->eventBase , $ stream , Event::PERSIST | Event::WRITE , $ this ->streamCallback );
98
+ $ event ->add ();
99
+ $ this ->writeEvents [$ key ] = $ event ;
100
+ $ this ->writeListeners [$ key ] = $ listener ;
93
101
94
- if (isset ($ this ->readListeners [$ key ])) {
95
- unset($ this ->readListeners [$ key ]);
96
- $ this ->unsubscribeStreamEvent ($ stream , Event::READ );
102
+ // ext-event does not increase refcount on stream resources for PHP 7+
103
+ // manually keep track of stream resource to prevent premature garbage collection
104
+ if (PHP_VERSION_ID >= 70000 ) {
105
+ $ this ->writeRefs [$ key ] = $ stream ;
97
106
}
98
107
}
99
108
100
- public function removeWriteStream ($ stream )
109
+ public function removeReadStream ($ stream )
101
110
{
102
111
$ key = (int ) $ stream ;
103
112
104
- if (isset ($ this ->writeListeners [$ key ])) {
105
- unset($ this ->writeListeners [$ key ]);
106
- $ this ->unsubscribeStreamEvent ($ stream , Event::WRITE );
113
+ if (isset ($ this ->readEvents [$ key ])) {
114
+ $ this ->readEvents [$ key ]->free ();
115
+ unset(
116
+ $ this ->readEvents [$ key ],
117
+ $ this ->readListeners [$ key ],
118
+ $ this ->readRefs [$ key ]
119
+ );
107
120
}
108
121
}
109
122
110
- private function removeStream ($ stream )
123
+ public function removeWriteStream ($ stream )
111
124
{
112
125
$ key = (int ) $ stream ;
113
126
114
- if (isset ($ this ->streamEvents [$ key ])) {
115
- $ this ->streamEvents [$ key ]->free ();
116
-
127
+ if (isset ($ this ->writeEvents [$ key ])) {
128
+ $ this ->writeEvents [$ key ]->free ();
117
129
unset(
118
- $ this ->streamFlags [$ key ],
119
- $ this ->streamEvents [$ key ],
120
- $ this ->readListeners [$ key ],
130
+ $ this ->writeEvents [$ key ],
121
131
$ this ->writeListeners [$ key ],
122
- $ this ->streamRefs [$ key ]
132
+ $ this ->writeRefs [$ key ]
123
133
);
124
134
}
125
135
}
@@ -175,7 +185,7 @@ public function run()
175
185
$ flags = EventBase::LOOP_ONCE ;
176
186
if (!$ this ->running || !$ this ->futureTickQueue ->isEmpty ()) {
177
187
$ flags |= EventBase::LOOP_NONBLOCK ;
178
- } elseif (!$ this ->streamEvents && !$ this ->timerEvents ->count ()) {
188
+ } elseif (!$ this ->readEvents && ! $ this -> writeEvents && !$ this ->timerEvents ->count ()) {
179
189
break ;
180
190
}
181
191
@@ -207,64 +217,6 @@ private function scheduleTimer(TimerInterface $timer)
207
217
$ event ->add ($ timer ->getInterval ());
208
218
}
209
219
210
- /**
211
- * Create a new ext-event Event object, or update the existing one.
212
- *
213
- * @param resource $stream
214
- * @param integer $flag Event::READ or Event::WRITE
215
- */
216
- private function subscribeStreamEvent ($ stream , $ flag )
217
- {
218
- $ key = (int ) $ stream ;
219
-
220
- if (isset ($ this ->streamEvents [$ key ])) {
221
- $ event = $ this ->streamEvents [$ key ];
222
- $ flags = ($ this ->streamFlags [$ key ] |= $ flag );
223
-
224
- $ event ->del ();
225
- $ event ->set ($ this ->eventBase , $ stream , Event::PERSIST | $ flags , $ this ->streamCallback );
226
- } else {
227
- $ event = new Event ($ this ->eventBase , $ stream , Event::PERSIST | $ flag , $ this ->streamCallback );
228
-
229
- $ this ->streamEvents [$ key ] = $ event ;
230
- $ this ->streamFlags [$ key ] = $ flag ;
231
-
232
- // ext-event does not increase refcount on stream resources for PHP 7+
233
- // manually keep track of stream resource to prevent premature garbage collection
234
- if (PHP_VERSION_ID >= 70000 ) {
235
- $ this ->streamRefs [$ key ] = $ stream ;
236
- }
237
- }
238
-
239
- $ event ->add ();
240
- }
241
-
242
- /**
243
- * Update the ext-event Event object for this stream to stop listening to
244
- * the given event type, or remove it entirely if it's no longer needed.
245
- *
246
- * @param resource $stream
247
- * @param integer $flag Event::READ or Event::WRITE
248
- */
249
- private function unsubscribeStreamEvent ($ stream , $ flag )
250
- {
251
- $ key = (int ) $ stream ;
252
-
253
- $ flags = $ this ->streamFlags [$ key ] &= ~$ flag ;
254
-
255
- if (0 === $ flags ) {
256
- $ this ->removeStream ($ stream );
257
-
258
- return ;
259
- }
260
-
261
- $ event = $ this ->streamEvents [$ key ];
262
-
263
- $ event ->del ();
264
- $ event ->set ($ this ->eventBase , $ stream , Event::PERSIST | $ flags , $ this ->streamCallback );
265
- $ event ->add ();
266
- }
267
-
268
220
/**
269
221
* Create a callback used as the target of timer events.
270
222
*
0 commit comments