Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.7KB

  1. //
  2. // impl/co_spawn.hpp
  3. // ~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_IMPL_CO_SPAWN_HPP
  11. #define ASIO_IMPL_CO_SPAWN_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/awaitable.hpp"
  17. #include "asio/dispatch.hpp"
  18. #include "asio/post.hpp"
  19. #include "asio/use_awaitable.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. namespace asio {
  22. namespace detail {
  23. template <typename T, typename Executor, typename F, typename Handler>
  24. awaitable<void, Executor> co_spawn_entry_point(
  25. awaitable<T, Executor>*, Executor ex, F f, Handler handler)
  26. {
  27. auto spawn_work = make_work_guard(ex);
  28. auto handler_work = make_work_guard(handler, ex);
  29. (void) co_await (post)(spawn_work.get_executor(),
  30. use_awaitable_t<Executor>{});
  31. bool done = false;
  32. try
  33. {
  34. T t = co_await f();
  35. done = true;
  36. (dispatch)(handler_work.get_executor(),
  37. [handler = std::move(handler), t = std::move(t)]() mutable
  38. {
  39. handler(std::exception_ptr(), std::move(t));
  40. });
  41. }
  42. catch (...)
  43. {
  44. if (done)
  45. throw;
  46. (dispatch)(handler_work.get_executor(),
  47. [handler = std::move(handler), e = std::current_exception()]() mutable
  48. {
  49. handler(e, T());
  50. });
  51. }
  52. }
  53. template <typename Executor, typename F, typename Handler>
  54. awaitable<void, Executor> co_spawn_entry_point(
  55. awaitable<void, Executor>*, Executor ex, F f, Handler handler)
  56. {
  57. auto spawn_work = make_work_guard(ex);
  58. auto handler_work = make_work_guard(handler, ex);
  59. (void) co_await (post)(spawn_work.get_executor(),
  60. use_awaitable_t<Executor>{});
  61. std::exception_ptr e = nullptr;
  62. try
  63. {
  64. co_await f();
  65. }
  66. catch (...)
  67. {
  68. e = std::current_exception();
  69. }
  70. (dispatch)(handler_work.get_executor(),
  71. [handler = std::move(handler), e]() mutable
  72. {
  73. handler(e);
  74. });
  75. }
  76. struct initiate_co_spawn
  77. {
  78. template <typename Handler, typename Executor, typename F>
  79. void operator()(Handler&& handler, const Executor& ex, F&& f) const
  80. {
  81. typedef typename result_of<F()>::type awaitable_type;
  82. typedef typename awaitable_type::executor_type executor_type;
  83. executor_type ex2(ex);
  84. auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),
  85. ex2, std::forward<F>(f), std::forward<Handler>(handler));
  86. awaitable_handler<executor_type, void>(std::move(a), ex2).launch();
  87. }
  88. };
  89. } // namespace detail
  90. template <typename Executor, typename F, typename CompletionToken>
  91. inline ASIO_INITFN_RESULT_TYPE(CompletionToken,
  92. typename detail::awaitable_signature<typename result_of<F()>::type>::type)
  93. co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
  94. typename enable_if<
  95. is_executor<Executor>::value
  96. >::type*)
  97. {
  98. return async_initiate<CompletionToken,
  99. typename detail::awaitable_signature<typename result_of<F()>::type>>(
  100. detail::initiate_co_spawn(), token, ex, std::forward<F>(f));
  101. }
  102. template <typename ExecutionContext, typename F, typename CompletionToken>
  103. inline ASIO_INITFN_RESULT_TYPE(CompletionToken,
  104. typename detail::awaitable_signature<typename result_of<F()>::type>::type)
  105. co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
  106. typename enable_if<
  107. is_convertible<ExecutionContext&, execution_context&>::value
  108. >::type*)
  109. {
  110. return (co_spawn)(ctx.get_executor(), std::forward<F>(f),
  111. std::forward<CompletionToken>(token));
  112. }
  113. } // namespace asio
  114. #include "asio/detail/pop_options.hpp"
  115. #endif // ASIO_IMPL_CO_SPAWN_HPP