From 65f2f19b41f3220f1f6f0f52f09ac7a6bea7a16d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 29 Apr 2019 15:57:49 +0200 Subject: [PATCH] CEventLoop: Protect the message queue with a Lock. --- LibCore/CEventLoop.cpp | 21 ++++++++++++++++++--- LibCore/CEventLoop.h | 3 +++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/LibCore/CEventLoop.cpp b/LibCore/CEventLoop.cpp index 485ac4b5d9c..614e8311167 100644 --- a/LibCore/CEventLoop.cpp +++ b/LibCore/CEventLoop.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -91,11 +92,17 @@ int CEventLoop::exec() if (m_exit_requested) return m_exit_code; do_processing(); + if (m_queued_events.is_empty()) { wait_for_event(); do_processing(); } - auto events = move(m_queued_events); + decltype(m_queued_events) events; + { + LOCKER(m_lock); + events = move(m_queued_events); + } + for (auto& queued_event : events) { auto* receiver = queued_event.receiver.ptr(); auto& event = *queued_event.event; @@ -120,6 +127,7 @@ int CEventLoop::exec() } if (m_exit_requested) { + LOCKER(m_lock); auto rejigged_event_queue = move(events); rejigged_event_queue.append(move(m_queued_events)); m_queued_events = move(rejigged_event_queue); @@ -132,6 +140,7 @@ int CEventLoop::exec() void CEventLoop::post_event(CObject& receiver, OwnPtr&& event) { + LOCKER(m_lock); #ifdef CEVENTLOOP_DEBUG dbgprintf("CEventLoop::post_event: {%u} << receiver=%p, event=%p\n", m_queued_events.size(), &receiver, event.ptr()); #endif @@ -164,11 +173,17 @@ void CEventLoop::wait_for_event() ASSERT_NOT_REACHED(); } + bool queued_events_is_empty; + { + LOCKER(m_lock); + queued_events_is_empty = m_queued_events.is_empty(); + } + struct timeval timeout = { 0, 0 }; - if (!s_timers->is_empty() && m_queued_events.is_empty()) + if (!s_timers->is_empty() && queued_events_is_empty) get_next_timer_expiration(timeout); - int rc = select(max_fd + 1, &rfds, &wfds, nullptr, (m_queued_events.is_empty() && s_timers->is_empty()) ? nullptr : &timeout); + int rc = select(max_fd + 1, &rfds, &wfds, nullptr, (queued_events_is_empty && s_timers->is_empty()) ? nullptr : &timeout); if (rc < 0) { ASSERT_NOT_REACHED(); } diff --git a/LibCore/CEventLoop.h b/LibCore/CEventLoop.h index 50dc8e8f11a..005d7ec610d 100644 --- a/LibCore/CEventLoop.h +++ b/LibCore/CEventLoop.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -58,6 +59,8 @@ private: bool m_exit_requested { false }; int m_exit_code { 0 }; + CLock m_lock; + struct EventLoopTimer { int timer_id { 0 }; int interval { 0 };