detached_tasks.h 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. // SPDX-FileCopyrightText: 2018 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <condition_variable>
  5. #include <functional>
  6. namespace Common {
  7. /**
  8. * A background manager which ensures that all detached task is finished before program exits.
  9. *
  10. * Some tasks, telemetry submission for example, prefer executing asynchronously and don't care
  11. * about the result. These tasks are suitable for std::thread::detach(). However, this is unsafe if
  12. * the task is launched just before the program exits (which is a common case for telemetry), so we
  13. * need to block on these tasks on program exit.
  14. *
  15. * To make detached task safe, a single DetachedTasks object should be placed in the main(), and
  16. * call WaitForAllTasks() after all program execution but before global/static variable destruction.
  17. * Any potentially unsafe detached task should be executed via DetachedTasks::AddTask.
  18. */
  19. class DetachedTasks {
  20. public:
  21. DetachedTasks();
  22. ~DetachedTasks();
  23. void WaitForAllTasks();
  24. static void AddTask(std::function<void()> task);
  25. private:
  26. static DetachedTasks* instance;
  27. std::condition_variable cv;
  28. std::mutex mutex;
  29. int count = 0;
  30. };
  31. } // namespace Common