rippled
Loading...
Searching...
No Matches
yield_to.h
1//
2// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#ifndef BEAST_TEST_YIELD_TO_HPP
9#define BEAST_TEST_YIELD_TO_HPP
10
11#include <boost/asio/executor_work_guard.hpp>
12#include <boost/asio/io_context.hpp>
13#include <boost/asio/spawn.hpp>
14#include <boost/optional.hpp>
15#include <boost/thread/csbl/memory/allocator_arg.hpp>
16
17#include <condition_variable>
18#include <mutex>
19#include <thread>
20#include <vector>
21
22namespace beast {
23namespace test {
24
32{
33protected:
34 boost::asio::io_context ios_;
35
36private:
37 boost::optional<boost::asio::executor_work_guard<
38 boost::asio::io_context::executor_type>>
44
45public:
47 using yield_context = boost::asio::yield_context;
48
49 explicit enable_yield_to(std::size_t concurrency = 1)
50 : work_(boost::asio::make_work_guard(ios_))
51 {
52 threads_.reserve(concurrency);
53 while (concurrency--)
54 threads_.emplace_back([&] { ios_.run(); });
55 }
56
58 {
59 work_ = boost::none;
60 for (auto& t : threads_)
61 t.join();
62 }
63
65 boost::asio::io_context&
67 {
68 return ios_;
69 }
70
82#if BEAST_DOXYGEN
83 template <class... FN>
84 void
85 yield_to(FN&&... fn);
86#else
87 template <class F0, class... FN>
88 void
89 yield_to(F0&& f0, FN&&... fn);
90#endif
91
92private:
93 void
95 {
96 }
97
98 template <class F0, class... FN>
99 void
100 spawn(F0&& f, FN&&... fn);
101};
102
103template <class F0, class... FN>
104void
105enable_yield_to::yield_to(F0&& f0, FN&&... fn)
106{
107 running_ = 1 + sizeof...(FN);
108 spawn(f0, fn...);
110 cv_.wait(lock, [&] { return running_ == 0; });
111}
112
113template <class F0, class... FN>
114inline void
115enable_yield_to::spawn(F0&& f, FN&&... fn)
116{
117 boost::asio::spawn(
118 ios_,
119 boost::allocator_arg,
120 boost::context::fixedsize_stack(2 * 1024 * 1024),
121 [&](yield_context yield) {
122 f(yield);
123 std::lock_guard lock{m_};
124 if (--running_ == 0)
125 cv_.notify_all();
126 },
127 [](std::exception_ptr e) {
128 if (e)
130 });
131 spawn(fn...);
132}
133
134} // namespace test
135} // namespace beast
136
137#endif
Mix-in to support tests using asio coroutines.
Definition yield_to.h:32
boost::asio::io_context & get_io_context()
Return the io_context associated with the object.
Definition yield_to.h:66
enable_yield_to(std::size_t concurrency=1)
Definition yield_to.h:49
boost::asio::yield_context yield_context
The type of yield context passed to functions.
Definition yield_to.h:47
std::condition_variable cv_
Definition yield_to.h:42
void yield_to(F0 &&f0, FN &&... fn)
Run one or more functions, each in a coroutine.
Definition yield_to.h:105
boost::asio::io_context ios_
Definition yield_to.h:34
std::vector< std::thread > threads_
Definition yield_to.h:40
boost::optional< boost::asio::executor_work_guard< boost::asio::io_context::executor_type > > work_
Definition yield_to.h:39
T emplace_back(T... args)
T reserve(T... args)
T rethrow_exception(T... args)