diff --git a/Userland/Libraries/LibThreading/BackgroundAction.h b/Userland/Libraries/LibThreading/BackgroundAction.h index 87925a4e1b..928dc2665e 100644 --- a/Userland/Libraries/LibThreading/BackgroundAction.h +++ b/Userland/Libraries/LibThreading/BackgroundAction.h @@ -55,8 +55,7 @@ public: private: BackgroundAction(Function(BackgroundAction&)> action, Function(Result)> on_complete, Optional> on_error = {}) - : Core::EventReceiver(&background_thread()) - , m_promise(Promise::try_create().release_value_but_fixme_should_propagate_errors()) + : m_promise(Promise::try_create().release_value_but_fixme_should_propagate_errors()) , m_action(move(action)) , m_on_complete(move(on_complete)) { @@ -75,21 +74,18 @@ private: if (on_error.has_value()) m_on_error = on_error.release_value(); - enqueue_work([this, origin_event_loop = &Core::EventLoop::current()] { - auto result = m_action(*this); + enqueue_work([self = NonnullRefPtr(*this), origin_event_loop = &Core::EventLoop::current()]() { + auto result = self->m_action(*self); // The event loop cancels the promise when it exits. - m_canceled |= m_promise->is_rejected(); - auto callback_scheduled = false; + self->m_canceled |= self->m_promise->is_rejected(); // All of our work was successful and we weren't cancelled; resolve the event loop's promise. - if (!m_canceled && !result.is_error()) { - m_result = result.release_value(); + if (!self->m_canceled && !result.is_error()) { + self->m_result = result.release_value(); // If there is no completion callback, we don't rely on the user keeping around the event loop. - if (m_on_complete) { - callback_scheduled = true; - origin_event_loop->deferred_invoke([this] { + if (self->m_on_complete) { + origin_event_loop->deferred_invoke([self] { // Our promise's resolution function will never error. - (void)m_promise->resolve(*this); - remove_from_parent(); + (void)self->m_promise->resolve(*self); }); origin_event_loop->wake(); } @@ -99,21 +95,16 @@ private: if (result.is_error()) error = result.release_error(); - m_promise->reject(Error::from_errno(ECANCELED)); - if (!m_canceled && m_on_error) { - callback_scheduled = true; - origin_event_loop->deferred_invoke([this, error = move(error)]() mutable { - m_on_error(move(error)); - remove_from_parent(); + self->m_promise->reject(Error::from_errno(ECANCELED)); + if (!self->m_canceled && self->m_on_error) { + origin_event_loop->deferred_invoke([self, error = move(error)]() mutable { + self->m_on_error(move(error)); }); origin_event_loop->wake(); - } else if (m_on_error) { - m_on_error(move(error)); + } else if (self->m_on_error) { + self->m_on_error(move(error)); } } - - if (!callback_scheduled) - remove_from_parent(); }); } diff --git a/Userland/Libraries/LibThreading/Thread.cpp b/Userland/Libraries/LibThreading/Thread.cpp index 95dc0b55ea..d8ac15a26c 100644 --- a/Userland/Libraries/LibThreading/Thread.cpp +++ b/Userland/Libraries/LibThreading/Thread.cpp @@ -12,8 +12,7 @@ namespace Threading { Thread::Thread(Function action, StringView thread_name) - : Core::EventReceiver(nullptr) - , m_action(move(action)) + : m_action(move(action)) , m_thread_name(thread_name.is_null() ? ""sv : thread_name) { } diff --git a/Userland/Libraries/LibThreading/Thread.h b/Userland/Libraries/LibThreading/Thread.h index 8bb5398e7f..aa5f9cf745 100644 --- a/Userland/Libraries/LibThreading/Thread.h +++ b/Userland/Libraries/LibThreading/Thread.h @@ -41,10 +41,19 @@ enum class ThreadState : u8 { Joined, }; -class Thread final : public Core::EventReceiver { - C_OBJECT(Thread); - +class Thread final + : public RefCounted + , public Weakable { public: + static NonnullRefPtr construct(Function action, StringView thread_name = {}) + { + return adopt_ref(*new Thread(move(action), thread_name)); + } + static ErrorOr> try_create(Function action, StringView thread_name = {}) + { + return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(action), thread_name)); + } + virtual ~Thread(); ErrorOr set_priority(int priority);