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