diff options
author | Tom <tomut@yahoo.com> | 2020-12-11 11:07:42 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-11 19:33:15 +0100 |
commit | 03fcd02dfd6d572f6d35991a372961b1789fe478 (patch) | |
tree | 19d9f4751c76218d4936cd08e06e011ab046c0cd /Kernel | |
parent | 66f9a2d9ecb8d628d9db8f684839dba5a7e1434f (diff) | |
download | serenity-03fcd02dfd6d572f6d35991a372961b1789fe478.zip |
Kernel: Fix leaking Timer instances
When a Timer is queued we add a reference, so whenever we remove
a timer or fire it we should drop that reference.
Fixes #4382
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/TimerQueue.cpp | 8 | ||||
-rw-r--r-- | Kernel/TimerQueue.h | 2 |
2 files changed, 7 insertions, 3 deletions
diff --git a/Kernel/TimerQueue.cpp b/Kernel/TimerQueue.cpp index 0a5a67b22e..2419386f7f 100644 --- a/Kernel/TimerQueue.cpp +++ b/Kernel/TimerQueue.cpp @@ -213,8 +213,6 @@ bool TimerQueue::cancel_timer(TimerId id) ASSERT(found_timer); ASSERT(timer_queue); remove_timer_locked(*timer_queue, *found_timer); - lock.unlock(); - found_timer->unref(); return true; } @@ -241,6 +239,7 @@ bool TimerQueue::cancel_timer(Timer& timer) return false; } + ASSERT(timer.ref_count() > 1); remove_timer_locked(timer_queue, timer); return true; } @@ -256,6 +255,10 @@ void TimerQueue::remove_timer_locked(Queue& queue, Timer& timer) if (was_next_timer) update_next_timer_due(queue); + // Whenever we remove a timer that was still queued (but hasn't been + // fired) we added a reference to it. So, when removing it from the + // queue we need to drop that reference. + timer.unref(); } void TimerQueue::fire() @@ -279,6 +282,7 @@ void TimerQueue::fire() m_timers_executing.remove(timer); timer->set_queued(false); + // Drop the reference we added when queueing the timer timer->unref(); timer = queue.list.head(); diff --git a/Kernel/TimerQueue.h b/Kernel/TimerQueue.h index 33e741b388..f4eda76c41 100644 --- a/Kernel/TimerQueue.h +++ b/Kernel/TimerQueue.h @@ -97,7 +97,7 @@ public: bool cancel_timer(Timer&); bool cancel_timer(NonnullRefPtr<Timer>&& timer) { - return cancel_timer(timer.leak_ref()); + return cancel_timer(*move(timer)); } void fire(); |