BackgroundAction.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
  3. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Function.h>
  9. #include <AK/NonnullRefPtr.h>
  10. #include <AK/Optional.h>
  11. #include <AK/Queue.h>
  12. #include <LibCore/Event.h>
  13. #include <LibCore/EventLoop.h>
  14. #include <LibCore/Object.h>
  15. #include <LibThreading/Thread.h>
  16. namespace Threading {
  17. template<typename Result>
  18. class BackgroundAction;
  19. class BackgroundActionBase {
  20. template<typename Result>
  21. friend class BackgroundAction;
  22. private:
  23. BackgroundActionBase() { }
  24. static void enqueue_work(Function<void()>);
  25. static Thread& background_thread();
  26. };
  27. template<typename Result>
  28. class BackgroundAction final : public Core::Object
  29. , private BackgroundActionBase {
  30. C_OBJECT(BackgroundAction);
  31. public:
  32. void cancel()
  33. {
  34. m_cancelled = true;
  35. }
  36. bool is_cancelled() const
  37. {
  38. return m_cancelled;
  39. }
  40. virtual ~BackgroundAction() { }
  41. private:
  42. BackgroundAction(Function<Result(BackgroundAction&)> action, Function<void(Result)> on_complete)
  43. : Core::Object(&background_thread())
  44. , m_action(move(action))
  45. , m_on_complete(move(on_complete))
  46. {
  47. enqueue_work([this] {
  48. m_result = m_action(*this);
  49. if (m_on_complete) {
  50. deferred_invoke([this] {
  51. m_on_complete(m_result.release_value());
  52. remove_from_parent();
  53. });
  54. Core::EventLoop::wake();
  55. } else {
  56. this->remove_from_parent();
  57. }
  58. });
  59. }
  60. bool m_cancelled { false };
  61. Function<Result(BackgroundAction&)> m_action;
  62. Function<void(Result)> m_on_complete;
  63. Optional<Result> m_result;
  64. };
  65. }