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