run.hpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Copyright (c) 2022 Klemens D. Morgenstern
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_COBALT_RUN_HPP
  6. #define BOOST_COBALT_RUN_HPP
  7. #include <boost/cobalt/spawn.hpp>
  8. #include <boost/cobalt/task.hpp>
  9. #include <boost/asio/use_future.hpp>
  10. namespace boost::cobalt
  11. {
  12. template<typename T>
  13. T run(task<T> t)
  14. {
  15. #if !defined(BOOST_COBALT_NO_PMR)
  16. pmr::unsynchronized_pool_resource root_resource{this_thread::get_default_resource()};
  17. struct reset_res
  18. {
  19. void operator()(pmr::memory_resource * res)
  20. {
  21. this_thread::set_default_resource(res);
  22. }
  23. };
  24. std::unique_ptr<pmr::memory_resource, reset_res> pr{
  25. boost::cobalt::this_thread::set_default_resource(&root_resource)};
  26. #endif
  27. std::future<T> f;
  28. {
  29. asio::io_context ctx{BOOST_ASIO_CONCURRENCY_HINT_1};
  30. struct reset_exec
  31. {
  32. std::optional<executor> exec;
  33. reset_exec()
  34. {
  35. if (this_thread::has_executor())
  36. exec = this_thread::get_executor();
  37. }
  38. ~reset_exec()
  39. {
  40. if (exec)
  41. this_thread::set_executor(*exec);
  42. }
  43. };
  44. reset_exec re;
  45. this_thread::set_executor(ctx.get_executor());
  46. f = spawn(ctx, std::move(t), asio::bind_executor(ctx.get_executor(), asio::use_future));
  47. ctx.run();
  48. }
  49. return f.get();
  50. }
  51. }
  52. #endif //BOOST_COBALT_RUN_HPP