|
2 | 2 |
|
3 | 3 | namespace React\EventLoop;
|
4 | 4 |
|
| 5 | +use SplObjectStorage; |
| 6 | +use libev\TimerEvent as LibEvTimer; |
| 7 | +use React\EventLoop\Timer\Timer; |
| 8 | +use React\EventLoop\Timer\TimerInterface; |
| 9 | + |
5 | 10 | /**
|
6 | 11 | * @see https://github.com/m4rw3r/php-libev
|
7 | 12 | * @see https://gist.github.com/1688204
|
8 | 13 | */
|
9 | 14 | class LibEvLoop implements LoopInterface
|
10 | 15 | {
|
11 | 16 | private $loop;
|
| 17 | + private $timers; |
12 | 18 | private $readEvents = array();
|
13 | 19 | private $writeEvents = array();
|
14 |
| - private $timers = array(); |
15 | 20 |
|
16 | 21 | public function __construct()
|
17 | 22 | {
|
18 | 23 | $this->loop = new \libev\EventLoop();
|
| 24 | + $this->timers = new SplObjectStorage(); |
19 | 25 | }
|
20 | 26 |
|
21 | 27 | public function addReadStream($stream, $listener)
|
@@ -85,49 +91,51 @@ private function wrapStreamListener($stream, $listener, $flags)
|
85 | 91 |
|
86 | 92 | public function addTimer($interval, $callback)
|
87 | 93 | {
|
88 |
| - $dummyCallback = function () {}; |
89 |
| - $timer = new \libev\TimerEvent($dummyCallback, $interval); |
| 94 | + $timer = new Timer($this, $interval, $callback, false); |
| 95 | + $this->setupTimer($timer); |
90 | 96 |
|
91 |
| - return $this->createTimer($timer, $callback, false); |
| 97 | + return $timer; |
92 | 98 | }
|
93 | 99 |
|
94 | 100 | public function addPeriodicTimer($interval, $callback)
|
95 | 101 | {
|
96 |
| - $dummyCallback = function () {}; |
97 |
| - $timer = new \libev\TimerEvent($dummyCallback, $interval, $interval); |
| 102 | + $timer = new Timer($this, $interval, $callback, true); |
| 103 | + $this->setupTimer($timer); |
98 | 104 |
|
99 |
| - return $this->createTimer($timer, $callback, true); |
| 105 | + return $timer; |
100 | 106 | }
|
101 | 107 |
|
102 |
| - public function cancelTimer($signature) |
| 108 | + public function cancelTimer($timer) |
103 | 109 | {
|
104 |
| - $this->loop->remove($this->timers[$signature]); |
105 |
| - unset($this->timers[$signature]); |
| 110 | + if (isset($this->timers[$timer])) { |
| 111 | + $this->loop->remove($this->timers[$timer]); |
| 112 | + $this->timers->detach($timer); |
| 113 | + } |
106 | 114 | }
|
107 | 115 |
|
108 |
| - private function createTimer($timer, $callback, $periodic) |
| 116 | + private function setupTimer(TimerInterface $timer) |
109 | 117 | {
|
110 |
| - $signature = spl_object_hash($timer); |
111 |
| - $callback = $this->wrapTimerCallback($signature, $callback, $periodic); |
112 |
| - $timer->setCallback($callback); |
| 118 | + $dummyCallback = function () {}; |
| 119 | + $interval = $timer->getInterval(); |
113 | 120 |
|
114 |
| - $this->timers[$signature] = $timer; |
115 |
| - $this->loop->add($timer); |
| 121 | + if ($timer->isPeriodic()) { |
| 122 | + $libevTimer = new \libev\TimerEvent($dummyCallback, $interval, $interval); |
| 123 | + } else { |
| 124 | + $libevTimer = new \libev\TimerEvent($dummyCallback, $interval); |
| 125 | + } |
116 | 126 |
|
117 |
| - return $signature; |
118 |
| - } |
| 127 | + $libevTimer->setCallback(function () use ($timer) { |
| 128 | + call_user_func($timer->getCallback(), $timer); |
119 | 129 |
|
120 |
| - private function wrapTimerCallback($signature, $callback, $periodic) |
121 |
| - { |
122 |
| - $loop = $this; |
| 130 | + if ($timer->isPeriodic() === false) { |
| 131 | + $timer->cancel(); |
| 132 | + } |
| 133 | + }); |
123 | 134 |
|
124 |
| - return function ($event) use ($signature, $callback, $periodic, $loop) { |
125 |
| - call_user_func($callback, $signature, $loop); |
| 135 | + $this->timers->attach($timer, $libevTimer); |
| 136 | + $this->loop->add($libevTimer); |
126 | 137 |
|
127 |
| - if (!$periodic) { |
128 |
| - $loop->cancelTimer($signature); |
129 |
| - } |
130 |
| - }; |
| 138 | + return $timer; |
131 | 139 | }
|
132 | 140 |
|
133 | 141 | public function tick()
|
|
0 commit comments