BackgroundAction.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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/Lock.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).leak_ref();
  35. s_background_thread->set_name("Background thread");
  36. s_background_thread->start();
  37. }
  38. Threading::Thread& Threading::BackgroundActionBase::background_thread()
  39. {
  40. if (s_background_thread == nullptr)
  41. init();
  42. return *s_background_thread;
  43. }
  44. void Threading::BackgroundActionBase::enqueue_work(Function<void()> work)
  45. {
  46. if (s_all_actions == nullptr)
  47. init();
  48. pthread_mutex_lock(&s_mutex);
  49. s_all_actions->enqueue(move(work));
  50. pthread_cond_broadcast(&s_condition);
  51. pthread_mutex_unlock(&s_mutex);
  52. }