detached_tasks.h 1.2 KB

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