fiber.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <functional>
  5. #include <memory>
  6. namespace boost::context::detail {
  7. struct transfer_t;
  8. }
  9. namespace Common {
  10. /**
  11. * Fiber class
  12. * a fiber is a userspace thread with it's own context. They can be used to
  13. * implement coroutines, emulated threading systems and certain asynchronous
  14. * patterns.
  15. *
  16. * This class implements fibers at a low level, thus allowing greater freedom
  17. * to implement such patterns. This fiber class is 'threadsafe' only one fiber
  18. * can be running at a time and threads will be locked while trying to yield to
  19. * a running fiber until it yields. WARNING exchanging two running fibers between
  20. * threads will cause a deadlock. In order to prevent a deadlock, each thread should
  21. * have an intermediary fiber, you switch to the intermediary fiber of the current
  22. * thread and then from it switch to the expected fiber. This way you can exchange
  23. * 2 fibers within 2 different threads.
  24. */
  25. class Fiber {
  26. public:
  27. Fiber(std::function<void()>&& entry_point_func);
  28. ~Fiber();
  29. Fiber(const Fiber&) = delete;
  30. Fiber& operator=(const Fiber&) = delete;
  31. Fiber(Fiber&&) = default;
  32. Fiber& operator=(Fiber&&) = default;
  33. /// Yields control from Fiber 'from' to Fiber 'to'
  34. /// Fiber 'from' must be the currently running fiber.
  35. static void YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to);
  36. [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
  37. void SetRewindPoint(std::function<void()>&& rewind_func);
  38. void Rewind();
  39. /// Only call from main thread's fiber
  40. void Exit();
  41. private:
  42. Fiber();
  43. void OnRewind(boost::context::detail::transfer_t& transfer);
  44. void Start(boost::context::detail::transfer_t& transfer);
  45. static void FiberStartFunc(boost::context::detail::transfer_t transfer);
  46. static void RewindStartFunc(boost::context::detail::transfer_t transfer);
  47. struct FiberImpl;
  48. std::unique_ptr<FiberImpl> impl;
  49. };
  50. } // namespace Common