File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ class ExtEventLoop implements LoopInterface
2222 private $ streamCallback ;
2323 private $ streamEvents = [];
2424 private $ streamFlags = [];
25+ private $ streamRefs = [];
2526 private $ readListeners = [];
2627 private $ writeListeners = [];
2728 private $ running ;
@@ -110,7 +111,8 @@ private function removeStream($stream)
110111 $ this ->streamFlags [$ key ],
111112 $ this ->streamEvents [$ key ],
112113 $ this ->readListeners [$ key ],
113- $ this ->writeListeners [$ key ]
114+ $ this ->writeListeners [$ key ],
115+ $ this ->streamRefs [$ key ]
114116 );
115117 }
116118 }
@@ -224,6 +226,12 @@ private function subscribeStreamEvent($stream, $flag)
224226
225227 $ this ->streamEvents [$ key ] = $ event ;
226228 $ this ->streamFlags [$ key ] = $ flag ;
229+
230+ // ext-event does not increase refcount on stream resources for PHP 7+
231+ // manually keep track of stream resource to prevent premature garbage collection
232+ if (PHP_VERSION_ID >= 70000 ) {
233+ $ this ->streamRefs [$ key ] = $ stream ;
234+ }
227235 }
228236
229237 $ event ->add ();
Original file line number Diff line number Diff line change @@ -61,6 +61,39 @@ public function testAddReadStreamIgnoresSecondCallable()
6161 $ this ->tickLoop ($ this ->loop );
6262 }
6363
64+ public function testAddReadStreamReceivesDataFromStreamReference ()
65+ {
66+ $ this ->received = '' ;
67+ $ this ->subAddReadStreamReceivesDataFromStreamReference ();
68+ $ this ->assertEquals ('' , $ this ->received );
69+
70+ $ this ->assertRunFasterThan ($ this ->tickTimeout * 2 );
71+ $ this ->assertEquals ('[hello]X ' , $ this ->received );
72+ }
73+
74+ /**
75+ * Telper for above test. This happens in another helper method to verify
76+ * the loop keep track of assigned stream resources (refcount).
77+ */
78+ private function subAddReadStreamReceivesDataFromStreamReference ()
79+ {
80+ list ($ input , $ output ) = $ this ->createSocketPair ();
81+
82+ fwrite ($ input , 'hello ' );
83+ fclose ($ input );
84+
85+ $ this ->loop ->addReadStream ($ output , function ($ output ) {
86+ $ chunk = fread ($ output , 1024 );
87+ if ($ chunk === '' ) {
88+ $ this ->received .= 'X ' ;
89+ $ this ->loop ->removeReadStream ($ output );
90+ fclose ($ output );
91+ } else {
92+ $ this ->received .= '[ ' . $ chunk . '] ' ;
93+ }
94+ });
95+ }
96+
6497 public function testAddWriteStream ()
6598 {
6699 list ($ input ) = $ this ->createSocketPair ();
You can’t perform that action at this time.
0 commit comments