mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 06:14:58 +00:00
LibThreading: Remove Thread's inheritance from Core::EventReceiver
Inheritance from `EventReceiver` on the `Thread` class was only used in the `BackgroundAction` class, where the children vector was keeping the action alive until the work was completed. However, this can be accomplished by instead capturing a `NonnullRefPtr` of `this`. The work function can then avoid having to remove the `BackgroundAction` from its parent `Thread` when the work completes.
This commit is contained in:
parent
925afcd4b0
commit
71df0ee994
3 changed files with 28 additions and 29 deletions
|
@ -55,8 +55,7 @@ public:
|
|||
|
||||
private:
|
||||
BackgroundAction(Function<ErrorOr<Result>(BackgroundAction&)> action, Function<ErrorOr<void>(Result)> on_complete, Optional<Function<void(Error)>> 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();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
namespace Threading {
|
||||
|
||||
Thread::Thread(Function<intptr_t()> 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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -41,10 +41,19 @@ enum class ThreadState : u8 {
|
|||
Joined,
|
||||
};
|
||||
|
||||
class Thread final : public Core::EventReceiver {
|
||||
C_OBJECT(Thread);
|
||||
|
||||
class Thread final
|
||||
: public RefCounted<Thread>
|
||||
, public Weakable<Thread> {
|
||||
public:
|
||||
static NonnullRefPtr<Thread> construct(Function<intptr_t()> action, StringView thread_name = {})
|
||||
{
|
||||
return adopt_ref(*new Thread(move(action), thread_name));
|
||||
}
|
||||
static ErrorOr<NonnullRefPtr<Thread>> try_create(Function<intptr_t()> action, StringView thread_name = {})
|
||||
{
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(action), thread_name));
|
||||
}
|
||||
|
||||
virtual ~Thread();
|
||||
|
||||
ErrorOr<void> set_priority(int priority);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue