@@ -10,7 +10,7 @@ class LibEventLoop implements LoopInterface
1010 private $ callback ;
1111
1212 private $ timers = array ();
13- private $ timersGc = array () ;
13+ private $ timersGc ;
1414
1515 private $ events = array ();
1616 private $ flags = array ();
@@ -21,24 +21,18 @@ public function __construct()
2121 {
2222 $ this ->base = event_base_new ();
2323 $ this ->callback = $ this ->createLibeventCallback ();
24+ $ this ->timersGc = new \SplQueue ();
25+ $ this ->timersGc ->setIteratorMode (\SplQueue::IT_MODE_DELETE );
2426 }
2527
2628 protected function createLibeventCallback ()
2729 {
28- $ timersGc = &$ this ->timersGc ;
2930 $ readCallbacks = &$ this ->readCallbacks ;
3031 $ writeCallbacks = &$ this ->writeCallbacks ;
3132
32- return function ($ stream , $ flags , $ loop ) use (&$ timersGc , & $ readCallbacks , &$ writeCallbacks ) {
33+ return function ($ stream , $ flags , $ loop ) use (&$ readCallbacks , &$ writeCallbacks ) {
3334 $ id = (int ) $ stream ;
3435
35- if ($ timersGc ) {
36- foreach ($ timersGc as $ signature => $ resource ) {
37- event_free ($ resource );
38- unset($ timersGc [$ signature ]);
39- }
40- }
41-
4236 try {
4337 if (($ flags & EV_READ ) === EV_READ && isset ($ readCallbacks [$ id ])) {
4438 if (call_user_func ($ readCallbacks [$ id ], $ stream , $ loop ) === false ) {
@@ -167,6 +161,10 @@ protected function addTimerInternal($interval, $callback, $periodic = false)
167161 throw new \InvalidArgumentException ('The callback must be a callable object. ' );
168162 }
169163
164+ while ($ resource = $ this ->timersGc ->dequeue ()){
165+ event_free ($ resource );
166+ }
167+
170168 $ timer = (object ) array (
171169 'loop ' => $ this ,
172170 'resource ' => $ resource = event_new (),
@@ -185,6 +183,9 @@ protected function addTimerInternal($interval, $callback, $periodic = false)
185183 if ($ timer ->periodic === true ) {
186184 event_add ($ timer ->resource , $ timer ->interval );
187185 }
186+ else {
187+ $ this ->cancelTimer ($ timer ->signature );
188+ }
188189 }
189190 };
190191
@@ -214,7 +215,7 @@ public function cancelTimer($signature)
214215
215216 $ timer ->cancelled = true ;
216217 event_del ($ timer ->resource );
217- $ this ->timersGc [ $ signature ] = $ timer ->resource ;
218+ $ this ->timersGc -> enqueue ( $ timer ->resource ) ;
218219 unset($ this ->timers [$ signature ]);
219220 }
220221 }
0 commit comments