/* * Copyright (c) 2019-2020, Sergey Bugaev * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include namespace LibThread { template class BackgroundAction; class BackgroundActionBase { template friend class BackgroundAction; private: BackgroundActionBase() { } static Lockable>>& all_actions(); static Thread& background_thread(); }; template class BackgroundAction final : public Core::Object , private BackgroundActionBase { C_OBJECT(BackgroundAction); public: static NonnullRefPtr> create( Function action, Function on_complete = nullptr) { return adopt_ref(*new BackgroundAction(move(action), move(on_complete))); } virtual ~BackgroundAction() { } private: BackgroundAction(Function action, Function on_complete) : Core::Object(&background_thread()) , m_action(move(action)) , m_on_complete(move(on_complete)) { Locker locker(all_actions().lock()); all_actions().resource().enqueue([this] { m_result = m_action(); if (m_on_complete) { Core::EventLoop::current().post_event(*this, make([this](auto&) { m_on_complete(m_result.release_value()); this->remove_from_parent(); })); Core::EventLoop::wake(); } else { this->remove_from_parent(); } }); } Function m_action; Function m_on_complete; Optional m_result; }; }