coroutine.hpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. #ifndef __COROUTINE_HPP__
  2. #define __COROUTINE_HPP__
  3. #include <vector>
  4. #include <boost/coroutine2/coroutine.hpp>
  5. #include "mpcio.hpp"
  6. typedef boost::coroutines2::coroutine<void>::pull_type coro_t;
  7. typedef boost::coroutines2::coroutine<void>::push_type yield_t;
  8. // The top-level coroutine runner will call run_coroutines with
  9. // a MPCTIO, and we should call its send() method. Subcoroutines that
  10. // launch their own coroutines (and coroutine running) will call
  11. // run_coroutines with a yield_t instead, which we should just call, in
  12. // order to yield to the next higher level of coroutine runner.
  13. static inline void send_or_yield(MPCTIO &tio) { tio.send(); }
  14. static inline void send_or_yield(yield_t &yield) { yield(); }
  15. template <typename T>
  16. inline void run_coroutines(T &mpctio_or_yield, std::vector<coro_t> &coroutines) {
  17. // Loop until all the coroutines are finished
  18. bool finished = false;
  19. while(!finished) {
  20. // If this current function is not itself a coroutine (i.e.,
  21. // this is the top-level function that launches all the
  22. // coroutines), here's where to call send(). Otherwise, call
  23. // yield() here to let other coroutines at this level run.
  24. send_or_yield(mpctio_or_yield);
  25. finished = true;
  26. for (auto &c : coroutines) {
  27. // This tests if coroutine c still has work to do (is not
  28. // finished)
  29. if (c) {
  30. finished = false;
  31. // Resume coroutine c from the point it yield()ed
  32. c();
  33. }
  34. }
  35. }
  36. }
  37. #endif