From d8387f1506c90091d615ee7ba3ebb7bb0381a155 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Tue, 16 Jul 2019 20:31:14 +0200 Subject: [PATCH] CNotifier: Turn into a CObject and Use the event queue to deliver events This way, CNotifier can mutate state to its little heart's content without destroying the world when the global CNotifier hash changes during delivery. --- Libraries/LibCore/CEvent.h | 32 ++++++++++++++++++++++++++++++++ Libraries/LibCore/CEventLoop.cpp | 4 ++-- Libraries/LibCore/CNotifier.cpp | 11 +++++++++++ Libraries/LibCore/CNotifier.h | 6 +++++- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/Libraries/LibCore/CEvent.h b/Libraries/LibCore/CEvent.h index 6238cc59a43..cd5342eb55d 100644 --- a/Libraries/LibCore/CEvent.h +++ b/Libraries/LibCore/CEvent.h @@ -13,6 +13,8 @@ public: Invalid = 0, Quit, Timer, + NotifierRead, + NotifierWrite, DeferredDestroy, DeferredInvoke, ChildAdded, @@ -62,6 +64,36 @@ private: int m_timer_id; }; +class CNotifierReadEvent final : public CEvent { +public: + explicit CNotifierReadEvent(int fd) + : CEvent(CEvent::NotifierRead) + , m_fd(fd) + { + } + ~CNotifierReadEvent() {} + + int fd() const { return m_fd; } + +private: + int m_fd; +}; + +class CNotifierWriteEvent final : public CEvent { +public: + explicit CNotifierWriteEvent(int fd) + : CEvent(CEvent::NotifierWrite) + , m_fd(fd) + { + } + ~CNotifierWriteEvent() {} + + int fd() const { return m_fd; } + +private: + int m_fd; +}; + class CChildEvent final : public CEvent { public: CChildEvent(Type, CObject& child); diff --git a/Libraries/LibCore/CEventLoop.cpp b/Libraries/LibCore/CEventLoop.cpp index a2eada598a0..2a315a03134 100644 --- a/Libraries/LibCore/CEventLoop.cpp +++ b/Libraries/LibCore/CEventLoop.cpp @@ -245,11 +245,11 @@ void CEventLoop::wait_for_event(WaitMode mode) for (auto& notifier : *s_notifiers) { if (FD_ISSET(notifier->fd(), &rfds)) { if (notifier->on_ready_to_read) - notifier->on_ready_to_read(); + post_event(*notifier, make(notifier->fd())); } if (FD_ISSET(notifier->fd(), &wfds)) { if (notifier->on_ready_to_write) - notifier->on_ready_to_write(); + post_event(*notifier, make(notifier->fd())); } } diff --git a/Libraries/LibCore/CNotifier.cpp b/Libraries/LibCore/CNotifier.cpp index d042a579ca0..31870d5b348 100644 --- a/Libraries/LibCore/CNotifier.cpp +++ b/Libraries/LibCore/CNotifier.cpp @@ -21,3 +21,14 @@ void CNotifier::set_enabled(bool enabled) else CEventLoop::unregister_notifier({}, *this); } + +void CNotifier::event(CEvent& event) +{ + if (event.type() == CEvent::NotifierRead && on_ready_to_read) { + on_ready_to_read(); + } else if (event.type() == CEvent::NotifierWrite && on_ready_to_write) { + on_ready_to_write(); + } else { + CObject::event(event); + } +} diff --git a/Libraries/LibCore/CNotifier.h b/Libraries/LibCore/CNotifier.h index 7ef16519148..6464000037f 100644 --- a/Libraries/LibCore/CNotifier.h +++ b/Libraries/LibCore/CNotifier.h @@ -1,8 +1,9 @@ #pragma once #include +#include "CObject.h" -class CNotifier { +class CNotifier : public CObject { public: enum Event { None = 0, @@ -22,6 +23,9 @@ public: unsigned event_mask() const { return m_event_mask; } void set_event_mask(unsigned event_mask) { m_event_mask = event_mask; } + const char* class_name() const override { return "CNotifier"; } + void event(CEvent& event) override; + private: int m_fd { -1 }; unsigned m_event_mask { 0 };