mirror of
https://github.com/boostorg/cobalt.git
synced 2026-01-19 04:02:16 +00:00
composition is not experimental anymore.
composition fix for immediate completion.
This commit is contained in:
committed by
Klemens Morgenstern
parent
6e5713de52
commit
0f502f36fc
@@ -24,7 +24,6 @@ constant boost_dependencies :
|
||||
/boost/static_string//boost_static_string
|
||||
/boost/system//boost_system
|
||||
/boost/throw_exception//boost_throw_exception
|
||||
/boost/url//boost_url
|
||||
/boost/variant2//boost_variant2 ;
|
||||
|
||||
project /boost/cobalt
|
||||
|
||||
@@ -77,10 +77,9 @@ include::reference/thread.adoc[]
|
||||
include::reference/result.adoc[]
|
||||
include::reference/async_for.adoc[]
|
||||
include::reference/error.adoc[]
|
||||
include::reference/composition.adoc[]
|
||||
include::reference/config.adoc[]
|
||||
|
||||
include::reference/experimental/context.adoc[]
|
||||
|
||||
include::reference/io/buffer.adoc[]
|
||||
include::reference/io/ops.adoc[]
|
||||
include::reference/io/steady_timer.adoc[]
|
||||
@@ -104,6 +103,9 @@ include::reference/io/resolver.adoc[]
|
||||
include::reference/io/acceptor.adoc[]
|
||||
include::reference/io/ssl.adoc[]
|
||||
|
||||
include::reference/experimental/context.adoc[]
|
||||
|
||||
|
||||
= In-Depth
|
||||
|
||||
include::background/custom_executors.adoc[]
|
||||
|
||||
41
doc/reference/composition.adoc
Normal file
41
doc/reference/composition.adoc
Normal file
@@ -0,0 +1,41 @@
|
||||
[#detached]
|
||||
== cobalt/composition.hpp
|
||||
|
||||
Including the `cobalt/composition.hpp` provides definitions to turn any function that
|
||||
takes a `cobalt::completion_handler` as it's last argument. This allows simple creation of composed operations.
|
||||
|
||||
Results of `co_await` statements automatically get turned into tuples (akin to used `as_tuple`) to avoid exceptions.
|
||||
|
||||
The results need to be `co_return`-ed. The Handler passed into the coroutine must not be touched.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
struct echo_op final : op<system::error_code>
|
||||
{
|
||||
echo_op(cobalt::io::stream & str) : stream(str) {}
|
||||
void initiate(completion_handler<system::error_code>) final;
|
||||
cobalt::io::stream & str;
|
||||
};
|
||||
|
||||
void echo_op::initiate(completion_handler<system::error_code, std::size_t>)
|
||||
{
|
||||
char buf[4096];
|
||||
auto [ec, n] = co_await str.read_some(buf);
|
||||
|
||||
auto buf = asio::buffer(buf, n);
|
||||
|
||||
while (!ec && !buf.empty() && !!co_await this_coro::cancelled)
|
||||
{
|
||||
std::tie(ec, n) = co_await str.write_some(buf);
|
||||
buf += n;
|
||||
}
|
||||
|
||||
if (!!co_await this_coro::cancelled)
|
||||
co_return {asio::error::operation_aborted, m};
|
||||
else
|
||||
co_return {system::error_code{}, m};
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ foreach(SRC ${ALL_EXAMPLES})
|
||||
add_executable(boost_cobalt_example_${NAME} ${SRC})
|
||||
target_link_libraries(boost_cobalt_example_${NAME} PUBLIC Boost::cobalt Boost::cobalt::io OpenSSL::SSL)
|
||||
target_compile_definitions(boost_cobalt_example_${NAME} PUBLIC)
|
||||
if (NAME STREQUAL python)
|
||||
if (NAME STREQUAL echo_server)
|
||||
target_link_libraries(boost_cobalt_example_${NAME} PUBLIC Boost::cobalt::io)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -23,7 +23,7 @@ project : requirements
|
||||
exe channel : channel.cpp /boost/cobalt//boost_cobalt ;
|
||||
exe delay : delay.cpp /boost/cobalt//boost_cobalt ;
|
||||
exe delay_op : delay_op.cpp /boost/cobalt//boost_cobalt ;
|
||||
exe echo_server : echo_server.cpp /boost/cobalt//boost_cobalt ;
|
||||
exe echo_server : echo_server.cpp /boost/cobalt//boost_cobalt /boost/cobalt//boost_cobalt_io ;
|
||||
exe outcome : outcome.cpp /boost/cobalt//boost_cobalt /boost/outcome//boost_outcome ;
|
||||
exe thread : thread.cpp /boost/cobalt//boost_cobalt ;
|
||||
exe thread_pool : thread_pool.cpp /boost/cobalt//boost_cobalt ;
|
||||
|
||||
@@ -153,6 +153,15 @@ struct composition_promise
|
||||
auto exec = handler.get_executor();
|
||||
auto ho = handler.self.release();
|
||||
detail::self_destroy(h, exec);
|
||||
|
||||
if (handler.completed_immediately != nullptr
|
||||
&& *handler.completed_immediately == completed_immediately_t::initiating)
|
||||
//not maybe here, because we don't go through the immediate executor
|
||||
{
|
||||
*handler.completed_immediately = completed_immediately_t::yes;
|
||||
return std::noop_coroutine();
|
||||
}
|
||||
|
||||
return ho;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
namespace boost::cobalt::io
|
||||
{
|
||||
|
||||
struct acceptor
|
||||
struct BOOST_SYMBOL_VISIBLE acceptor
|
||||
{
|
||||
using wait_type = asio::socket_base::wait_type;
|
||||
constexpr static std::size_t max_listen_connections = asio::socket_base::max_listen_connections;
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/static_string.hpp>
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/url/static_url.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -15,16 +15,15 @@
|
||||
#include <boost/cobalt/promise.hpp>
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/url/url_view.hpp>
|
||||
|
||||
namespace boost::cobalt::io
|
||||
{
|
||||
|
||||
struct resolver
|
||||
struct BOOST_SYMBOL_VISIBLE resolver
|
||||
{
|
||||
using flags = asio::ip::resolver_base::flags;
|
||||
|
||||
resolver(const executor & exec = this_thread::get_executor());
|
||||
resolver(resolver && ) = delete;
|
||||
|
||||
@@ -37,37 +36,39 @@ struct resolver
|
||||
void initiate(completion_handler<system::error_code, endpoint_sequence> h) override;
|
||||
|
||||
resolve_op_(asio::ip::basic_resolver<protocol_type, executor> & resolver,
|
||||
std::string_view host, std::string_view service)
|
||||
: resolver_(resolver), host_(host), service_(service) {}
|
||||
std::string_view host, std::string_view service, flags flags_ = {})
|
||||
: resolver_(resolver), host_(host), service_(service), flags_(flags_) {}
|
||||
private:
|
||||
asio::ip::basic_resolver<protocol_type, executor> & resolver_;
|
||||
std::string_view host_;
|
||||
std::string_view service_;
|
||||
|
||||
flags flags_;
|
||||
};
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto resolve(std::string_view host, std::string_view service)
|
||||
[[nodiscard]] auto resolve(std::string_view host, std::string_view service,
|
||||
flags flags_ = {})
|
||||
{
|
||||
return resolve_op_{resolver_, host, service};
|
||||
return resolve_op_{resolver_, host, service, flags_};
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
asio::ip::basic_resolver<protocol_type, executor> resolver_;
|
||||
};
|
||||
|
||||
struct lookup : op<system::error_code, endpoint_sequence>
|
||||
struct BOOST_SYMBOL_VISIBLE lookup : op<system::error_code, endpoint_sequence>
|
||||
{
|
||||
lookup(std::string_view host, std::string_view service,
|
||||
const executor & exec = this_thread::get_executor())
|
||||
: host_(host), service_(service), resolver_{exec} {}
|
||||
const executor & exec = this_thread::get_executor(),
|
||||
resolver::flags flags_ = {})
|
||||
: host_(host), service_(service), resolver_{exec}, flags_{flags_} {}
|
||||
BOOST_COBALT_IO_DECL void initiate(completion_handler<system::error_code, endpoint_sequence> h) final override;
|
||||
|
||||
private:
|
||||
std::string_view host_;
|
||||
std::string_view service_;
|
||||
asio::ip::basic_resolver<protocol_type, executor> resolver_;
|
||||
resolver::flags flags_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
#include <boost/cobalt/io/acceptor.hpp>
|
||||
#include <boost/cobalt/experimental/composition.hpp>
|
||||
#include <boost/cobalt/composition.hpp>
|
||||
|
||||
namespace boost::cobalt::io
|
||||
{
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#include <boost/cobalt/io/endpoint.hpp>
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
|
||||
#include <boost/url/parse.hpp>
|
||||
#include <boost/url/url_view.hpp>
|
||||
|
||||
namespace boost::cobalt::detail
|
||||
{
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
#include <boost/cobalt/io/read.hpp>
|
||||
#include <boost/cobalt/experimental/composition.hpp>
|
||||
#include <boost/cobalt/composition.hpp>
|
||||
|
||||
#include <boost/asio/read_at.hpp>
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ struct transformer
|
||||
r.assign(rr.begin(), rr.end());
|
||||
|
||||
return asio::deferred.values(ec, std::move(r));
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,14 +36,14 @@ struct transformer
|
||||
void resolver::resolve_op_::initiate(completion_handler<system::error_code, endpoint_sequence> h)
|
||||
{
|
||||
resolver_.async_resolve(
|
||||
cobalt::io::ip, host_, service_,
|
||||
cobalt::io::ip, host_, service_, flags_,
|
||||
asio::deferred(transformer{}))(std::move(h));
|
||||
}
|
||||
|
||||
void lookup::initiate(completion_handler<system::error_code, endpoint_sequence> h)
|
||||
{
|
||||
resolver_.async_resolve(
|
||||
cobalt::io::ip, host_, service_,
|
||||
cobalt::io::ip, host_, service_, flags_,
|
||||
asio::deferred(transformer{}))(std::move(h));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
#include <boost/cobalt/io/write.hpp>
|
||||
#include <boost/cobalt/experimental/composition.hpp>
|
||||
#include <boost/cobalt/composition.hpp>
|
||||
|
||||
namespace boost::cobalt::io
|
||||
{
|
||||
|
||||
@@ -11,7 +11,8 @@ add_executable(boost_cobalt_main_compile EXCLUDE_FROM_ALL main_compile.cpp)
|
||||
add_executable(boost_cobalt_basic_tests EXCLUDE_FROM_ALL
|
||||
async_for.cpp test_main.cpp promise.cpp with.cpp op.cpp handler.cpp join.cpp race.cpp this_coro.cpp
|
||||
channel.cpp generator.cpp run.cpp task.cpp gather.cpp wait_group.cpp wrappers.cpp left_race.cpp
|
||||
strand.cpp fork.cpp thread.cpp any_completion_handler.cpp detached.cpp monotonic_resource.cpp sbo_resource.cpp)
|
||||
strand.cpp fork.cpp thread.cpp any_completion_handler.cpp detached.cpp monotonic_resource.cpp sbo_resource.cpp
|
||||
composition.cpp)
|
||||
|
||||
target_link_libraries(boost_cobalt_main Boost::cobalt)
|
||||
target_link_libraries(boost_cobalt_main_compile Boost::cobalt)
|
||||
@@ -20,7 +21,7 @@ target_link_libraries(boost_cobalt_basic_tests Boost::cobalt Boost::unit_test_f
|
||||
add_test(NAME boost_cobalt_main COMMAND boost_cobalt_main)
|
||||
add_test(NAME boost_cobalt_basic_tests COMMAND boost_cobalt_basic_tests)
|
||||
|
||||
add_executable(boost_cobalt_experimental EXCLUDE_FROM_ALL test_main.cpp experimental/context.cpp experimental/yield_context.cpp experimental/composition.cpp)
|
||||
add_executable(boost_cobalt_experimental EXCLUDE_FROM_ALL test_main.cpp experimental/context.cpp experimental/yield_context.cpp)
|
||||
target_link_libraries(boost_cobalt_experimental Boost::cobalt Boost::unit_test_framework Boost::context)
|
||||
add_test(NAME boost_cobalt_experimental COMMAND boost_cobalt_experimental)
|
||||
|
||||
@@ -33,6 +34,7 @@ add_executable(boost_cobalt_io_test EXCLUDE_FROM_ALL
|
||||
io/sleep.cpp
|
||||
io/pipe.cpp
|
||||
io/endpoint.cpp
|
||||
io/lookup.cpp
|
||||
)
|
||||
target_link_libraries(boost_cobalt_io_test Boost::cobalt::io Boost::unit_test_framework OpenSSL::SSL OpenSSL::Crypto)
|
||||
target_link_libraries(boost_cobalt_io_test Boost::cobalt::io Boost::unit_test_framework OpenSSL::SSL OpenSSL::Crypto Boost::url)
|
||||
add_dependencies(tests boost_cobalt_main boost_cobalt_basic_tests boost_cobalt_static_tests boost_cobalt_experimental boost_cobalt_io_test)
|
||||
|
||||
@@ -28,11 +28,11 @@ lib test_impl : test_main.cpp /boost/cobalt//boost_cobalt /boost/test//boost_uni
|
||||
run main.cpp /boost/cobalt//boost_cobalt ;
|
||||
run main_compile.cpp /boost/cobalt//boost_cobalt util.cpp concepts.cpp ;
|
||||
|
||||
for local src in [ glob *.cpp : main.cpp main_compile.cpp test_main.cpp concepts.cpp util.cpp ]
|
||||
for local src in [ glob *.cpp : main.cpp main_compile.cpp test_main.cpp concepts.cpp util.cpp composition.cpp ]
|
||||
{
|
||||
run $(src) test_impl ;
|
||||
}
|
||||
|
||||
run experimental/context.cpp experimental/composition.cpp test_impl //boost/context ;
|
||||
run experimental/context.cpp test_impl //boost/context ;
|
||||
|
||||
run [ glob io/*.cpp ] test_impl /boost/cobalt//boost_cobalt_io /boost/cobalt//boost_cobalt ;
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/cobalt/experimental/composition.hpp>
|
||||
#include <boost/cobalt/composition.hpp>
|
||||
|
||||
#include "../test.hpp"
|
||||
#include "test.hpp"
|
||||
|
||||
using namespace boost::cobalt;
|
||||
|
||||
29
test/io/lookup.cpp
Normal file
29
test/io/lookup.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Copyright (c) 2025 Klemens Morgenstern (klemens.morgenstern@gmx.net)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/cobalt/io/resolver.hpp>
|
||||
|
||||
#include <boost/asio/buffer_registration.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#include "../test.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(io);
|
||||
BOOST_AUTO_TEST_SUITE(lookup);
|
||||
|
||||
CO_TEST_CASE(boost_org)
|
||||
{
|
||||
auto ep = co_await boost::cobalt::io::lookup("boost.org", "https");
|
||||
BOOST_REQUIRE(ep.size() >= 1u);
|
||||
BOOST_CHECK(boost::cobalt::io::get<boost::cobalt::io::tcp>(ep[0]).port() == 443);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
Reference in New Issue
Block a user