rippled
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#ifndef BEAST_TEST_YIELD_TO_HPP
6#define BEAST_TEST_YIELD_TO_HPP
7
8#include <boost/asio/executor_work_guard.hpp>
9#include <boost/asio/io_context.hpp>
10#include <boost/asio/spawn.hpp>
11#include <boost/optional.hpp>
12#include <boost/thread/csbl/memory/allocator_arg.hpp>
13
14#include <condition_variable>
15#include <mutex>
16#include <thread>
17#include <vector>
18
19namespace beast {
20namespace test {
21
29{
30protected:
31 boost::asio::io_context ios_;
32
33private:
34 boost::optional<boost::asio::executor_work_guard<
35 boost::asio::io_context::executor_type>>
41
42public:
44 using yield_context = boost::asio::yield_context;
45
46 explicit enable_yield_to(std::size_t concurrency = 1)
47 : work_(boost::asio::make_work_guard(ios_))
48 {
49 threads_.reserve(concurrency);
50 while (concurrency--)
51 threads_.emplace_back([&] { ios_.run(); });
52 }
53
55 {
56 work_ = boost::none;
57 for (auto& t : threads_)
58 t.join();
59 }
60
62 boost::asio::io_context&
64 {
65 return ios_;
66 }
67
79#if BEAST_DOXYGEN
80 template <class... FN>
81 void
82 yield_to(FN&&... fn);
83#else
84 template <class F0, class... FN>
85 void
86 yield_to(F0&& f0, FN&&... fn);
87#endif
88
89private:
90 void
92 {
93 }
94
95 template <class F0, class... FN>
96 void
97 spawn(F0&& f, FN&&... fn);
98};
99
100template <class F0, class... FN>
101void
102enable_yield_to::yield_to(F0&& f0, FN&&... fn)
103{
104 running_ = 1 + sizeof...(FN);
105 spawn(f0, fn...);
107 cv_.wait(lock, [&] { return running_ == 0; });
108}
109
110template <class F0, class... FN>
111inline void
112enable_yield_to::spawn(F0&& f, FN&&... fn)
113{
114 boost::asio::spawn(
115 ios_,
116 boost::allocator_arg,
117 boost::context::fixedsize_stack(2 * 1024 * 1024),
118 [&](yield_context yield) {
119 f(yield);
120 std::lock_guard lock{m_};
121 if (--running_ == 0)
122 cv_.notify_all();
123 },
124 [](std::exception_ptr e) {
125 if (e)
127 });
128 spawn(fn...);
129}
130
131} // namespace test
132} // namespace beast
133
134#endif
Mix-in to support tests using asio coroutines.
Definition yield_to.h:29
boost::asio::io_context & get_io_context()
Return the io_context associated with the object.
Definition yield_to.h:63
enable_yield_to(std::size_t concurrency=1)
Definition yield_to.h:46
boost::asio::yield_context yield_context
The type of yield context passed to functions.
Definition yield_to.h:44
std::condition_variable cv_
Definition yield_to.h:39
void yield_to(F0 &&f0, FN &&... fn)
Run one or more functions, each in a coroutine.
Definition yield_to.h:102
boost::asio::io_context ios_
Definition yield_to.h:31
std::vector< std::thread > threads_
Definition yield_to.h:37
boost::optional< boost::asio::executor_work_guard< boost::asio::io_context::executor_type > > work_
Definition yield_to.h:36
T emplace_back(T... args)
T reserve(T... args)
T rethrow_exception(T... args)