Skip to content

Commit 3fec69d

Browse files
committed
Merge branch 'issue76'
* issue76: Add libevent timers fix to CHANGELOG Whitespace nitpick force travis retest. Appears 5.3.3 timed out 5.3 backward compatibility for ->timersGc moved timersgc foreach loop into callback Fix timersGc iteration in LibEventLoop issue 76 fix. Using SplQueue for
2 parents 2ad8ff4 + 4463cb2 commit 3fec69d

File tree

2 files changed

+13
-12
lines changed

2 files changed

+13
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
* 0.2.6 (2012-12-xx)
55

66
* Bug fix: [Http] Emit end event when Response closes (@beaucollins)
7+
* Bug fix: [EventLoop] Plug memory issue in libevent timers (@cameronjacobson)
78

89
* 0.2.5 (2012-11-26)
910

src/React/EventLoop/LibEventLoop.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {
@@ -177,13 +171,19 @@ protected function addTimerInternal($interval, $callback, $periodic = false)
177171
);
178172

179173
$timer->signature = spl_object_hash($timer);
174+
$timersGc = $this->timersGc;
175+
$callback = function () use ($timer, $timersGc) {
176+
foreach ($timersGc as $resource) {
177+
event_free($resource);
178+
}
180179

181-
$callback = function () use ($timer) {
182180
if ($timer->cancelled === false) {
183181
call_user_func($timer->callback, $timer->signature, $timer->loop);
184182

185183
if ($timer->periodic === true) {
186184
event_add($timer->resource, $timer->interval);
185+
} else {
186+
$this->cancelTimer($timer->signature);
187187
}
188188
}
189189
};
@@ -214,7 +214,7 @@ public function cancelTimer($signature)
214214

215215
$timer->cancelled = true;
216216
event_del($timer->resource);
217-
$this->timersGc[$signature] = $timer->resource;
217+
$this->timersGc->enqueue($timer->resource);
218218
unset($this->timers[$signature]);
219219
}
220220
}

0 commit comments

Comments
 (0)