xrpld
Loading...
Searching...
No Matches
yield_to.h
1// Distributed under the Boost Software License, Version 1.0. (See accompanying
2// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
3//
4
5#pragma once
6
7#include <boost/asio/executor_work_guard.hpp>
8#include <boost/asio/io_context.hpp>
9#include <boost/asio/spawn.hpp>
10#include <boost/optional.hpp>
11#include <boost/thread/csbl/memory/allocator_arg.hpp>
12
13#include <condition_variable>
14#include <mutex>
15#include <thread>
16#include <vector>
17
18namespace beast::test {
19
27{
28protected:
29 boost::asio::io_context ios_;
30
31private:
32 boost::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
37
38public:
40 using yield_context = boost::asio::yield_context;
41
42 explicit EnableYieldTo(std::size_t concurrency = 1) : work_(boost::asio::make_work_guard(ios_))
43 {
44 threads_.reserve(concurrency);
45 for (std::size_t i = 0; i < concurrency; ++i)
46 {
47 threads_.emplace_back([&] { ios_.run(); });
48 }
49 }
50
52 {
53 work_ = boost::none;
54 for (auto& t : threads_)
55 t.join();
56 }
57
59 boost::asio::io_context&
61 {
62 return ios_;
63 }
64
76#if BEAST_DOXYGEN
77 template <class... FN>
78 void
79 yield_to(FN&&... fn);
80#else
81 template <class F0, class... FN>
82 void
83 yieldTo(F0&& f0, FN&&... fn);
84#endif
85
86private:
87 void
89 {
90 }
91
92 template <class F0, class... FN>
93 void
94 spawn(F0&& f, FN&&... fn);
95};
96
97template <class F0, class... FN>
98void
99EnableYieldTo::yieldTo(F0&& f0, FN&&... fn)
100{
101 running_ = 1 + sizeof...(FN);
102 spawn(f0, fn...);
104 cv_.wait(lock, [&] { return running_ == 0; });
105}
106
107template <class F0, class... FN>
108inline void
109EnableYieldTo::spawn(F0&& f, FN&&... fn)
110{
111 boost::asio::spawn(
112 ios_,
113 boost::allocator_arg,
114 boost::context::fixedsize_stack(2 * 1024 * 1024),
115 [&](yield_context yield) {
116 f(yield);
117 std::scoped_lock const lock{m_};
118 if (--running_ == 0)
119 cv_.notify_all();
120 },
121 [](std::exception_ptr e) {
122 if (e)
124 });
125 spawn(fn...);
126}
127
128} // namespace beast::test
EnableYieldTo(std::size_t concurrency=1)
Definition yield_to.h:42
std::condition_variable cv_
Definition yield_to.h:35
std::vector< std::thread > threads_
Definition yield_to.h:33
boost::asio::io_context ios_
Definition yield_to.h:29
boost::asio::io_context & getIoContext()
Return the io_context associated with the object.
Definition yield_to.h:60
boost::asio::yield_context yield_context
The type of yield context passed to functions.
Definition yield_to.h:40
boost::optional< boost::asio::executor_work_guard< boost::asio::io_context::executor_type > > work_
Definition yield_to.h:32
void yieldTo(F0 &&f0, FN &&... fn)
Run one or more functions, each in a coroutine.
Definition yield_to.h:99
T rethrow_exception(T... args)