From a362c37c8b3d2c8f0d5e23276bfe81cb1c24d384 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Wed, 8 May 2024 20:08:18 +0200 Subject: [PATCH] LibCore: Add Core::deferred_invoke_if(F, Condition) This will invoke the function F only if the provided Condition is met, otherwise the execution of the function F will be further deferred. --- .../Libraries/LibCore/DeferredInvocationContext.h | 15 ++++++++++++++- Userland/Libraries/LibCore/EventLoop.cpp | 11 +++++++++++ Userland/Libraries/LibCore/EventLoop.h | 3 ++- Userland/Libraries/LibCore/ThreadEventQueue.cpp | 8 +++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibCore/DeferredInvocationContext.h b/Userland/Libraries/LibCore/DeferredInvocationContext.h index 5af46ff3db..31ee2176d6 100644 --- a/Userland/Libraries/LibCore/DeferredInvocationContext.h +++ b/Userland/Libraries/LibCore/DeferredInvocationContext.h @@ -13,8 +13,21 @@ namespace Core { class DeferredInvocationContext final : public Core::EventReceiver { C_OBJECT(DeferredInvocationContext) +public: + bool should_invoke() const { return m_condition(); } + private: - DeferredInvocationContext() = default; + DeferredInvocationContext() + : m_condition([] { return true; }) + { + } + + DeferredInvocationContext(Function condition) + : m_condition(move(condition)) + { + } + + Function m_condition; }; } diff --git a/Userland/Libraries/LibCore/EventLoop.cpp b/Userland/Libraries/LibCore/EventLoop.cpp index bbe7667179..417487c700 100644 --- a/Userland/Libraries/LibCore/EventLoop.cpp +++ b/Userland/Libraries/LibCore/EventLoop.cpp @@ -156,11 +156,22 @@ void EventLoop::deferred_invoke(Function invokee) post_event(context, make(context, move(invokee))); } +void EventLoop::deferred_invoke_if(Function invokee, Function condition) +{ + auto context = DeferredInvocationContext::construct(move(condition)); + post_event(context, make(context, move(invokee))); +} + void deferred_invoke(Function invokee) { EventLoop::current().deferred_invoke(move(invokee)); } +void deferred_invoke_if(Function invokee, Function condition) +{ + EventLoop::current().deferred_invoke_if(move(invokee), move(condition)); +} + bool EventLoop::was_exit_requested() const { return m_impl->was_exit_requested(); diff --git a/Userland/Libraries/LibCore/EventLoop.h b/Userland/Libraries/LibCore/EventLoop.h index bdca156520..a5bbc7bff2 100644 --- a/Userland/Libraries/LibCore/EventLoop.h +++ b/Userland/Libraries/LibCore/EventLoop.h @@ -68,6 +68,7 @@ public: void add_job(NonnullRefPtr>> job_promise); void deferred_invoke(Function); + void deferred_invoke_if(Function, Function); void wake(); @@ -102,5 +103,5 @@ private: }; void deferred_invoke(Function); - +void deferred_invoke_if(Function, Function); } diff --git a/Userland/Libraries/LibCore/ThreadEventQueue.cpp b/Userland/Libraries/LibCore/ThreadEventQueue.cpp index a6fbe30dcc..959385b26b 100644 --- a/Userland/Libraries/LibCore/ThreadEventQueue.cpp +++ b/Userland/Libraries/LibCore/ThreadEventQueue.cpp @@ -84,6 +84,7 @@ void ThreadEventQueue::cancel_all_pending_jobs() size_t ThreadEventQueue::process() { decltype(m_private->queued_events) events; + decltype(m_private->queued_events) future_events; { Threading::MutexLocker locker(m_private->mutex); events = move(m_private->queued_events); @@ -105,7 +106,10 @@ size_t ThreadEventQueue::process() break; } } else if (event.type() == Event::Type::DeferredInvoke) { - static_cast(event).m_invokee(); + if (static_cast(*receiver).should_invoke()) + static_cast(event).m_invokee(); + else + future_events.append(move(queued_event)); } else { NonnullRefPtr protector(*receiver); receiver->dispatch_event(event); @@ -115,6 +119,8 @@ size_t ThreadEventQueue::process() { Threading::MutexLocker locker(m_private->mutex); + if (!future_events.is_empty()) + m_private->queued_events.extend(move(future_events)); if (m_private->pending_promises.size() > 30 && !m_private->warned_promise_count) { m_private->warned_promise_count = true; dbgln("ThreadEventQueue::process: Job queue wasn't designed for this load ({} promises)", m_private->pending_promises.size());