BackgroundAction.cpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. #include <AK/Queue.h>
  8. #include <LibThreading/BackgroundAction.h>
  9. #include <LibThreading/Mutex.h>
  10. #include <LibThreading/Thread.h>
  11. #include <unistd.h>
  12. static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER;
  13. static pthread_cond_t s_condition = PTHREAD_COND_INITIALIZER;
  14. static Queue<Function<void()>>* s_all_actions;
  15. static Threading::Thread* s_background_thread;
  16. static intptr_t background_thread_func()
  17. {
  18. Vector<Function<void()>> actions;
  19. while (true) {
  20. pthread_mutex_lock(&s_mutex);
  21. while (s_all_actions->is_empty())
  22. pthread_cond_wait(&s_condition, &s_mutex);
  23. while (!s_all_actions->is_empty())
  24. actions.append(s_all_actions->dequeue());
  25. pthread_mutex_unlock(&s_mutex);
  26. for (auto& action : actions)
  27. action();
  28. actions.clear();
  29. }
  30. }
  31. static void init()
  32. {
  33. s_all_actions = new Queue<Function<void()>>;
  34. s_background_thread = &Threading::Thread::construct(background_thread_func, "Background Thread"sv).leak_ref();
  35. s_background_thread->start();
  36. }
  37. Threading::Thread& Threading::BackgroundActionBase::background_thread()
  38. {
  39. if (s_background_thread == nullptr)
  40. init();
  41. return *s_background_thread;
  42. }
  43. void Threading::BackgroundActionBase::enqueue_work(Function<void()> work)
  44. {
  45. if (s_all_actions == nullptr)
  46. init();
  47. pthread_mutex_lock(&s_mutex);
  48. s_all_actions->enqueue(move(work));
  49. pthread_cond_broadcast(&s_condition);
  50. pthread_mutex_unlock(&s_mutex);
  51. }