detached_tasks.cpp 1004 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. // SPDX-FileCopyrightText: 2018 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <thread>
  4. #include "common/assert.h"
  5. #include "common/detached_tasks.h"
  6. namespace Common {
  7. DetachedTasks* DetachedTasks::instance = nullptr;
  8. DetachedTasks::DetachedTasks() {
  9. ASSERT(instance == nullptr);
  10. instance = this;
  11. }
  12. void DetachedTasks::WaitForAllTasks() {
  13. std::unique_lock lock{mutex};
  14. cv.wait(lock, [this]() { return count == 0; });
  15. }
  16. DetachedTasks::~DetachedTasks() {
  17. WaitForAllTasks();
  18. std::unique_lock lock{mutex};
  19. ASSERT(count == 0);
  20. instance = nullptr;
  21. }
  22. void DetachedTasks::AddTask(std::function<void()> task) {
  23. std::unique_lock lock{instance->mutex};
  24. ++instance->count;
  25. std::thread([task_{std::move(task)}]() {
  26. task_();
  27. std::unique_lock thread_lock{instance->mutex};
  28. --instance->count;
  29. std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock));
  30. }).detach();
  31. }
  32. } // namespace Common