forked from boostorg/beast
Better test::enable_yield_to
This commit is contained in:
@@ -2,6 +2,7 @@ Version 45
|
||||
|
||||
* Workaround for boost::asio::basic_streambuf type check
|
||||
* Fix message doc image
|
||||
* Better test::enable_yield_to
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <beast/core/async_result.hpp>
|
||||
#include <beast/core/bind_handler.hpp>
|
||||
#include <beast/core/buffer_prefix.hpp>
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/websocket/teardown.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
@@ -68,7 +67,7 @@ public:
|
||||
error_code& ec)
|
||||
{
|
||||
auto const n = boost::asio::buffer_copy(
|
||||
buffers, buffer_prefix(read_max_, cb_));
|
||||
buffers, cb_, read_max_);
|
||||
if(n > 0)
|
||||
cb_ = cb_ + n;
|
||||
else
|
||||
|
@@ -35,7 +35,7 @@ private:
|
||||
std::thread thread_;
|
||||
std::mutex m_;
|
||||
std::condition_variable cv_;
|
||||
bool running_ = false;
|
||||
std::size_t running_ = 0;
|
||||
|
||||
public:
|
||||
/// The type of yield context passed to functions.
|
||||
@@ -65,61 +65,65 @@ public:
|
||||
return ios_;
|
||||
}
|
||||
|
||||
/** Run a function in a coroutine.
|
||||
/** Run one or more functions, each in a coroutine.
|
||||
|
||||
This call will block until the coroutine terminates.
|
||||
|
||||
Function will be called with this signature:
|
||||
This call will block until all coroutines terminate.
|
||||
|
||||
Each functions should have this signature:
|
||||
@code
|
||||
void f(args..., yield_context);
|
||||
void f(yield_context);
|
||||
@endcode
|
||||
|
||||
@param f The Callable object to invoke.
|
||||
|
||||
@param args Optional arguments forwarded to the callable object.
|
||||
@param fn... One or more functions to invoke.
|
||||
*/
|
||||
#if BEAST_DOXYGEN
|
||||
template<class F, class... Args>
|
||||
template<class... FN>
|
||||
void
|
||||
yield_to(F&& f, Args&&... args);
|
||||
yield_to(FN&&... fn)
|
||||
#else
|
||||
template<class F>
|
||||
template<class F0, class... FN>
|
||||
void
|
||||
yield_to(F&& f);
|
||||
|
||||
template<class Function, class Arg, class... Args>
|
||||
void
|
||||
yield_to(Function&& f, Arg&& arg, Args&&... args)
|
||||
{
|
||||
yield_to(std::bind(f,
|
||||
std::forward<Arg>(arg),
|
||||
std::forward<Args>(args)...,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
yield_to(F0&& f0, FN&&... fn);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void
|
||||
spawn()
|
||||
{
|
||||
}
|
||||
|
||||
template<class F0, class... FN>
|
||||
void
|
||||
spawn(F0&& f, FN&&... fn);
|
||||
};
|
||||
|
||||
template<class Function>
|
||||
template<class F0, class... FN>
|
||||
void
|
||||
enable_yield_to::yield_to(Function&& f)
|
||||
enable_yield_to::
|
||||
yield_to(F0&& f0, FN&&... fn)
|
||||
{
|
||||
running_ = 1 + sizeof...(FN);
|
||||
spawn(f0, fn...);
|
||||
std::unique_lock<std::mutex> lock{m_};
|
||||
cv_.wait(lock, [&]{ return running_ == 0; });
|
||||
}
|
||||
|
||||
template<class F0, class... FN>
|
||||
inline
|
||||
void
|
||||
enable_yield_to::
|
||||
spawn(F0&& f, FN&&... fn)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_);
|
||||
running_ = true;
|
||||
}
|
||||
boost::asio::spawn(ios_,
|
||||
[&](boost::asio::yield_context do_yield)
|
||||
[&](yield_context yield)
|
||||
{
|
||||
f(do_yield);
|
||||
std::lock_guard<std::mutex> lock(m_);
|
||||
running_ = false;
|
||||
f(yield);
|
||||
std::lock_guard<std::mutex> lock{m_};
|
||||
if(--running_ == 0)
|
||||
cv_.notify_all();
|
||||
}
|
||||
, boost::coroutines::attributes(2 * 1024 * 1024));
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_);
|
||||
cv_.wait(lock, [&]{ return ! running_; });
|
||||
spawn(fn...);
|
||||
}
|
||||
|
||||
} // test
|
||||
|
@@ -132,7 +132,8 @@ public:
|
||||
{
|
||||
testSpecialMembers();
|
||||
|
||||
yield_to(&self::testRead, this);
|
||||
yield_to([&](yield_context yield){
|
||||
testRead(yield);});
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -319,9 +319,12 @@ public:
|
||||
{
|
||||
testThrow();
|
||||
|
||||
yield_to(&read_test::testFailures, this);
|
||||
yield_to(&read_test::testRead, this);
|
||||
yield_to(&read_test::testEof, this);
|
||||
yield_to([&](yield_context yield){
|
||||
testFailures(yield); });
|
||||
yield_to([&](yield_context yield){
|
||||
testRead(yield); });
|
||||
yield_to([&](yield_context yield){
|
||||
testEof(yield); });
|
||||
|
||||
testIoService();
|
||||
}
|
||||
|
@@ -666,9 +666,12 @@ public:
|
||||
|
||||
void run() override
|
||||
{
|
||||
yield_to(&write_test::testAsyncWriteHeaders, this);
|
||||
yield_to(&write_test::testAsyncWrite, this);
|
||||
yield_to(&write_test::testFailures, this);
|
||||
yield_to([&](yield_context yield){
|
||||
testAsyncWriteHeaders(yield); });
|
||||
yield_to([&](yield_context yield){
|
||||
testAsyncWrite(yield); });
|
||||
yield_to([&](yield_context yield){
|
||||
testFailures(yield); });
|
||||
testOutput();
|
||||
test_std_ostream();
|
||||
testOstream();
|
||||
|
Reference in New Issue
Block a user