summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-12-11 11:07:42 -0700
committerAndreas Kling <kling@serenityos.org>2020-12-11 19:33:15 +0100
commit03fcd02dfd6d572f6d35991a372961b1789fe478 (patch)
tree19d9f4751c76218d4936cd08e06e011ab046c0cd /Kernel
parent66f9a2d9ecb8d628d9db8f684839dba5a7e1434f (diff)
downloadserenity-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.cpp8
-rw-r--r--Kernel/TimerQueue.h2
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();