1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-10 18:10:56 +09:00

Kernel: Fix deadlock cancelling timer

It's possible that a timer may have been queued to be executed by
the timer irq handler, but if we're in a critical section on the
same processor and are trying to cancel that timer, we would spin
forever waiting for it to be executed.
This commit is contained in:
Tom 2021-01-29 22:49:28 -07:00 committed by Andreas Kling
parent 6938be00f1
commit d9fb93c5ce
Notes: sideshowbarker 2024-07-18 09:12:19 +09:00
2 changed files with 78 additions and 58 deletions

View file

@ -43,7 +43,8 @@ private:
Time m_expires;
Time m_remaining {};
Function<void()> m_callback;
Atomic<bool, AK::MemoryOrder::memory_order_relaxed> m_queued { false };
Atomic<bool> m_cancelled { false };
Atomic<bool> m_callback_finished { false };
bool operator<(const Timer& rhs) const
{
@ -57,10 +58,15 @@ private:
{
return m_id == rhs.m_id;
}
bool is_queued() const { return m_queued; }
void set_queued(bool queued) { m_queued = queued; }
void clear_cancelled() { return m_cancelled.store(false, AK::memory_order_release); }
bool set_cancelled() { return m_cancelled.exchange(true, AK::memory_order_acq_rel); }
bool is_callback_finished() const { return m_callback_finished.load(AK::memory_order_acquire); }
void clear_callback_finished() { m_callback_finished.store(false, AK::memory_order_release); }
void set_callback_finished() { m_callback_finished.store(true, AK::memory_order_release); }
Time now(bool) const;
bool is_queued() const { return m_list_node.is_in_list(); }
public:
IntrusiveListNode<Timer> m_list_node;
using List = IntrusiveList<Timer, RawPtr<Timer>, &Timer::m_list_node>;