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/io_service.hpp>
12#include <boost/asio/spawn.hpp>
13#include <boost/optional.hpp>
14
15#include <condition_variable>
16#include <functional>
17#include <mutex>
18#include <thread>
19#include <vector>
20
21namespace beast {
22namespace test {
23
31{
32protected:
33 boost::asio::io_service ios_;
34
35private:
36 boost::optional<boost::asio::io_service::work> work_;
41
42public:
44 using yield_context = boost::asio::yield_context;
45
46 explicit enable_yield_to(std::size_t concurrency = 1) : work_(ios_)
47 {
48 threads_.reserve(concurrency);
49 while (concurrency--)
50 threads_.emplace_back([&] { ios_.run(); });
51 }
52
54 {
55 work_ = boost::none;
56 for (auto& t : threads_)
57 t.join();
58 }
59
61 boost::asio::io_service&
63 {
64 return ios_;
65 }
66
78#if BEAST_DOXYGEN
79 template <class... FN>
80 void
81 yield_to(FN&&... fn);
82#else
83 template <class F0, class... FN>
84 void
85 yield_to(F0&& f0, FN&&... fn);
86#endif
87
88private:
89 void
91 {
92 }
93
94 template <class F0, class... FN>
95 void
96 spawn(F0&& f, FN&&... fn);
97};
98
99template <class F0, class... FN>
100void
101enable_yield_to::yield_to(F0&& f0, FN&&... fn)
102{
103 running_ = 1 + sizeof...(FN);
104 spawn(f0, fn...);
106 cv_.wait(lock, [&] { return running_ == 0; });
107}
108
109template <class F0, class... FN>
110inline void
111enable_yield_to::spawn(F0&& f, FN&&... fn)
112{
113 boost::asio::spawn(
114 ios_,
115 [&](yield_context yield) {
116 f(yield);
117 std::lock_guard lock{m_};
118 if (--running_ == 0)
119 cv_.notify_all();
120 },
121 boost::coroutines::attributes(2 * 1024 * 1024));
122 spawn(fn...);
123}
124
125} // namespace test
126} // namespace beast
127
128#endif
Mix-in to support tests using asio coroutines.
Definition: yield_to.h:31
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:101
boost::optional< boost::asio::io_service::work > work_
Definition: yield_to.h:36
boost::asio::io_service & get_io_service()
Return the io_service associated with the object.
Definition: yield_to.h:62
std::vector< std::thread > threads_
Definition: yield_to.h:37
boost::asio::io_service ios_
Definition: yield_to.h:33
T emplace_back(T... args)
T reserve(T... args)