mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:58:11 +00:00
CEventLoop: Protect the message queue with a Lock.
This commit is contained in:
parent
14ac77131b
commit
65f2f19b41
2 changed files with 21 additions and 3 deletions
|
@ -1,6 +1,7 @@
|
||||||
#include <LibCore/CObject.h>
|
#include <LibCore/CObject.h>
|
||||||
#include <LibCore/CEventLoop.h>
|
#include <LibCore/CEventLoop.h>
|
||||||
#include <LibCore/CEvent.h>
|
#include <LibCore/CEvent.h>
|
||||||
|
#include <LibCore/CLock.h>
|
||||||
#include <LibCore/CNotifier.h>
|
#include <LibCore/CNotifier.h>
|
||||||
#include <LibC/unistd.h>
|
#include <LibC/unistd.h>
|
||||||
#include <LibC/stdio.h>
|
#include <LibC/stdio.h>
|
||||||
|
@ -91,11 +92,17 @@ int CEventLoop::exec()
|
||||||
if (m_exit_requested)
|
if (m_exit_requested)
|
||||||
return m_exit_code;
|
return m_exit_code;
|
||||||
do_processing();
|
do_processing();
|
||||||
|
|
||||||
if (m_queued_events.is_empty()) {
|
if (m_queued_events.is_empty()) {
|
||||||
wait_for_event();
|
wait_for_event();
|
||||||
do_processing();
|
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) {
|
for (auto& queued_event : events) {
|
||||||
auto* receiver = queued_event.receiver.ptr();
|
auto* receiver = queued_event.receiver.ptr();
|
||||||
auto& event = *queued_event.event;
|
auto& event = *queued_event.event;
|
||||||
|
@ -120,6 +127,7 @@ int CEventLoop::exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_exit_requested) {
|
if (m_exit_requested) {
|
||||||
|
LOCKER(m_lock);
|
||||||
auto rejigged_event_queue = move(events);
|
auto rejigged_event_queue = move(events);
|
||||||
rejigged_event_queue.append(move(m_queued_events));
|
rejigged_event_queue.append(move(m_queued_events));
|
||||||
m_queued_events = move(rejigged_event_queue);
|
m_queued_events = move(rejigged_event_queue);
|
||||||
|
@ -132,6 +140,7 @@ int CEventLoop::exec()
|
||||||
|
|
||||||
void CEventLoop::post_event(CObject& receiver, OwnPtr<CEvent>&& event)
|
void CEventLoop::post_event(CObject& receiver, OwnPtr<CEvent>&& event)
|
||||||
{
|
{
|
||||||
|
LOCKER(m_lock);
|
||||||
#ifdef CEVENTLOOP_DEBUG
|
#ifdef CEVENTLOOP_DEBUG
|
||||||
dbgprintf("CEventLoop::post_event: {%u} << receiver=%p, event=%p\n", m_queued_events.size(), &receiver, event.ptr());
|
dbgprintf("CEventLoop::post_event: {%u} << receiver=%p, event=%p\n", m_queued_events.size(), &receiver, event.ptr());
|
||||||
#endif
|
#endif
|
||||||
|
@ -164,11 +173,17 @@ void CEventLoop::wait_for_event()
|
||||||
ASSERT_NOT_REACHED();
|
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 };
|
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);
|
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) {
|
if (rc < 0) {
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibCore/CLock.h>
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
|
@ -58,6 +59,8 @@ private:
|
||||||
bool m_exit_requested { false };
|
bool m_exit_requested { false };
|
||||||
int m_exit_code { 0 };
|
int m_exit_code { 0 };
|
||||||
|
|
||||||
|
CLock m_lock;
|
||||||
|
|
||||||
struct EventLoopTimer {
|
struct EventLoopTimer {
|
||||||
int timer_id { 0 };
|
int timer_id { 0 };
|
||||||
int interval { 0 };
|
int interval { 0 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue