2
0
mirror of https://github.com/boostorg/cobalt.git synced 2026-01-19 04:02:16 +00:00

renamed to cobalt.

This commit is contained in:
Klemens Morgenstern
2023-10-16 09:11:44 +08:00
committed by Klemens Morgenstern
parent 03380b6a46
commit 45901641ac
162 changed files with 1643 additions and 1665 deletions

View File

@@ -67,8 +67,8 @@ def git_boost_steps(branch, image="alpine/git", env_win_style=False):
"image": image,
"commands": [
"cd boost/libs",
"git clone {}".format("$Env:DRONE_GIT_HTTP_URL" if env_win_style else "$DRONE_GIT_HTTP_URL"),
"cd async",
"git clone {} cobalt".format("$Env:DRONE_GIT_HTTP_URL" if env_win_style else "$DRONE_GIT_HTTP_URL"),
"cd cobalt",
"git checkout {}".format("$Env:DRONE_COMMIT" if env_win_style else "$DRONE_COMMIT")
]
}
@@ -97,7 +97,7 @@ def linux_build_steps(image, **kwargs):
"name": "build",
"image": image,
"commands" : [
"cd boost/libs/async",
"cd boost/libs/cobalt",
"../../b2 build -j8 " + args
]
},
@@ -105,7 +105,7 @@ def linux_build_steps(image, **kwargs):
"name": "test",
"image": image,
"commands" : [
"cd boost/libs/async",
"cd boost/libs/cobalt",
"../../b2 test -j8 " + args
]
}
@@ -127,7 +127,7 @@ def windows_build_steps(image, **kwargs):
"name" : "build",
"image" : image,
"commands": [
"cd boost/libs/async",
"cd boost/libs/cobalt",
"..\\\\..\\\\b2 build -j8 " + args
]
},
@@ -135,7 +135,7 @@ def windows_build_steps(image, **kwargs):
"name": "test",
"image": image,
"commands": [
"cd boost/libs/async",
"cd boost/libs/cobalt",
"..\\\\..\\\\b2 test -j8 " + args
]
}
@@ -192,12 +192,12 @@ def main(ctx):
linux("gcc-13 (asan)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", debug_symbols="on", address_sanitizer="on"),
linux("gcc-13 (usan)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", debug_symbols="on", undefined_sanitizer="on"),
linux("gcc-13 (tsan)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", debug_symbols="on", thread_sanitizer="on"),
linux("gcc-13 (io_context)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", **{'boost.async.executor': 'use_io_context'}),
linux("gcc-13 (container.pmr)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", **{'boost.async.pmr': 'boost-container'}),
linux("gcc-13 (no pmr)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", **{'boost.async.pmr': 'no'}),
linux("gcc-13 (io_context)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", **{'boost.cobalt.executor': 'use_io_context'}),
linux("gcc-13 (container.pmr)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", **{'boost.cobalt.pmr': 'boost-container'}),
linux("gcc-13 (no pmr)", branch, "docker.io/library/gcc:13", variant="release", cxxstd="20", **{'boost.cobalt.pmr': 'no'}),
linux("clang", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20"),
linux("clang (container.pmr)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", **{'boost.async.pmr': 'boost-container'}),
linux("clang (no pmr)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", **{'boost.async.pmr': 'no'}),
linux("clang (container.pmr)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", **{'boost.cobalt.pmr': 'boost-container'}),
linux("clang (no pmr)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", **{'boost.cobalt.pmr': 'no'}),
linux("clang (asan)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", debug_symbols="on", address_sanitizer="on"),
linux("clang (usan)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", debug_symbols="on", undefined_sanitizer="on"),
linux("clang (tsan)", branch, "docker.io/silkeh/clang", toolset='clang', variant="release", cxxstd="20", debug_symbols="on", thread_sanitizer="on"),

View File

@@ -5,69 +5,69 @@ if(BOOST_SUPERPROJECT_VERSION)
set(BOOST_REQUESTS_VERSION ${BOOST_SUPERPROJECT_VERSION})
endif()
project(boost_async VERSION "${BOOST_ASYNC_VERSION}" LANGUAGES CXX)
project(boost_cobalt VERSION "${BOOST_COBALT_VERSION}" LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(BOOST_ASYNC_IS_ROOT OFF)
set(BOOST_COBALT_IS_ROOT OFF)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(BOOST_ASYNC_IS_ROOT ON)
set(BOOST_COBALT_IS_ROOT ON)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../boost.css)
set(BOOST_ASYNC_SHOULD_BE_INLINE ON)
set(BOOST_COBALT_SHOULD_BE_INLINE ON)
else()
set(BOOST_ASYNC_SHOULD_BE_INLINE OFF)
set(BOOST_COBALT_SHOULD_BE_INLINE OFF)
endif()
option(BOOST_ASYNC_BUILD_INLINE "Configure as if part of the boost source tree" ${BOOST_ASYNC_SHOULD_BE_INLINE})
option(BOOST_COBALT_BUILD_INLINE "Configure as if part of the boost source tree" ${BOOST_COBALT_SHOULD_BE_INLINE})
file(GLOB_RECURSE ADOC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.adoc)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html
COMMAND asciidoctor ${CMAKE_CURRENT_SOURCE_DIR}/doc/index.adoc --require asciidoctor-diagram --require asciidoctor-multipage -b multipage_html5 -o ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html
DEPENDS ${ADOC_FILES})
add_custom_target(boost_async_doc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html)
add_custom_target(boost_cobalt_doc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html)
if(BOOST_ASYNC_IS_ROOT)
if(BOOST_COBALT_IS_ROOT)
#include(CTest)
endif()
if(NOT BOOST_SUPERPROJECT_VERSION)
option(BOOST_ASYNC_INSTALL "Install boost::async files" ON)
option(BOOST_ASYNC_BUILD_TESTS "Build boost::async tests" ${BUILD_TESTING})
option(BOOST_ASYNC_BUILD_EXAMPLES "Build boost::async examples" ${BOOST_ASYNC_IS_ROOT})
option(BOOST_ASYNC_BUILD_BENCHMARKS "Build boost::async benchmarks" OFF)
option(BOOST_COBALT_INSTALL "Install boost::cobalt files" ON)
option(BOOST_COBALT_BUILD_TESTS "Build boost::cobalt tests" ${BUILD_TESTING})
option(BOOST_COBALT_BUILD_EXAMPLES "Build boost::cobalt examples" ${BOOST_COBALT_IS_ROOT})
option(BOOST_COBALT_BUILD_BENCHMARKS "Build boost::cobalt benchmarks" OFF)
else()
set(BOOST_ASYNC_BUILD_TESTS ${BUILD_TESTING})
set(BOOST_COBALT_BUILD_TESTS ${BUILD_TESTING})
endif()
set(BOOST_ASYNC_SHOULD_USE_CONTAINER OFF)
set(BOOST_COBALT_SHOULD_USE_CONTAINER OFF)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CLANG_VERSION_MAJOR LESS 16)
set(BOOST_ASYNC_SHOULD_USE_CONTAINER ON)
set(BOOST_COBALT_SHOULD_USE_CONTAINER ON)
endif()
option(BOOST_ASYNC_USE_BOOST_CONTAINER "Use boost.container instead of std::pmr" ${BOOST_ASYNC_SHOULD_USE_CONTAINER})
option(BOOST_COBALT_USE_BOOST_CONTAINER "Use boost.container instead of std::pmr" ${BOOST_COBALT_SHOULD_USE_CONTAINER})
if(BOOST_ASYNC_IS_ROOT AND BOOST_ASYNC_BUILD_INLINE)
if(BOOST_COBALT_IS_ROOT AND BOOST_COBALT_BUILD_INLINE)
#
# Building inside Boost tree, but as a separate project e.g. on Travis or
# other CI, or when producing Visual Studio Solution and Projects.
set(BOOST_INCLUDE_LIBRARIES ASYNC)
set(BOOST_EXCLUDE_LIBRARIES ASYNC)
set(BOOST_INCLUDE_LIBRARIES COBALT)
set(BOOST_EXCLUDE_LIBRARIES COBALT)
set(CMAKE_FOLDER _deps)
add_subdirectory(../.. _deps/boost EXCLUDE_FROM_ALL)
unset(CMAKE_FOLDER)
endif()
if (NOT BOOST_ASYNC_BUILD_INLINE)
if (NOT BOOST_COBALT_BUILD_INLINE)
find_package(Threads REQUIRED)
# Boost 1.82 is the first with a Boost.ASIO with necessary support
find_package(Boost 1.82 REQUIRED COMPONENTS system OPTIONAL_COMPONENTS json context url)
if (BOOST_ASYNC_USE_BOOST_CONTAINER)
if (BOOST_COBALT_USE_BOOST_CONTAINER)
find_package(Boost REQUIRED container)
endif()
include_directories(include)
@@ -78,7 +78,7 @@ if (NOT MSVC)
link_libraries(${OPENSSL_LIBRARIES})
endif()
add_library(boost_async
add_library(boost_cobalt
src/detail/exception.cpp
src/detail/util.cpp
src/error.cpp
@@ -86,27 +86,27 @@ add_library(boost_async
src/main.cpp
src/this_thread.cpp
src/thread.cpp)
target_include_directories(boost_async PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(boost_async PUBLIC
target_include_directories(boost_cobalt PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(boost_cobalt PUBLIC
Boost::system
Threads::Threads)
target_compile_definitions(boost_async PRIVATE BOOST_ASYNC_SOURCE=1 )
target_compile_definitions(boost_cobalt PRIVATE BOOST_COBALT_SOURCE=1 )
if (BOOST_ASYNC_USE_BOOST_CONTAINER)
target_link_libraries(boost_async PUBLIC Boost::container)
target_compile_definitions(boost_async PUBLIC BOOST_ASYNC_USE_BOOST_CONTAINER_PMR=1 )
if (BOOST_COBALT_USE_BOOST_CONTAINER)
target_link_libraries(boost_cobalt PUBLIC Boost::container)
target_compile_definitions(boost_cobalt PUBLIC BOOST_COBALT_USE_BOOST_CONTAINER_PMR=1 )
endif()
add_library(Boost::async ALIAS boost_async)
add_library(Boost::cobalt ALIAS boost_cobalt)
if(BUILD_SHARED_LIBS)
target_compile_definitions(boost_async PUBLIC BOOST_ASYNC_DYN_LINK=1)
target_compile_definitions(boost_cobalt PUBLIC BOOST_COBALT_DYN_LINK=1)
else()
target_compile_definitions(boost_async PUBLIC BOOST_ASYNC_STATIC_LINK=1)
target_compile_definitions(boost_cobalt PUBLIC BOOST_COBALT_STATIC_LINK=1)
endif()
if(BOOST_ASYNC_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION)
install(TARGETS boost_async
if(BOOST_COBALT_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION)
install(TARGETS boost_cobalt
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
@@ -114,16 +114,16 @@ if(BOOST_ASYNC_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION)
endif()
if(BOOST_ASYNC_BUILD_TESTS)
if(BOOST_COBALT_BUILD_TESTS)
add_subdirectory(test)
endif()
if(BOOST_ASYNC_BUILD_EXAMPLES)
if(BOOST_COBALT_BUILD_EXAMPLES)
add_subdirectory(example)
set_target_properties(boost_async PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(boost_cobalt PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
if(BOOST_ASYNC_BUILD_BENCHMARKS)
if(BOOST_COBALT_BUILD_BENCHMARKS)
add_subdirectory(bench)
endif()

View File

@@ -1,42 +1,42 @@
add_executable(boost_async_post_bench post.cpp)
target_link_libraries(boost_async_post_bench PRIVATE Boost::async Boost::system Threads::Threads)
add_executable(boost_cobalt_post_bench post.cpp)
target_link_libraries(boost_cobalt_post_bench PRIVATE Boost::cobalt Boost::system Threads::Threads)
if (TARGET Boost::context)
target_link_libraries(boost_async_post_bench PRIVATE Boost::context)
target_compile_definitions(boost_async_post_bench PRIVATE BOOST_ASYNC_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_async_post_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
target_link_libraries(boost_cobalt_post_bench PRIVATE Boost::context)
target_compile_definitions(boost_cobalt_post_bench PRIVATE BOOST_COBALT_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_cobalt_post_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()
add_executable(boost_async_immediate_bench immediate.cpp)
target_link_libraries(boost_async_immediate_bench PRIVATE Boost::async Boost::system Threads::Threads)
add_executable(boost_cobalt_immediate_bench immediate.cpp)
target_link_libraries(boost_cobalt_immediate_bench PRIVATE Boost::cobalt Boost::system Threads::Threads)
if (TARGET Boost::context)
target_link_libraries(boost_async_immediate_bench PRIVATE Boost::context)
target_compile_definitions(boost_async_immediate_bench PRIVATE BOOST_ASYNC_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_async_immediate_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
target_link_libraries(boost_cobalt_immediate_bench PRIVATE Boost::context)
target_compile_definitions(boost_cobalt_immediate_bench PRIVATE BOOST_COBALT_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_cobalt_immediate_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()
add_executable(boost_async_channel_bench channel.cpp)
target_link_libraries(boost_async_channel_bench PRIVATE Boost::async Boost::system Threads::Threads)
add_executable(boost_cobalt_channel_bench channel.cpp)
target_link_libraries(boost_cobalt_channel_bench PRIVATE Boost::cobalt Boost::system Threads::Threads)
if (TARGET Boost::context)
target_link_libraries(boost_async_channel_bench PRIVATE Boost::context)
target_compile_definitions(boost_async_channel_bench PRIVATE BOOST_ASYNC_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_async_channel_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
target_link_libraries(boost_cobalt_channel_bench PRIVATE Boost::context)
target_compile_definitions(boost_cobalt_channel_bench PRIVATE BOOST_COBALT_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_cobalt_channel_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()
add_executable(boost_async_parallel_bench parallel.cpp)
target_link_libraries(boost_async_parallel_bench PRIVATE Boost::async Boost::system Threads::Threads)
add_executable(boost_cobalt_parallel_bench parallel.cpp)
target_link_libraries(boost_cobalt_parallel_bench PRIVATE Boost::cobalt Boost::system Threads::Threads)
if (TARGET Boost::context)
target_link_libraries(boost_async_parallel_bench PRIVATE Boost::context)
target_compile_definitions(boost_async_parallel_bench PRIVATE BOOST_ASYNC_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_async_parallel_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
target_link_libraries(boost_cobalt_parallel_bench PRIVATE Boost::context)
target_compile_definitions(boost_cobalt_parallel_bench PRIVATE BOOST_COBALT_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_cobalt_parallel_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()
add_executable(boost_async_monotonic_bench monotonic.cpp)
target_link_libraries(boost_async_monotonic_bench PRIVATE Boost::async Boost::system Threads::Threads)
add_executable(boost_cobalt_monotonic_bench monotonic.cpp)
target_link_libraries(boost_cobalt_monotonic_bench PRIVATE Boost::cobalt Boost::system Threads::Threads)
if (TARGET Boost::context)
target_link_libraries(boost_async_monotonic_bench PRIVATE Boost::context)
target_compile_definitions(boost_async_monotonic_bench PRIVATE BOOST_ASYNC_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_async_monotonic_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
target_link_libraries(boost_cobalt_monotonic_bench PRIVATE Boost::context)
target_compile_definitions(boost_cobalt_monotonic_bench PRIVATE BOOST_COBALT_BENCH_WITH_CONTEXT=1)
set_property(TARGET boost_cobalt_monotonic_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()

View File

@@ -4,29 +4,29 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio.hpp>
#include <boost/asio/experimental/channel.hpp>
#include <boost/asio/experimental/parallel_group.hpp>
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
#include <boost/asio/spawn.hpp>
#endif
using namespace boost;
constexpr std::size_t n = 3'000'000ull;
async::task<void> atest()
cobalt::task<void> atest()
{
async::channel<void> chan{0u};
cobalt::channel<void> chan{0u};
for (std::size_t i = 0u; i < n; i++)
co_await async::gather(chan.write(), chan.read());
co_await cobalt::gather(chan.write(), chan.read());
}
asio::awaitable<void> awtest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 0u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
for (std::size_t i = 0u; i < n; i++)
co_await asio::experimental::make_parallel_group(
chan.async_send(system::error_code{}, asio::deferred),
@@ -34,7 +34,7 @@ asio::awaitable<void> awtest()
.async_wait(asio::experimental::wait_for_all(), asio::deferred);
}
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
void stest(asio::yield_context ctx)
{
@@ -52,9 +52,9 @@ int main(int argc, char * argv[])
{
{
auto start = std::chrono::steady_clock::now();
async::run(atest());
cobalt::run(atest());
auto end = std::chrono::steady_clock::now();
printf("async : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
printf("cobalt : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
{
@@ -66,7 +66,7 @@ int main(int argc, char * argv[])
printf("awaitable: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
{
auto start = std::chrono::steady_clock::now();
asio::io_context ctx{BOOST_ASIO_CONCURRENCY_HINT_1};

View File

@@ -4,31 +4,31 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio.hpp>
#include <boost/asio/experimental/channel.hpp>
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
#include <boost/asio/spawn.hpp>
#endif
using namespace boost;
constexpr std::size_t n = 10'000'000ull;
async::task<void> atest()
cobalt::task<void> atest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 1u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 1u};
for (std::size_t i = 0u; i < n; i++)
{
co_await chan.async_send(system::error_code{}, async::use_op);
co_await chan.async_receive(async::use_op);
co_await chan.async_send(system::error_code{}, cobalt::use_op);
co_await chan.async_receive(cobalt::use_op);
}
}
asio::awaitable<void> awtest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 1u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 1u};
for (std::size_t i = 0u; i < n; i++)
{
co_await chan.async_send(system::error_code{}, asio::deferred);
@@ -36,7 +36,7 @@ asio::awaitable<void> awtest()
}
}
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
void stest(asio::yield_context ctx)
{
@@ -54,9 +54,9 @@ int main(int argc, char * argv[])
{
{
auto start = std::chrono::steady_clock::now();
async::run(atest());
cobalt::run(atest());
auto end = std::chrono::steady_clock::now();
printf("async : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
printf("cobalt : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
{
@@ -68,7 +68,7 @@ int main(int argc, char * argv[])
printf("awaitable: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
{
auto start = std::chrono::steady_clock::now();
asio::io_context ctx{BOOST_ASIO_CONCURRENCY_HINT_1};

View File

@@ -4,9 +4,9 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/async.hpp>
#include <boost/async/detail/monotonic_resource.hpp>
#include <boost/async/detail/sbo_resource.hpp>
#include <boost/cobalt.hpp>
#include <boost/cobalt/detail/monotonic_resource.hpp>
#include <boost/cobalt/detail/sbo_resource.hpp>
#include <boost/asio.hpp>
#include <boost/asio/yield.hpp>
@@ -50,7 +50,7 @@ struct my_composed_op : asio::coroutine
template<typename Token>
auto my_composed(asio::io_context & ctx, Token && token)
{
return asio::async_compose<Token, void()>(my_composed_op{}, token, ctx.get_executor());
return asio::cobalt_compose<Token, void()>(my_composed_op{}, token, ctx.get_executor());
}
@@ -66,15 +66,15 @@ struct std_test
};
alignas(std::max_align_t) char buf[1024];
async::detail::monotonic_resource res{buf, sizeof(buf)};
cobalt::detail::monotonic_resource res{buf, sizeof(buf)};
struct mono_test
{
asio::io_context & ctx;
std::size_t i = 0u;
using allocator_type = async::detail::monotonic_allocator<void>;
allocator_type get_allocator() const { return async::detail::monotonic_allocator<void>{&res}; }
using allocator_type = cobalt::detail::monotonic_allocator<void>;
allocator_type get_allocator() const { return cobalt::detail::monotonic_allocator<void>{&res}; }
void operator()()
{
@@ -84,15 +84,15 @@ struct mono_test
}
};
async::pmr::monotonic_buffer_resource pmr_res{buf, sizeof(buf)};
cobalt::pmr::monotonic_buffer_resource pmr_res{buf, sizeof(buf)};
struct pmr_test
{
asio::io_context & ctx;
std::size_t i = 0u;
using allocator_type = async::pmr::polymorphic_allocator<void>;
allocator_type get_allocator() const { return async::pmr::polymorphic_allocator<void>{&pmr_res}; }
using allocator_type = cobalt::pmr::polymorphic_allocator<void>;
allocator_type get_allocator() const { return cobalt::pmr::polymorphic_allocator<void>{&pmr_res}; }
void operator()()
{
@@ -103,15 +103,15 @@ struct pmr_test
};
async::detail::sbo_resource sbo_res{buf, sizeof(buf)};
cobalt::detail::sbo_resource sbo_res{buf, sizeof(buf)};
struct sbo_test
{
asio::io_context & ctx;
std::size_t i = 0u;
using allocator_type = async::detail::sbo_allocator<void>;
allocator_type get_allocator() const { return async::detail::sbo_allocator<void>{&sbo_res}; }
using allocator_type = cobalt::detail::sbo_allocator<void>;
allocator_type get_allocator() const { return cobalt::detail::sbo_allocator<void>{&sbo_res}; }
void operator()()
{
@@ -141,7 +141,7 @@ int main(int argc, char * argv[])
mono_test{ctx}();
ctx.run();
auto end = std::chrono::steady_clock::now();
printf("async::monotonic: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
printf("cobalt::monotonic: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
{
@@ -160,7 +160,7 @@ int main(int argc, char * argv[])
sbo_test{ctx}();
ctx.run();
auto end = std::chrono::steady_clock::now();
printf("async::sbo: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
printf("cobalt::sbo: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}

View File

@@ -4,32 +4,32 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio.hpp>
#include <boost/asio/experimental/channel.hpp>
#include <boost/asio/experimental/parallel_group.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
#include <boost/asio/spawn.hpp>
#endif
using namespace boost;
constexpr std::size_t n = 3'000'000ull;
async::task<void> atest()
cobalt::task<void> atest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 0u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
for (std::size_t i = 0u; i < n; i++)
co_await async::gather(
chan.async_send(system::error_code{}, async::use_task),
chan.async_receive(async::use_task));
co_await cobalt::gather(
chan.async_send(system::error_code{}, cobalt::use_task),
chan.async_receive(cobalt::use_task));
}
asio::awaitable<void> awtest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 0u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
using boost::asio::experimental::awaitable_operators::operator&&;
for (std::size_t i = 0u; i < n; i++)
co_await (
@@ -42,9 +42,9 @@ int main(int argc, char * argv[])
{
{
auto start = std::chrono::steady_clock::now();
async::run(atest());
cobalt::run(atest());
auto end = std::chrono::steady_clock::now();
printf("async : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
printf("cobalt : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
{

View File

@@ -4,20 +4,20 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio.hpp>
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
#include <boost/asio/spawn.hpp>
#endif
using namespace boost;
constexpr std::size_t n = 50'000'000ull;
async::task<void> atest()
cobalt::task<void> atest()
{
for (std::size_t i = 0u; i < n; i++)
co_await asio::post(async::use_op);
co_await asio::post(cobalt::use_op);
}
asio::awaitable<void> awtest()
@@ -26,7 +26,7 @@ asio::awaitable<void> awtest()
co_await asio::post(asio::deferred);
}
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
void stest(asio::yield_context ctx)
{
@@ -41,9 +41,9 @@ int main(int argc, char * argv[])
{
{
auto start = std::chrono::steady_clock::now();
async::run(atest());
cobalt::run(atest());
auto end = std::chrono::steady_clock::now();
printf("async : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
printf("cobalt : %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
{
@@ -55,7 +55,7 @@ int main(int argc, char * argv[])
printf("awaitable: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
}
#if defined(BOOST_ASYNC_BENCH_WITH_CONTEXT)
#if defined(BOOST_COBALT_BENCH_WITH_CONTEXT)
{
auto start = std::chrono::steady_clock::now();
asio::io_context ctx{BOOST_ASIO_CONCURRENCY_HINT_1};

View File

@@ -17,20 +17,20 @@ project : requirements
;
feature.feature boost.async.pmr : std boost-container custom no : propagated composite ;
feature.compose <boost.async.pmr>std : <define>BOOST_ASYNC_USE_STD_PMR=1 ;
feature.compose <boost.async.pmr>boost-container : <define>BOOST_ASYNC_USE_BOOST_CONTAINER_PMR=1 ;
feature.compose <boost.async.pmr>custom : <define>BOOST_ASYNC_USE_CUSTOM_PMR=1 ;
feature.compose <boost.async.pmr>no : <define>BOOST_ASYNC_NO_PMR=1 ;
feature.feature boost.cobalt.pmr : std boost-container custom no : propagated composite ;
feature.compose <boost.cobalt.pmr>std : <define>BOOST_COBALT_USE_STD_PMR=1 ;
feature.compose <boost.cobalt.pmr>boost-container : <define>BOOST_COBALT_USE_BOOST_CONTAINER_PMR=1 ;
feature.compose <boost.cobalt.pmr>custom : <define>BOOST_COBALT_USE_CUSTOM_PMR=1 ;
feature.compose <boost.cobalt.pmr>no : <define>BOOST_COBALT_NO_PMR=1 ;
feature.feature boost.async.executor : any_io_executor use_io_context custom : propagated composite ;
feature.compose <boost.async.executor>any_io_executor : ;
feature.compose <boost.async.executor>use_io_context : <define>BOOST_ASYNC_USE_IO_CONTEXT=1 ;
feature.compose <boost.async.executor>custom_executor : <define>BOOST_ASYNC_CUSTOM_EXECUTOR=1 ;
feature.feature boost.cobalt.executor : any_io_executor use_io_context custom : propagated composite ;
feature.compose <boost.cobalt.executor>any_io_executor : ;
feature.compose <boost.cobalt.executor>use_io_context : <define>BOOST_COBALT_USE_IO_CONTEXT=1 ;
feature.compose <boost.cobalt.executor>custom_executor : <define>BOOST_COBALT_CUSTOM_EXECUTOR=1 ;
alias async_sources
alias cobalt_sources
: detail/exception.cpp
detail/util.cpp
channel.cpp
@@ -40,15 +40,15 @@ alias async_sources
thread.cpp
;
explicit async_sources ;
explicit cobalt_sources ;
lib boost_async
: async_sources
: requirements <define>BOOST_ASYNC_SOURCE=1
<link>shared:<define>BOOST_ASYNC_DYN_LINK=1
: usage-requirements <boost.async.pmr>boost-container:<library>/boost//container
lib boost_cobalt
: cobalt_sources
: requirements <define>BOOST_COBALT_SOURCE=1
<link>shared:<define>BOOST_COBALT_DYN_LINK=1
: usage-requirements <boost.cobalt.pmr>boost-container:<library>/boost//container
;
boost-install boost_async ;
boost-install boost_cobalt ;

View File

@@ -10,7 +10,7 @@ in this library, nor is it possible to `co_await` any of those types from within
`asio::awaitable`. They can however interact through `asio::co_spawn` or <<spawn>>.
The way `asio::awaitable` blocks `co_await`-ing is by strict `await_transform` in its promises.
It prohibits being awaited by a strict definition of `async_resume`:
It prohibits being awaited by a strict definition of `await_suspend`:
[source,cpp]
----

View File

@@ -4,15 +4,15 @@ __Run on 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz__
== Posting to an executor
The benchmark is running the following code, with async's task, `asio::awaitable` and `asio`'s
The benchmark is running the following code, with cobalt's task, `asio::awaitable` and `asio`'s
stackful coroutine (boost.context) based.
[source,cpp]
----
async::task<void> atest()
cobalt::task<void> atest()
{
for (std::size_t i = 0u; i < n; i++)
co_await asio::post(async::use_op);
co_await asio::post(cobalt::use_op);
}
----
@@ -21,7 +21,7 @@ async::task<void> atest()
|===
| |gcc 12 |clang 16
|async | 2472 | 2098
|cobalt | 2472 | 2098
|awaitable | 2432 | 2253
|stackful | 3655 | 3725
|===
@@ -29,23 +29,23 @@ async::task<void> atest()
== Running noop coroutine in parallel
This benchmark uses an `asio::experimental::channel` that has a size of zero,
to read & write in parallel to it. It uses <<gather, gather>> with async
to read & write in parallel to it. It uses <<gather, gather>> with cobalt
and an `awaitable_operator` in the `asio::awaitable`.
[source,cpp]
----
async::task<void> atest()
cobalt::task<void> atest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 0u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
for (std::size_t i = 0u; i < n; i++)
co_await async::gather(
chan.async_send(system::error_code{}, async::use_task),
chan.async_receive(async::use_task));
co_await cobalt::gather(
chan.async_send(system::error_code{}, cobalt::use_task),
chan.async_receive(cobalt::use_task));
}
asio::awaitable<void> awtest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 0u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
using boost::asio::experimental::awaitable_operators::operator&&;
for (std::size_t i = 0u; i < n; i++)
co_await (
@@ -61,7 +61,7 @@ asio::awaitable<void> awtest()
|===
| |gcc 12 |clang 16
|async | 1563 | 1468
|cobalt | 1563 | 1468
|awaitable | 2800 | 2805
|===
@@ -72,13 +72,13 @@ with a size of 1, so that every operation is immediate.
[source,cpp]
----
async::task<void> atest()
cobalt::task<void> atest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await async::this_coro::executor, 1u};
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 1u};
for (std::size_t i = 0u; i < n; i++)
{
co_await chan.async_send(system::error_code{}, async::use_op);
co_await chan.async_receive(async::use_op);
co_await chan.async_send(system::error_code{}, cobalt::use_op);
co_await chan.async_receive(cobalt::use_op);
}
}
----
@@ -89,7 +89,7 @@ async::task<void> atest()
|===
| |gcc 12 |clang 16
|async | 1810 | 1864
|cobalt | 1810 | 1864
|awaitable | 3109 | 4110
|stackful | 3922 | 4705
@@ -97,16 +97,16 @@ async::task<void> atest()
== Channels
In this benchmark asio::experimental::channel and async::channel get compared.
In this benchmark asio::experimental::channel and cobalt::channel get compared.
This is similar to the parallel test, but uses the `async::channel` instead.
This is similar to the parallel test, but uses the `cobalt::channel` instead.
.result of running the test 3M times in ms
[cols="1,1,1"]
|===
| |gcc |clang
|async | 500 | 350
|cobalt | 500 | 350
|awaitable | 790 | 770
|stackful | 867 | 907
@@ -122,11 +122,11 @@ This benchmark compares the different possible solutions for the associated allo
| |gcc |clang
|std::allocator | 1136 | 1139
|async::monotonic | 1149 | 1270
|cobalt::monotonic | 1149 | 1270
|pmr::monotonic | 1164 | 1173
|async::sbo | 1021 | 1060
|cobalt::sbo | 1021 | 1060
The latter method is used internally by async.
The latter method is used internally by cobalt.
|===

View File

@@ -2,7 +2,7 @@
== Libraries
Boost.async requires a C++20 compilers and directly depends on the following boost libraries:
Boost.cobalt requires a C++20 compilers and directly depends on the following boost libraries:
- boost.asio
- boost.system

View File

@@ -1,14 +1,14 @@
[#associators]
== Associators
`async` uses the `associator` concept of asio, but simplifies it.
`cobalt` uses the `associator` concept of asio, but simplifies it.
That is, it has three associators that are member functions of an awaiting promise.
- `const executor_type & get_executor()` (always `executor`, must return by const ref)
- `allocator_type get_allocator()` (always `pmr::polymorphic_allocator<void>`)
- `cancellation_slot_type get_cancellation_slot()` (must have the same IF as `asio::cancellation_slot`)
`async` uses concepts to check if those are present in its `await_suspend` functions.
`cobalt` uses concepts to check if those are present in its `await_suspend` functions.
That way custom coroutines can support cancellation, executors and allocators.

View File

@@ -7,7 +7,7 @@ promises that do not suspend, like this:
[source,cpp]
----
async::promise<void> noop()
cobalt::promise<void> noop()
{
co_return;
}

View File

@@ -11,14 +11,14 @@ awaitable is found to be ready or completed immediately.
[source,cpp]
----
async::generator<int> gen1();
async::generator<double> gen2();
cobalt::generator<int> gen1();
cobalt::generator<double> gen2();
async::promise<void> p()
cobalt::promise<void> p()
{
auto g1 = gen1();
auto g2 = gen2();
while (!co_await async::this_coro::cancelled)
while (!co_await cobalt::this_coro::cancelled)
{
switch(auto v = co_await race(g1, g2); v.index())
{
@@ -42,8 +42,8 @@ it tries to <<interrupt_await, interrupt>> the rest, and if that fails cancels t
[source,cpp]
----
async::promise<void> timeout();
async::promise<void> work();
cobalt::promise<void> timeout();
cobalt::promise<void> work();
race(timeout(), work());
----
@@ -85,7 +85,7 @@ race(g, gen2());
The above will call a `interrupt_await() &` function for `g1` and `interrupt_await() &&` for `g2` if available.
NOTE: Generally speaking, the coroutines in async support lvalue interruption, i.e. `interrupt_await() &`.
NOTE: Generally speaking, the coroutines in `cobalt` support lvalue interruption, i.e. `interrupt_await() &`.
<<channel,channel>> operations are unqualified, i.e. work in both cases.
<<join,join>> and <<gather, gather>> will forward interruptions,

View File

@@ -28,7 +28,7 @@ list directly followed by the executor to be used in the argument list of the co
[source,cpp]
----
async::promise<void> example_with_executor(int some_arg, asio::executor_arg_t, async::executor);
cobalt::promise<void> example_with_executor(int some_arg, asio::executor_arg_t, cobalt::executor);
----
This way the coroutine-promise can pick up the executor from the third argument,
@@ -39,9 +39,9 @@ if they are sometimes with a thread_local executor.
[source,cpp]
----
async::promise<void> example_with_executor(int some_arg,
cobalt::promise<void> example_with_executor(int some_arg,
asio::executor_arg_t = asio::executor_arg,
async::executor = async::this_thread::get_executor());
cobalt::executor = cobalt::this_thread::get_executor());
----
If this gets omitted on a strand an exception of type `asio::bad_allocator` is thrown,
@@ -59,11 +59,11 @@ e.g. to avoid locks, limit memory usage or monitor usage.
`pmr` allows us to achieve this without introducing unnecessary template parameters,
i.e. no `promise<T, Allocator>` complexity.
Using `pmr` however does introduce some minimal overheads,
so a user has the option to disable by defining `BOOST_ASYNC_NO_PMR`.
so a user has the option to disable by defining `BOOST_COBALT_NO_PMR`.
<<op, op>> uses an internal resource optimized for asio's allocator usages
and <<gather, gather>>, <<race,race>> and <<join,join>> use a monotonic resource to miminize allocations.
Both still work with `BOOST_ASYNC_NO_PMR` defined, in which case they'll use `new/delete` as upstream allocations.
Both still work with `BOOST_COBALT_NO_PMR` defined, in which case they'll use `new/delete` as upstream allocations.
<<main,main>> and <<thread,thread>> single `pmr::unsynchronized_pool_resource` per thread with PMR enabled.
@@ -72,7 +72,7 @@ returning a `pmr::polymorphic_allocator<void>`.
== cancellation
async uses implicit cancellation based on `asio::cancellation_signal`.
cobalt uses implicit cancellation based on `asio::cancellation_signal`.
This is mostly used implicitly (e.g. with <<race, race>>),
so that there is very little explicit use in the examples.

View File

@@ -1,4 +1,4 @@
= Documentation boost.async
= Documentation boost.cobalt
Klemens Morgenstern <klemens.morgenstern@gmx.net>
Version 0.1, 29.01.2023
:source-highlighter: rouge

View File

@@ -3,30 +3,30 @@
Many languages programming languages
like node.js and python provide easy to use single-threaded concurrency frameworks.
While more complex than synchronous code,
single threaded asynchronicity avoids many of the pitfalls & overhead of multi-threading.
single threaded cobalthronicity avoids many of the pitfalls & overhead of multi-threading.
That is, one coroutine can work, while others wait for events (e.g. a response from a server).
This allows to write applications that *do multiple things simultaneously* on a *single thread*.
This library is meant to provide this to C++: *simple single threaded asynchronicity*
akin to node.js and asyncio in python that works with existing libraries like
This library is meant to provide this to C++: *simple single threaded cobalthronicity*
akin to node.js and cobaltio in python that works with existing libraries like
`boost.beast`, `boost.mysql` or `boost.redis`.
It based on `boost.asio`.
It takes a collection of concepts from other languages and provides them based on C++20 coroutines.
- easy asynchronous base functions, such as an async <<main, main>> & <<thread, threads>>
- easy asynchronous base functions, such as an cobalt <<main, main>> & <<thread, threads>>
- <<promise, promise>> & <<generator, generator>> types
- <<op, operation wrappers>>
- an <<with, async scope>>
- an <<with, cobalt scope>>
- <<race, race>>
- <<channel, channel>>
Unlike `asio::awaitable` and `asio::experimental::coro`, `async` coroutines are open.
Unlike `asio::awaitable` and `asio::experimental::coro`, `cobalt` coroutines are open.
That is, an `asio::awaitable` can only await and be awaited by other `asio::awaitable`
and does not provide coroutine specific synchronization mechanisms.
`async` on the other hand provides a coroutine specific `channel`
`cobalt` on the other hand provides a coroutine specific `channel`
and different wait types (`race`, `gather` etc.) that are optimized
to work with coroutines and awaitables.

View File

@@ -1,6 +1,6 @@
= Overview
Here's a list of relevant features in async:
Here's a list of relevant features in cobalt:
.Coroutine types
[cols="1,5"]

View File

@@ -45,18 +45,18 @@ Operating systems provide APIs that allow IO to be performed asynchronously,
and libraries such as https://www.boost.org/doc/libs/1_83_0/doc/html/boost_asio.html[boost.asio]
provide portable ways to manage asynchronous operations.
Asio itself does not dictate a way to handle the completions.
This library (boost.async) provides a way to manage this all through coroutines/awaitables.
This library (boost.cobalt) provides a way to manage this all through coroutines/awaitables.
[source,cpp]
----
async::promise<std::string> http_async_get(std:string_view url);
cobalt::promise<std::string> http_cobalt_get(std:string_view url);
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
auto [res, other_res] =
async::join(
http_async_get(("https://boost.org"),
http_async_get(("https://cppalliance.org")
cobalt::join(
http_cobalt_get(("https://boost.org"),
http_cobalt_get(("https://cppalliance.org")
);
printf("%s", res.c_str());
@@ -69,6 +69,6 @@ In the above code the asynchronous function to perform the request
takes advantage of the operating system APIs so that the actual IO doesn't block.
This means that while we're waiting for both functions to complete,
the operations are interleaved and non-blocking.
At the same time async provides the coroutine primitives that keep us out of callback hell.
At the same time cobalt provides the coroutine primitives that keep us out of callback hell.

View File

@@ -30,9 +30,9 @@ E.g.:
[source,cpp]
----
async::promise<void> delay(std::chrono::milliseconds);
cobalt::promise<void> delay(std::chrono::milliseconds);
async::task<void> example()
cobalt::task<void> example()
{
co_await delay(std::chrono::milliseconds(50));
}
@@ -42,15 +42,15 @@ A `co_await` expression can yield a value, depending on what it is awaiting.
[source,cpp]
----
async::promise<std::string> read_some();
cobalt::promise<std::string> read_some();
async::task<void> example()
cobalt::task<void> example()
{
std::string res = co_await read_some();
}
----
NOTE: In `async` most coroutine primitives are also <<awaitables>>.
NOTE: In `cobalt` most coroutine primitives are also <<awaitables>>.
=== `co_yield`
@@ -61,7 +61,7 @@ For example:
[source,cpp]
----
async::generator<int> iota(int max)
cobalt::generator<int> iota(int max)
{
int i = 0;
while (i < max)
@@ -76,7 +76,7 @@ which allows the user of yielding coroutine to push values into it.
[source,cpp]
----
async::generator<int> iota()
cobalt::generator<int> iota()
{
int i = 0;
bool more = false;

View File

@@ -1,11 +1,11 @@
[#event-loops]
== Event Loops
Since the coroutines in `async` can `co_await` events, they need to be run on an event-loop.
Since the coroutines in `cobalt` can `co_await` events, they need to be run on an event-loop.
That is another piece of code is responsible for tracking outstanding event and resume a resuming coroutines that are awaiting them.
This pattern is very common and is used in a similar way by node.js or python's `asyncio`.
`async` uses an https://www.boost.org/doc/libs/master/doc/html/boost_asio/reference/io_context.html[`asio::io_context`]
`cobalt` uses an https://www.boost.org/doc/libs/master/doc/html/boost_asio/reference/io_context.html[`asio::io_context`]
as its default event loop. That is, the classes <<thread, thread>>, <<main, main>> and the <<run, run>> function
are using it internally.

View File

@@ -1,16 +1,16 @@
[#async_for]
== async/async_for.hpp
== cobalt/async_for.hpp
For types like generators a `BOOST_ASYNC_FOR` macro is provided, to emulate an `async for` loop.
For types like generators a `BOOST_COBALT_FOR` macro is provided, to emulate an `for co_await` loop.
[source,cpp]
----
async::generator<int> gen();
cobalt::generator<int> gen();
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
BOOST_ASYNC_FOR(auto i, gen())
BOOST_COBALT_FOR(auto i, gen())
printf("Generated value %d\n", i);
co_return 0;

View File

@@ -1,5 +1,5 @@
[#channel]
== async/channel.hpp
== cobalt/channel.hpp
Channels can be used to exchange data between different coroutines
on a single thread.
@@ -10,7 +10,7 @@ on a single thread.
[example]
[source,cpp,subs=+quotes]
----
include::../../include/boost/async/channel.hpp[tag=outline]
include::../../include/boost/cobalt/channel.hpp[tag=outline]
----
=== Description
@@ -67,16 +67,16 @@ include::../../example/channel.cpp[tag=channel_example]
----
Additionally, a `channel_reader` is provided to make reading channels more convenient & usable with
<<async_for, BOOST_ASYNC_FOR>>.
<<async_for, BOOST_COBALT_FOR>>.
[source,cpp]
----
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
async::channel<int> c;
cobalt::channel<int> c;
auto p = producer(c);
BOOST_ASYNC_FOR(int value, async::channel_reader(c))
BOOST_COBALT_FOR(int value, cobalt::channel_reader(c))
std::cout << value << std::endl;
co_await p;

View File

@@ -1,5 +1,5 @@
[#concepts]
== async/concepts.hpp
== cobalt/concepts.hpp
[#awaitable]
=== Awaitable
@@ -8,7 +8,7 @@ An awaitable is an expression that can be used with `co_await`.
[source,cpp]
----
include::../../include/boost/async/concepts.hpp[tag=outline]
include::../../include/boost/cobalt/concepts.hpp[tag=outline]
----
WARNING: <<awaitable,awaitables>> in this library require that the coroutine promise

View File

@@ -1,38 +1,38 @@
[#config]
== async/config.hpp
== cobalt/config.hpp
The config adder allows to config some implementation details of boost.async.
The config adder allows to config some implementation details of boost.cobalt.
=== executor_type
The executor type defaults to `boost::asio::any_io_executor`.
You can set it to `boost::asio::any_io_executor` by defining `BOOST_ASYNC_CUSTOM_EXECUTOR`
and adding a `boost::async::executor` type yourself.
You can set it to `boost::asio::any_io_executor` by defining `BOOST_COBALT_CUSTOM_EXECUTOR`
and adding a `boost::cobalt::executor` type yourself.
Alternatively, `BOOST_ASYNC_USE_IO_CONTEXT` can be defined
Alternatively, `BOOST_COBALT_USE_IO_CONTEXT` can be defined
to set the executor to `boost::asio::io_context::executor_type`.
=== pmr
Boost.async can be used with different pmr implementations, defaulting to `std::pmr`.
Boost.cobalt can be used with different pmr implementations, defaulting to `std::pmr`.
The following macros can be used to configure it:
- `BOOST_ASYNC_USE_STD_PMR`
- `BOOST_ASYNC_USE_BOOST_CONTAINER_PMR`
- `BOOST_ASYNC_USE_CUSTOM_PMR`
- `BOOST_COBALT_USE_STD_PMR`
- `BOOST_COBALT_USE_BOOST_CONTAINER_PMR`
- `BOOST_COBALT_USE_CUSTOM_PMR`
If you define `BOOST_ASYNC_USE_CUSTOM_PMR` you will need to provide a `boost::async::pmr` namespace,
If you define `BOOST_COBALT_USE_CUSTOM_PMR` you will need to provide a `boost::cobalt::pmr` namespace,
that is a drop-in replacement for `std::pmr`.
Alternatively, the `pmr` use can be disabled with
- `BOOST_ASYNC_NO_PMR`.
- `BOOST_COBALT_NO_PMR`.
In this case, async will use a non-pmr monotonic resource for the
In this case, cobalt will use a non-pmr monotonic resource for the
synchronization functions (<<race,race>>, <<gather, gather>> and <<join, join>>).
`use_op` uses a small-buffer-optimized resource which's size can be set by defining
`BOOST_ASYNC_SBO_BUFFER_SIZE` and defaults to 4096 bytes.
`BOOST_COBALT_SBO_BUFFER_SIZE` and defaults to 4096 bytes.

View File

@@ -1,19 +1,19 @@
[#detached]
== async/detached.hpp
== cobalt/detached.hpp
A detached is an eager coroutine that can `co_await` but not `co_return` values.
That is, it cannot be resumed and is usually not awaited.
[source,cpp]
----
async::detached delayed_print(std::chrono::milliseconds ms)
cobalt::detached delayed_print(std::chrono::milliseconds ms)
{
asio::steady_timer tim{co_await async::this_coro::executor, ms};
co_await tim.async_wait(async::use_op);
asio::steady_timer tim{co_await cobalt::this_coro::executor, ms};
co_await tim.async_wait(cobalt::use_op);
printf("Hello world\n");
}
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
delayed_print();
co_return 0;
@@ -24,9 +24,9 @@ Detached is used to run coroutines in the background easily.
[source,cpp]
----
async::detached my_task();
cobalt::detached my_task();
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
my_task(); // <1>
co_await delay(std::chrono::milliseconds(50));
@@ -41,13 +41,13 @@ A detached can assign itself a new cancellation source like this:
[source,cpp]
----
async::detached my_task(asio::cancellation_slot sl)
cobalt::detached my_task(asio::cancellation_slot sl)
{
co_await this_coro::reset_cancellation_source(sl);
// do somework
}
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
asio::cancellation_signal sig;
my_task(sig.slot()); // <1>
@@ -66,7 +66,7 @@ in any position followed by the executor argument.
[source, cpp]
----
async::detached my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use);
cobalt::detached my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use);
----
=== Memory Resource
@@ -77,7 +77,7 @@ unless a `std::allocator_arg` is used in any position followed by a `polymorphic
[source, cpp]
----
async::detached my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
cobalt::detached my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
----
[#detached-outline]

View File

@@ -1,7 +1,7 @@
[#error]
== async/error.hpp
== cobalt/error.hpp
In order to make errors easier to manage, async provides an `error_category` to be used with
In order to make errors easier to manage, cobalt provides an `error_category` to be used with
`boost::system::error_code`.
[source,cpp]
@@ -16,7 +16,7 @@ enum class error
allocation_failed
};
system::error_category & async_category();
system::error_category & cobalt_category();
system::error_code make_error_code(error e);
----

View File

@@ -1,5 +1,5 @@
[#gather]
== async/gather.hpp
== cobalt/gather.hpp
The `gather` function can be used to `co_await` multiple <<awaitable, awaitables>>
at once with cancellations being passed through.
@@ -11,14 +11,14 @@ It can be called as a variadic function with multiple <<awaitable>> or as on a r
[source,cpp]
----
async::promise<void> task1();
async::promise<void> task2();
cobalt::promise<void> task1();
cobalt::promise<void> task2();
async::promise<void> do_gather()
cobalt::promise<void> do_gather()
{
co_await async::gather(task1(), task2()); // <1>
std::vector<async::promise<void>> aws {task1(), task2()};
co_await async::gather(aws); // <2>
co_await cobalt::gather(task1(), task2()); // <1>
std::vector<cobalt::promise<void>> aws {task1(), task2()};
co_await cobalt::gather(aws); // <2>
}
----
<1> Wait for a variadic set of <<awaitable, awaitables>>

View File

@@ -1,11 +1,11 @@
[#generator]
== async/generator.hpp
== cobalt/generator.hpp
A generator is an eager coroutine that can `co_await` and `co_yield` values to the caller.
[source,cpp]
----
async::generator<int> example()
cobalt::generator<int> example()
{
printf("In coro 1\n");
co_yield 2;
@@ -13,7 +13,7 @@ async::generator<int> example()
co_return 4;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
printf("In main 0\n");
auto f = example(); // call and let it run until the first co_yield
@@ -53,7 +53,7 @@ Values can be pushed into the generator, when `Push` (the second template parame
[source,cpp]
----
async::generator<int, int> example()
cobalt::generator<int, int> example()
{
printf("In coro 1\n");
int i = co_yield 2;
@@ -61,7 +61,7 @@ async::generator<int, int> example()
co_return 4;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
printf("In main 0\n");
auto f = example(); // call and let it run until the first co_yield
@@ -88,16 +88,16 @@ and then process the newly pushed value and resume at the next co_yield.
[source,cpp]
----
async::generator<int, int> example()
cobalt::generator<int, int> example()
{
int v = co_await async::this_coro::initial;
int v = co_await cobalt::this_coro::initial;
printf("In coro %d\n", v);
co_yield 2;
printf("In coro %d\n", v);
co_return 4;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
printf("In main 0\n");
auto f = example(); // call and let it run until the first co_yield
@@ -140,7 +140,7 @@ in any position followed by the executor argument.
[source, cpp]
----
async::generator<int> my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use);
cobalt::generator<int> my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use);
----
[#generator-allocator]
@@ -151,7 +151,7 @@ unless a `std::allocator_arg` is used in any position followed by a `polymorphic
[source, cpp]
----
async::generator<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
cobalt::generator<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
----
[#generator-outline]
@@ -159,7 +159,7 @@ async::generator<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<vo
[source,cpp,subs=+quotes]
----
include::../../include/boost/async/generator.hpp[tag=outline]
include::../../include/boost/cobalt/generator.hpp[tag=outline]
----
<1> This allows code like `while (gen) co_await gen:`
<2> Supports <<interrupt_await>>

View File

@@ -1,5 +1,5 @@
[#join]
== async/join.hpp
== cobalt/join.hpp
The `join` function can be used to `co_await` multiple <<awaitable, awaitable>> at once with properly connected cancellations.
@@ -13,14 +13,14 @@ It can be called as a variadic function with multiple <<awaitable>> or as on a r
[source,cpp]
----
async::promise<void> task1();
async::promise<void> task2();
cobalt::promise<void> task1();
cobalt::promise<void> task2();
async::promise<void> do_join()
cobalt::promise<void> do_join()
{
co_await async::join(task1(), task2()); // <1>
std::vector<async::promise<void>> aws {task1(), task2()};
co_await async::join(aws); // <2>
co_await cobalt::join(task1(), task2()); // <1>
std::vector<cobalt::promise<void>> aws {task1(), task2()};
co_await cobalt::join(aws); // <2>
}
----
<1> Wait for a variadic set of <<awaitable, awaitables>>

View File

@@ -1,5 +1,5 @@
[#leaf]
== async/leaf.hpp
== cobalt/leaf.hpp
Async provides integration with boost.leaf.
It provides functions similar to leaf that take an <<awaitable, awaitables>>

View File

@@ -1,11 +1,11 @@
[#main]
== async/main.hpp
== cobalt/main.hpp
The easiest way to get started with an async application is to use the `co_main` function with the following signature:
The easiest way to get started with an cobalt application is to use the `co_main` function with the following signature:
[source,cpp]
----
async::main co_main(int argc, char *argv[]);
cobalt::main co_main(int argc, char *argv[]);
----
Declaring `co_main` will add a `main` function that performs all the necessary steps to run a coroutine on an event loop.
@@ -13,17 +13,17 @@ This allows us to write very simple asynchronous programs.
[source,cpp]
----
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
auto exec = co_await async::this_coro::executor; // <1>
auto exec = co_await cobalt::this_coro::executor; // <1>
asio::steady_timer tim{exec, std::chrono::milliseconds(50)}; // <2>
co_await tim.async_wait(async::use_op); // <3>
co_await tim.async_wait(cobalt::use_op); // <3>
co_return 0;
}
----
<1> get the executor `main` running on
<2> Use it with an asio object
<3> `co_await` an async operation
<3> `co_await` an cobalt operation
The main promise will create an `asio::signal_set` and uses it for cancellation.
`SIGINT` becomes total , while `SIGTERM` becomes terminal cancellation.
@@ -36,18 +36,18 @@ since the program otherwise doesn't allow graceful termination.
[#main-executor]
It will also create an `asio::io_context` to run on, which you can get through the `this_coro::executor`.
It will be assigned to the `async::this_thread::get_executor()` .
It will be assigned to the `cobalt::this_thread::get_executor()` .
=== Memory Resource
[#main-allocator]
It also creates a memory resource that will be used as a default for internal memory allocations.
It will be assigned to the `thread_local` to the `async::this_thread::get_default_resource()`.
It will be assigned to the `thread_local` to the `cobalt::this_thread::get_default_resource()`.
[#main-promise]
=== Promise
Every coroutine has an internal state, called `promise` (not to be confused with the `async::promise`).
Every coroutine has an internal state, called `promise` (not to be confused with the `cobalt::promise`).
Depending on the coroutine properties different things can be `co_await`-ed, like we used in the example above.
They are implemented through inheritance, and shared among different promise types

View File

@@ -1,33 +1,17 @@
[#async_operation]
== async/op.hpp
[#cobalt_operation]
== cobalt/op.hpp
An async operation is an <<awaitable, awaitable>> wrapping an `asio` operation.
E.g. this is an `async_operation` with the completion signature `void()`.
[source,cpp]
----
auto op = asio::post(ctx, async::use_op);
----
Or the async_operation can be templated like this:
[source,cpp]
----
auto op = [&ctx](auto token) {return asio::post(ctx, std::move(token)); };
----
An operation in `cobalt` is an <<awaitable, awaitable>> wrapping an `asio` operation.
[#use_op]
=== use_op
The `use_op` token is the direct to create an op,
i.e. using `async::use_op` as the completion token will create the required awaitable.
It also supports `defaults_on` so that async_ops can be awaited without the token:
i.e. using `cobalt::use_op` as the completion token will create the required awaitable.
[source,cpp]
----
auto tim = async::use_op.as_default_on(asio::steady_timer{co_await async::this_coro::executor});
auto tim = cobalt::use_op.as_default_on(asio::steady_timer{co_await cobalt::this_coro::executor});
co_await tim.async_wait();
----
@@ -53,7 +37,7 @@ NOTE: `use_op` will never complete immediately, i.e. `await_ready` will always
[#op]
=== Hand coded Operations
Operations are a more advanced implementation of the <<async_operation>> feature.
Operations are a more advanced implementation of the <<cobalt_operation>> feature.
This library makes it easy to create asynchronous operations with an early completion condition,
i.e. a condition that avoids suspension of coroutines altogether.
@@ -62,18 +46,18 @@ We can for example create a `wait_op` that does nothing if the timer is already
[source,cpp]
----
struct wait_op : async::op<system::error_code> // <1>
struct wait_op : cobalt::op<system::error_code> // <1>
{
asio::steady_timer & tim;
wait_op(asio::steady_timer & tim) : tim(tim) {}
bool ready(async::handler<system::error_code> ) // <2>
bool ready(cobalt::handler<system::error_code> ) // <2>
{
if (tim.expiry() < std::chrono::steady_clock::now())
h(system::error_code{});
}
void initiate(async::completion_handler<system::error_code> complete) // <3>
void initiate(cobalt::completion_handler<system::error_code> complete) // <3>
{
tim.async_wait(std::move(complete));
}
@@ -81,5 +65,5 @@ struct wait_op : async::op<system::error_code> // <1>
----
<1> Inherit `op` with the matching signature `await_transform` picks it up
<2> Check if the operation is ready - called from `await_ready`
<3> Initiate the async operation if its not ready.
<3> Initiate the operation if its not ready.

View File

@@ -1,17 +1,17 @@
[#promise]
== async/promise.hpp
== cobalt/promise.hpp
A promise is an eager coroutine that can `co_await` and `co_return` values. That is, it cannot use `co_yield`.
[source,cpp]
----
async::promise<void> delay(std::chrono::milliseconds ms)
cobalt::promise<void> delay(std::chrono::milliseconds ms)
{
asio::steady_timer tim{co_await async::this_coro::executor, ms};
co_await tim.async_wait(async::use_op);
asio::steady_timer tim{co_await cobalt::this_coro::executor, ms};
co_await tim.async_wait(cobalt::use_op);
}
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
co_await delay(std::chrono::milliseconds(50));
co_return 0;
@@ -27,9 +27,9 @@ A detached promise will not send a cancellation on destruction.
[source,cpp]
----
async::promise<void> my_task();
cobalt::promise<void> my_task();
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
+my_task(); // <1>
co_await delay(std::chrono::milliseconds(50));
@@ -46,7 +46,7 @@ in any position followed by the executor argument.
[source, cpp]
----
async::promise<int> my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use);
cobalt::promise<int> my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use);
----
=== Memory Resource
@@ -57,7 +57,7 @@ unless a `std::allocator_arg` is used in any position followed by a `polymorphic
[source, cpp]
----
async::promise<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
cobalt::promise<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
----
[#promise-outline]
@@ -66,7 +66,7 @@ async::promise<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void
[source,cpp]
----
include::../../include/boost/async/promise.hpp[tag=outline]
include::../../include/boost/cobalt/promise.hpp[tag=outline]
----
<1> Supports <<interrupt_await>>
<2> This allows to create promise running in parallel with a simple `+my_task()` expression.

View File

@@ -1,5 +1,5 @@
[#race]
== async/race.hpp
== cobalt/race.hpp
The `race` function can be used to `co_await` one <<awaitable, awaitable>> out of a set of them.
@@ -7,14 +7,14 @@ It can be called as a variadic function with multiple <<awaitable, awaitable>> o
[source,cpp]
----
async::promise<void> task1();
async::promise<void> task2();
cobalt::promise<void> task1();
cobalt::promise<void> task2();
async::promise<void> do_wait()
cobalt::promise<void> do_wait()
{
co_await async::race(task1(), task2()); // <1>
std::vector<async::promise<void>> aws {task1(), task2()};
co_await async::race(aws); // <2>
co_await cobalt::race(task1(), task2()); // <1>
std::vector<cobalt::promise<void>> aws {task1(), task2()};
co_await cobalt::race(aws); // <2>
}
----
<1> Wait for a variadic set of <<awaitable, awaitables>>
@@ -60,12 +60,12 @@ This means that you can reuse race like this:
[source,cpp]
----
async::promise<void> do_wait()
cobalt::promise<void> do_wait()
{
auto t1 = task1();
auto t2 = task2();
co_await async::race(t1, t2); // <1>
co_await async::race(t1, t2); // <2>
co_await cobalt::race(t1, t2); // <1>
co_await cobalt::race(t1, t2); // <2>
}
----
<1> Wait for the first task to complete
@@ -90,7 +90,7 @@ be useful for prioritization if proper care is taken.
[source,cpp,subs=+quotes]
----
// Concept for the random number generator.
include::../../include/boost/async/race.hpp[tag=concept]
include::../../include/boost/cobalt/race.hpp[tag=concept]
// Variadic race with a custom random number generator
template<asio::cancellation_type Ct = asio::cancellation_type::all,

View File

@@ -1,5 +1,5 @@
[#result]
== async/result.hpp
== cobalt/result.hpp
Awaitables can be modified to return `system::result` or
`std::tuple` instead of using exceptions.
@@ -10,20 +10,20 @@ Awaitables can be modified to return `system::result` or
T res = co_await foo();
// as result
system::result<T, std::exception_ptr> res = co_await async::as_result(foo());
system::result<T, std::exception_ptr> res = co_await cobalt::as_result(foo());
// as tuple
std::tuple<std::exception_ptr, T> res = co_await async::as_tuple(foo());
std::tuple<std::exception_ptr, T> res = co_await cobalt::as_tuple(foo());
----
Awaitables can also provide custom ways to handle results and tuples,
by providing `await_resume` overloads using `async::as_result_tag` and `async::as_tuple_tag`.:
by providing `await_resume` overloads using `cobalt::as_result_tag` and `cobalt::as_tuple_tag`.:
[source,cpp, subs="+quotes"]
----
__your_result_type__ await_resume(async::as_result_tag);
__your_tuple_type__ await_resume(async::as_tuple_tag);
__your_result_type__ await_resume(cobalt::as_result_tag);
__your_tuple_type__ await_resume(cobalt::as_tuple_tag);
----
This allows an awaitable to provide other error types than `std::exception_ptr`,
@@ -32,8 +32,8 @@ for example `system::error_code`. This is done by <<op,op>> and <<channel,channe
[source,cpp]
----
// example of an op with result system::error_code, std::size_t
system::result<std::size_t> await_resume(async::as_result_tag);
std::tuple<system::error_code, std::size_t> await_resume(async::as_tuple_tag);
system::result<std::size_t> await_resume(cobalt::as_result_tag);
std::tuple<system::error_code, std::size_t> await_resume(cobalt::as_tuple_tag);
----
NOTE: Awaitables are still allowed to throw exceptions, e.g. for critical exceptions such as OOM.

View File

@@ -1,10 +1,10 @@
[#run]
== async/run.hpp
== cobalt/run.hpp
The `run` function is similar to <<spawn, spawn>> but running synchronously.
It will internally setup an execution context and the memory resources.
This can be useful when integrating a piece of async code into a synchronous application.
This can be useful when integrating a piece of cobalt code into a synchronous application.
[#run-outline]
=== Outline
@@ -20,7 +20,7 @@ T run(task<T> t);
[source,cpp]
----
async::task<int> work();
cobalt::task<int> work();
int main(int argc, char *argv[])
{

View File

@@ -1,5 +1,5 @@
[#spawn]
== async/spawn.hpp
== cobalt/spawn.hpp
The `spawn` functions allow to run <<task, task>> on an asio `executor`/`execution_context`
and consume the result with a https://www.boost.org/doc/libs/1_83_0/doc/html/boost_asio/overview/model/completion_tokens.html[completion token].
@@ -19,7 +19,7 @@ That is, `spawn` can be used to cross threads.
[source,cpp]
----
async::task<int> work();
cobalt::task<int> work();
int main(int argc, char *argv[])
{

View File

@@ -1,17 +1,17 @@
[#task]
== async/task.hpp
== cobalt/task.hpp
A task is a lazy coroutine that can `co_await` and `co_return` values. That is, it cannot use `co_yield`.
[source,cpp]
----
async::task<void> delay(std::chrono::milliseconds ms)
cobalt::task<void> delay(std::chrono::milliseconds ms)
{
asio::steady_timer tim{co_await async::this_coro::executor, ms};
co_await tim.async_wait(async::use_op);
asio::steady_timer tim{co_await cobalt::this_coro::executor, ms};
co_await tim.async_wait(cobalt::use_op);
}
async::main co_main(int argc, char *argv[])
cobalt::main co_main(int argc, char *argv[])
{
co_await delay(std::chrono::milliseconds(50));
co_return 0;
@@ -36,7 +36,7 @@ unless a `std::allocator_arg` is used in any position followed by a `polymorphic
[source, cpp]
----
async::task<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
cobalt::task<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> alloc);
----
[#task-outline]
@@ -45,7 +45,7 @@ async::task<int> my_gen(std::allocator_arg_t, pmr::polymorphic_allocator<void> a
[source,cpp]
----
include::../../include/boost/async/task.hpp[tag=outline]
include::../../include/boost/cobalt/task.hpp[tag=outline]
----
NOTE: Tasks can be used synchronously from a sync function by calling `run(my_task())`.
@@ -66,7 +66,7 @@ The task promise has the following properties.
[#use_task]
=== use_task
The `use_task` completion token can be used to create a task from an `async_` function.
The `use_task` completion token can be used to create a task from an `cobalt_` function.
This is less efficient than <<use_op, use_op>> as it needs to allocate a coroutine frame,
but has a simpler return type and supports <<interrupt_await>>.

View File

@@ -1,5 +1,5 @@
[#this_coro]
== async/this_coro.hpp
== cobalt/this_coro.hpp
The `this_coro` namespace provides utilities to access the internal state of a coroutine promise.
@@ -7,7 +7,7 @@ Pseudo-awaitables:
[source,cpp,subs="+quotes"]
----
include::../../include/boost/async/this_coro.hpp[tag=outline]
include::../../include/boost/cobalt/this_coro.hpp[tag=outline]
----
@@ -19,14 +19,14 @@ The allocator of a coroutine supporting `enable_await_allocator` can be obtained
[source,cpp]
----
co_await async::this_coro::allocator;
co_await cobalt::this_coro::allocator;
----
In order to enable this for your own coroutine you can inherit `enable_await_allocator` with the CRTP pattern:
[source,cpp]
----
struct my_promise : async::enable_await_allocator<my_promise>
struct my_promise : cobalt::enable_await_allocator<my_promise>
{
using allocator_type = __your_allocator_type__;
allocator_type get_allocator();
@@ -43,14 +43,14 @@ The allocator of a coroutine supporting `enable_await_executor` can be obtained
[source,cpp]
----
co_await async::this_coro::executor;
co_await cobalt::this_coro::executor;
----
In order to enable this for your own coroutine you can inherit `enable_await_executor` with the CRTP pattern:
[source,cpp]
----
struct my_promise : async::enable_await_executor<my_promise>
struct my_promise : cobalt::enable_await_executor<my_promise>
{
using executor_type = __your_executor_type__;
executor_type get_executor();
@@ -74,7 +74,7 @@ to turn throw an exception when another actual <<awaitable, awaitable>> is await
[source,cpp]
----
co_await async::this_coro::throw_if_cancelled;
co_await cobalt::this_coro::throw_if_cancelled;
----
[#promise_cancellation_base]
@@ -86,14 +86,14 @@ https://www.boost.org/doc/libs/master/doc/html/boost_asio/reference/this_coro__r
[source,cpp]
----
co_await async::this_coro::reset_cancellation_state();
co_await cobalt::this_coro::reset_cancellation_state();
----
For convenience there is also a short-cut to check the current cancellation status:
[source,cpp]
----
asio::cancellation_type ct = (co_await async::this_coro::cancellation_state).cancelled();
asio::cancellation_type ct = co_await async::this_coro::cancelled; // same as above
asio::cancellation_type ct = (co_await cobalt::this_coro::cancellation_state).cancelled();
asio::cancellation_type ct = co_await cobalt::this_coro::cancelled; // same as above
----

View File

@@ -1,12 +1,12 @@
[#this_thread]
== async/this_thread.hpp
== cobalt/this_thread.hpp
Since everything is single threaded this library provides an executor
& default memory-resource for every thread.
[source,cpp]
----
namespace boost::async::this_thread
namespace boost::cobalt::this_thread
{
pmr::memory_resource* get_default_resource() noexcept; // <1>
@@ -26,5 +26,5 @@ void set_executor(asio::io_context::executor_type exec) noexcept; // <5>
The coroutines will use these as defaults, but keep a copy just in case.
NOTE: The only exception is the initialization of an async-operation,
NOTE: The only exception is the initialization of an cobalt-operation,
which will use the this_thread::executor to rethrow from.

View File

@@ -1,21 +1,21 @@
[#thread]
== async/thread.hpp
== cobalt/thread.hpp
The thread type is another way to create an environment that is similar to `main`, but doesn't use a `signal_set`.
[source,cpp]
----
async::thread my_thread()
cobalt::thread my_thread()
{
auto exec = co_await async::this_coro::executor; // <1>
auto exec = co_await cobalt::this_coro::executor; // <1>
asio::steady_timer tim{exec, std::chrono::milliseconds(50)}; // <2>
co_await tim.async_wait(async::use_op); // <3>
co_await tim.async_wait(cobalt::use_op); // <3>
co_return 0;
}
----
<1> get the executor `thread` running on
<2> Use it with an asio object
<3> `co_await` an async operation
<3> `co_await` an cobalt operation
To use a thread you can use it like a `std::thread`:
@@ -33,7 +33,7 @@ A thread is also an `awaitable` (including cancellation).
[source,cpp]
----
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
auto thr = my_thread();
co_await thr;
@@ -45,20 +45,20 @@ NOTE: Destructing a detached thread will cause a hard stop (`io_context::stop`)
WARNING: Nothing in this library, except for awaiting a <<thread>> and <<spawn>>, is thread-safe.
If you need to transfer data across threads, you'll need a thread-safe utility like https://www.boost.org/doc/libs/master/doc/html/boost_asio/reference/experimental__basic_concurrent_channel.html[`asio::concurrent_channel`].
You cannot share any async primitives between threads,
You cannot share any cobalt primitives between threads,
with the sole exception of being able to <<spawn, spawn>> a <<task, task>> onto another thread's executor.
=== Executor
[#thread-executor]
It will also create an `asio::io_context` to run on, which you can get through the `this_coro::executor`.
It will be assigned to the `async::this_thread::get_executor()` .
It will be assigned to the `cobalt::this_thread::get_executor()` .
=== Memory Resource
[#thread-allocator]
It also creates a memory resource that will be used as a default for internal memory allocations.
It will be assigned to the `thread_local` to the `async::this_thread::get_default_resource()`.
It will be assigned to the `thread_local` to the `cobalt::this_thread::get_default_resource()`.
[#thread-outline]
=== Outline
@@ -66,7 +66,7 @@ It will be assigned to the `thread_local` to the `async::this_thread::get_defau
[source,cpp]
----
include::../../include/boost/async/thread.hpp[tag=outline]
include::../../include/boost/cobalt/thread.hpp[tag=outline]
----
<1> Supports <<interrupt_await>>
<2> Always forward cancel

View File

@@ -1,5 +1,5 @@
[#wait_group]
== async/wait_group.hpp
== cobalt/wait_group.hpp
The `wait_group` function can be used to manage
multiple coroutines of type `promise<void>`.
@@ -11,6 +11,6 @@ a `gather` function (`wait_all`) and will clean up on scope exit.
[source,cpp,subs="+quotes"]
----
include::../../include/boost/async/wait_group.hpp[tag=outline]
include::../../include/boost/cobalt/wait_group.hpp[tag=outline]
----

View File

@@ -1,5 +1,5 @@
[#with]
== async/with.hpp
== cobalt/with.hpp
The `with` facility provides a way to perform asynchronous tear-down of coroutines.
That is it like an asynchronous destructor call.
@@ -8,14 +8,14 @@ That is it like an asynchronous destructor call.
----
struct my_resource
{
async::promise<void> await_exit(std::exception_ptr e);
cobalt::promise<void> await_exit(std::exception_ptr e);
};
async::promise<void> work(my_resource & res);
cobalt::promise<void> work(my_resource & res);
async::promise<void> outer()
cobalt::promise<void> outer()
{
co_await async::with(my_resource(), &work);
co_await cobalt::with(my_resource(), &work);
}
----
@@ -25,19 +25,19 @@ that returns an <<awaitable, awaitable>> or by providing the teardown as the thi
[source,cpp]
----
using ws_stream = beast::websocket::stream<asio::ip::tcp::socket>>;
async::promise<ws_stream> connect(urls::url); // <1>
async::promise<void> disconnect(ws_stream &ws); // <2>
cobalt::promise<ws_stream> connect(urls::url); // <1>
cobalt::promise<void> disconnect(ws_stream &ws); // <2>
auto teardown(const boost::async::with_exit_tag & wet , ws_stream & ws, std::exception_ptr e)
auto teardown(const boost::cobalt::with_exit_tag & wet , ws_stream & ws, std::exception_ptr e)
{
return disconnect(ws);
}
async::promise<void> run_session(ws_stream & ws);
cobalt::promise<void> run_session(ws_stream & ws);
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
co_await async::with(co_await connect(argv[1]), &run_session, &teardown);
co_await cobalt::with(co_await connect(argv[1]), &run_session, &teardown);
co_return 0;
}
----

View File

@@ -1,4 +1,4 @@
== Entry into an async environment
== Entry into an cobalt environment
In order to use <<awaitable, awaitables>> we need to be able to `co_await` them, i.e. be within a coroutine.
@@ -8,7 +8,7 @@ We got four ways to achieve this:
<<main>>:: replace `int main` with a coroutine
[source,cpp]
----
async::main co_main(int argc, char* argv[])
cobalt::main co_main(int argc, char* argv[])
{
// co_await things here
co_return 0;
@@ -18,7 +18,7 @@ async::main co_main(int argc, char* argv[])
<<thread>>:: create a thread for the asynchronous environments
[source,cpp]
----
async::thread my_thread()
cobalt::thread my_thread()
{
// co_await things here
co_return;
@@ -35,7 +35,7 @@ int main(int argc, char ** argv[])
<<task>>:: create a task and run or spawn it
[source,cpp]
----
async::task<void> my_thread()
cobalt::task<void> my_thread()
{
// co_await things here
co_return;
@@ -43,9 +43,9 @@ async::task<void> my_thread()
int main(int argc, char ** argv[])
{
async::run(my_task()); // sync
cobalt::run(my_task()); // sync
asio::io_context ctx;
async::spawn(ctx, my_task(), asio::detached); // async, refer to async for details
cobalt::spawn(ctx, my_task(), asio::detached);
ctx.run();
return 0;
}

View File

@@ -1,21 +1,21 @@
[#tour-generator]
== Generator
A <<generator, generator>> is the only type in async that can `co_yield` values.
A <<generator, generator>> is the only type in cobalt that can `co_yield` values.
<<generator, Generator>> are eager by default. Unlike https://en.cppreference.com/w/cpp/coroutine/generator[std::generator]
the `async::generator` can `co_await` and thus is asynchronous.
the `cobalt::generator` can `co_await` and thus is asynchronous.
[source,cpp]
----
async::generator<int> my_generator()
cobalt::generator<int> my_generator()
{
for (int i = 0; i < 10; i++)
co_yield i;
co_return 10;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
// create the generator
auto g = my_generator();
@@ -29,14 +29,14 @@ Values can be pushed into the generator, that will be returned from the `co_yiel
[source,cpp]
----
async::generator<double, int> my_eager_push_generator(int value)
cobalt::generator<double, int> my_eager_push_generator(int value)
{
while (value != 0)
value = co_yield value * 0.1;
co_return std::numeric_limits<double>::quiet_NaN();
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
// create the generator
auto g = my_generator(5);
@@ -58,7 +58,7 @@ A coroutine can also be made lazy using <<initial, `this_coro::initial`>>.
[source,cpp]
----
async::generator<double, int> my_eager_push_generator()
cobalt::generator<double, int> my_eager_push_generator()
{
auto value = co_await this_coro::initial;
while (value != 0)
@@ -66,7 +66,7 @@ async::generator<double, int> my_eager_push_generator()
co_return std::numeric_limits<double>::quiet_NaN();
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
// create the generator
auto g = my_generator(); // lazy, so the generator waits for the first pushed value

View File

@@ -6,12 +6,12 @@ If multiple <<awaitable, awaitables>> work in parallel they can be awaited simul
[source,cpp]
----
async::promise<int> some_work();
async::promise<double> more_work();
cobalt::promise<int> some_work();
cobalt::promise<double> more_work();
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
std::tuple<int, double> res = async::join(some_work(), more_work());
std::tuple<int, double> res = cobalt::join(some_work(), more_work());
co_return 0;
}
----

View File

@@ -5,13 +5,13 @@ They're eager and thus easily usable for ad-hoc concurrecy.
[source,cpp]
----
async::promise<int> my_promise()
cobalt::promise<int> my_promise()
{
co_await do_the_thing();
co_return 0;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
// start the promise here
auto p = my_promise();

View File

@@ -6,10 +6,10 @@ but we want to be notified if either completes, we shall use <<race, race>>.
[source,cpp]
----
async::generator<int> some_data_source();
async::generator<double> another_data_source();
cobalt::generator<int> some_data_source();
cobalt::generator<double> another_data_source();
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
auto g1 = some_data_source();
auto g2 = another_data_source();
@@ -21,7 +21,7 @@ async::main co_main(int argc, char * argv[])
while (g1 && g2)
{
switch(variant2::variant<int, double> nx = co_await async::race(g1, g2))
switch(variant2::variant<int, double> nx = co_await cobalt::race(g1, g2))
{
case 0:
res1 = variant2::get<0>(nx);

View File

@@ -4,13 +4,13 @@
[source,cpp]
----
async::task<int> my_task()
cobalt::task<int> my_task()
{
co_await do_the_thing();
co_return 0;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
// create the task here
auto t = my_task();

View File

@@ -1,4 +1,4 @@
:example-path: https://github.com/klemens-morgenstern/async/tree/master/example
:example-path: https://github.com/boostorg/cobalt/tree/master/example
== Advanced examples
@@ -15,7 +15,7 @@ More examples are provided in the repository as code only. All examples are list
| Using the `boost.outcome` coroutine types.
|{example-path}/python.cpp[example/python.cpp] & {example-path}/python.py[example/python.py]
| Uisng nanobind to integrate async with python.
| Using nanobind to integrate cobalt with python.
It uses python's asyncio as executor and allows C++ to co_await python functions et vice versa.
|{example-path}/signals.cpp[example/signals.cpp]

View File

@@ -11,7 +11,7 @@ include::../../example/delay.cpp[tag=timer_example]
and is the easiest way to set up an environment to run asynchronous code.
<2> Take the executor from the current coroutine promise.
<3> Use an argument to set the timeout
<4> Perform the wait by using <<use_op, async::use_op>>.
<4> Perform the wait by using <<use_op, cobalt::use_op>>.
<5> Return a value that gets returned from the implicit main.
In this example we use the <<main>> header, which provides us with a main coroutine if `co_main`
@@ -26,5 +26,5 @@ Not to be confused with <<promise>>) which we can obtain through the dummy-<<awa
the <<this_coro, this_coro>> namespace.
We can then construct a timer and initiate the `async_wait` with <<use_op>>.
`async` provides multiple ways to `co_await` to interact with asio, of which <<use_op>> is the easiest.
`cobalt` provides multiple ways to `co_await` to interact with asio, of which <<use_op>> is the easiest.

View File

@@ -2,10 +2,10 @@
We've used the `use_op` so far, to use an implicit operation based on asio's completion token mechanic.
We can however implement our own ops, that can also utilize the `async_ready` optimization.
We can however implement our own ops, that can also utilize the `await_ready` optimization.
Unlike immediate completion, the coroutine will never suspend when `await_ready` returns true.
To leverage this coroutine feature, `async` provides an easy way to create a skipable operation:
To leverage this coroutine feature, `cobalt` provides an easy way to create a skipable operation:
.example/delay_op.cpp
[example]

View File

@@ -10,7 +10,7 @@ The advantage of using a generator is the internal state management.
[source,cpp]
----
async::generator<system::error_code, json::object>
cobalt::generator<system::error_code, json::object>
json_writer(websocket_type & ws)
try
{
@@ -24,7 +24,7 @@ try
while (!ser.done())
{
auto sv = ser.read(buffer);
co_await ws.async_write({sv.data(), sv.size()}); // <3>
co_await ws.cobalt_write({sv.data(), sv.size()}); // <3>
}
}

View File

@@ -81,11 +81,11 @@ include::../../example/ticker.cpp[tag=run_blockchain_info]
<2> Instantiate the json_reader
<3> Run as long as the websocket is open
<4> Select, i.e. wait for either a new json message or subscription
<5> When its a json handle an update or a rejection
<5> When it's a json handle an update or a rejection
<6> Handle new subscription messages
The `handle_*` function's contents are not as important for the `async` functionality,
so its skipped in this tutorial.
The `handle_*` function's contents are not as important for the `cobalt` functionality,
so it's skipped in this tutorial.
The `handle_new_subscription` function sends a message to the `blockchain.info`,
which will send a confirmation or rejection back.
@@ -131,7 +131,7 @@ include::../../example/ticker.cpp[tag=main]
----
<1> Create the channel to manage subscriptions
<2> Use `join` to run both tasks in parallel.
<3> Use an async scope to provide a `wait_group`.
<3> Use an cobalt scope to provide a `wait_group`.
<4> Run until cancelled.
<5> When we've reached the `limit` we wait for one task to complete.
<6> Wait for a new connection.

View File

@@ -6,9 +6,9 @@ foreach(SRC ${ALL_EXAMPLES})
# ticker requires
if (NAME STREQUAL ticker)
if (TARGET Boost::json)
add_executable(boost_async_example_${NAME} ${SRC} )
target_link_libraries(boost_async_example_${NAME} PUBLIC Boost::async Boost::json Boost::url)
target_compile_definitions(boost_async_example_${NAME} PUBLIC)
add_executable(boost_cobalt_example_${NAME} ${SRC} )
target_link_libraries(boost_cobalt_example_${NAME} PUBLIC Boost::cobalt Boost::json Boost::url)
target_compile_definitions(boost_cobalt_example_${NAME} PUBLIC)
endif()
continue()
endif()
@@ -28,17 +28,17 @@ foreach(SRC ${ALL_EXAMPLES})
message(WARNING "nanobind not found, skipping python example")
continue()
endif()
nanobind_add_module(boost_async_example_python python.cpp)
target_link_libraries(boost_async_example_python PRIVATE Boost::async)
nanobind_add_module(boost_cobalt_example_python python.cpp)
target_link_libraries(boost_cobalt_example_python PRIVATE Boost::cobalt)
add_custom_command(
TARGET boost_async_example_python
TARGET boost_cobalt_example_python
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/python.py
${CMAKE_CURRENT_BINARY_DIR}/python.py)
continue()
endif()
add_executable(boost_async_example_${NAME} ${SRC})
target_link_libraries(boost_async_example_${NAME} PUBLIC Boost::async)
target_compile_definitions(boost_async_example_${NAME} PUBLIC)
add_executable(boost_cobalt_example_${NAME} ${SRC})
target_link_libraries(boost_cobalt_example_${NAME} PUBLIC Boost::cobalt)
target_compile_definitions(boost_cobalt_example_${NAME} PUBLIC)
endforeach()

View File

@@ -16,8 +16,8 @@ project : requirements
<target-os>linux:<linkflags>-lpthread
;
exe delay : delay.cpp /boost//async ;
exe delay_op : delay_op.cpp /boost//async ;
exe echo_server : echo_server.cpp /boost//async ;
exe outcome : outcome.cpp /boost//async ;
# exe ticker : ticker.cpp /boost//json /boost//async ;
exe delay : delay.cpp /boost//cobalt ;
exe delay_op : delay_op.cpp /boost//cobalt ;
exe echo_server : echo_server.cpp /boost//cobalt ;
exe outcome : outcome.cpp /boost//cobalt ;
# exe ticker : ticker.cpp /boost//json /boost//cobalt ;

View File

@@ -4,16 +4,16 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/async/channel.hpp>
#include <boost/async/main.hpp>
#include <boost/async/promise.hpp>
#include <boost/cobalt/channel.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/cobalt/promise.hpp>
#include <iostream>
namespace async = boost::async;
namespace cobalt = boost::cobalt;
// tag::channel_example[]
async::promise<void> producer(async::channel<int> & chan)
cobalt::promise<void> producer(cobalt::channel<int> & chan)
{
for (int i = 0; i < 4; i++)
co_await chan.write(i);
@@ -21,9 +21,9 @@ async::promise<void> producer(async::channel<int> & chan)
chan.close();
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
async::channel<int> c;
cobalt::channel<int> c;
auto p = producer(c);
while (c.is_open())

View File

@@ -3,18 +3,18 @@
// 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/async/main.hpp>
#include <boost/async/op.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/cobalt/op.hpp>
#include <boost/asio/steady_timer.hpp>
using namespace boost;
// tag::timer_example[]
async::main co_main(int argc, char * argv[]) // <1>
cobalt::main co_main(int argc, char * argv[]) // <1>
{
asio::steady_timer tim{co_await asio::this_coro::executor, // <2>
std::chrono::milliseconds(std::stoi(argv[1]))}; // <3>
co_await tim.async_wait(async::use_op); // <4>
co_await tim.async_wait(cobalt::use_op); // <4>
co_return 0; // <5>
}
// end::timer_example[]

View File

@@ -3,30 +3,30 @@
// 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/async/main.hpp>
#include <boost/async/op.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/cobalt/op.hpp>
#include <boost/asio/steady_timer.hpp>
using namespace boost;
// tag::timer_example[]
struct wait_op final : async::op<system::error_code> // <1>
struct wait_op final : cobalt::op<system::error_code> // <1>
{
asio::steady_timer & tim;
wait_op(asio::steady_timer & tim) : tim(tim) {}
void ready(async::handler<system::error_code> h ) override // <2>
void ready(cobalt::handler<system::error_code> h ) override // <2>
{
if (tim.expiry() < std::chrono::steady_clock::now())
h(system::error_code{});
}
void initiate(async::completion_handler<system::error_code> complete) override // <3>
void initiate(cobalt::completion_handler<system::error_code> complete) override // <3>
{
tim.async_wait(std::move(complete));
}
};
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
asio::steady_timer tim{co_await asio::this_coro::executor,
std::chrono::milliseconds(std::stoi(argv[1]))};

View File

@@ -5,8 +5,8 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/async.hpp>
#include <boost/async/main.hpp>
#include <boost/cobalt.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
@@ -16,16 +16,16 @@
#include <list>
// tag::decls[]
namespace async = boost::async;
namespace cobalt = boost::cobalt;
using boost::asio::ip::tcp;
using boost::asio::detached;
using tcp_acceptor = async::use_op_t::as_default_on_t<tcp::acceptor>;
using tcp_socket = async::use_op_t::as_default_on_t<tcp::socket>;
namespace this_coro = boost::async::this_coro;
using tcp_acceptor = cobalt::use_op_t::as_default_on_t<tcp::acceptor>;
using tcp_socket = cobalt::use_op_t::as_default_on_t<tcp::socket>;
namespace this_coro = boost::cobalt::this_coro;
//end::decls[]
// tag::echo[]
async::promise<void> echo(tcp_socket socket)
cobalt::promise<void> echo(tcp_socket socket)
{
try // <1>
{
@@ -45,9 +45,9 @@ async::promise<void> echo(tcp_socket socket)
// tag::listen[]
async::generator<tcp_socket> listen()
cobalt::generator<tcp_socket> listen()
{
tcp_acceptor acceptor({co_await async::this_coro::executor}, {tcp::v4(), 55555});
tcp_acceptor acceptor({co_await cobalt::this_coro::executor}, {tcp::v4(), 55555});
for (;;) // <1>
{
tcp_socket sock = co_await acceptor.async_accept(); // <2>
@@ -58,7 +58,7 @@ async::generator<tcp_socket> listen()
// end::listen[]
// tag::run_server[]
async::promise<void> run_server(async::wait_group & workers)
cobalt::promise<void> run_server(cobalt::wait_group & workers)
{
auto l = listen(); // <1>
while (true)
@@ -72,9 +72,9 @@ async::promise<void> run_server(async::wait_group & workers)
// end::run_server[]
// tag::main[]
async::main co_main(int argc, char ** argv)
cobalt::main co_main(int argc, char ** argv)
{
co_await async::with(async::wait_group(), &run_server); // <1>
co_await cobalt::with(cobalt::wait_group(), &run_server); // <1>
co_return 0u;
}
// end::main[]

View File

@@ -7,10 +7,10 @@
#include <boost/asio/ssl.hpp>
#include <boost/asio/ssl/stream_base.hpp>
#include <boost/asio/system_timer.hpp>
#include <boost/async.hpp>
#include <boost/async/promise.hpp>
#include <boost/async/race.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/cobalt.hpp>
#include <boost/cobalt/promise.hpp>
#include <boost/cobalt/race.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/beast.hpp>
#include <boost/beast/core/flat_buffer.hpp>
@@ -22,10 +22,10 @@
#include <boost/beast/websocket/stream.hpp>
#include <stdexcept>
namespace async = boost::async;
namespace cobalt = boost::cobalt;
namespace beast = boost::beast;
using executor_type = async::use_op_t::executor_with_default<async::executor>;
using executor_type = cobalt::use_op_t::executor_with_default<cobalt::executor>;
using socket_type = typename boost::asio::ip::tcp::socket::rebind_executor<
executor_type>::other;
using ssl_socket_type = boost::asio::ssl::stream<socket_type>;
@@ -34,14 +34,14 @@ using acceptor_type = typename boost::asio::ip::tcp::acceptor::rebind_executor<
using websocket_type = beast::websocket::stream<ssl_socket_type>;
async::promise<ssl_socket_type> connect(std::string_view host,
cobalt::promise<ssl_socket_type> connect(std::string_view host,
boost::asio::ssl::context &ctx) {
boost::asio::ip::tcp::resolver resolve{async::this_thread::get_executor()};
auto endpoints = co_await resolve.async_resolve(host, "https", async::use_op);
boost::asio::ip::tcp::resolver resolve{cobalt::this_thread::get_executor()};
auto endpoints = co_await resolve.async_resolve(host, "https", cobalt::use_op);
// Timer for timeouts
ssl_socket_type sock{async::this_thread::get_executor(), ctx};
ssl_socket_type sock{cobalt::this_thread::get_executor(), ctx};
printf("connecting\n");
co_await sock.next_layer().async_connect(*endpoints.begin());
@@ -54,19 +54,19 @@ async::promise<ssl_socket_type> connect(std::string_view host,
co_return sock;
}
async::main co_main(int argc, char **argv)
cobalt::main co_main(int argc, char **argv)
{
boost::asio::ssl::context ctx{boost::asio::ssl::context::tls_client};
auto conn = co_await connect("boost.org", ctx);
printf("connected\n");
beast::http::request<beast::http::empty_body> req{beast::http::verb::get, "/index.html", 11};
req.set(beast::http::field::host, "boost.org");
co_await beast::http::async_write(conn, req, async::use_op);
co_await beast::http::async_write(conn, req, cobalt::use_op);
// read the response
beast::flat_buffer b;
beast::http::response<beast::http::string_body> response;
co_await beast::http::async_read(conn, b, response, async::use_op);
co_await beast::http::async_read(conn, b, response, cobalt::use_op);
// write the response
printf("%s\n", response.body().c_str());

View File

@@ -5,7 +5,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/async/main.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/outcome/coroutine_support.hpp>
using namespace boost;
@@ -21,7 +21,7 @@ outcome_v2::awaitables::eager<int> eager_func(int x)
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
[[maybe_unused]] auto lr = co_await lazy_func(10);

View File

@@ -7,10 +7,10 @@
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <thread>
/** In this example we'll connect async and
/** In this example we'll connect cobalt and
* pythons asyncio using nanobind (a C++17 successor to pybind11).
*
*/
@@ -203,8 +203,8 @@ struct py_coroutine
handle_->exec_ = python_executor(handle_->loop);
handle_->owner = this;
if (!async::this_thread::has_executor())
async::this_thread::set_executor(handle_->exec_);
if (!cobalt::this_thread::has_executor())
cobalt::this_thread::set_executor(handle_->exec_);
std::coroutine_handle<promise_type>::from_promise(*handle_.release()).resume();
}
@@ -247,7 +247,7 @@ struct py_awaitable
if constexpr (requires (T & p) {p.get_executor();})
exec = h.promise().get_executor();
else
exec = async::this_thread::get_executor();
exec = cobalt::this_thread::get_executor();
auto loop = get_loop();
auto task = getattr(loop, "create_task")(target);
@@ -255,7 +255,7 @@ struct py_awaitable
struct wrapper
{
asio::any_io_executor exec;
mutable async::unique_handle<void> awaiter;
mutable cobalt::unique_handle<void> awaiter;
py_awaitable * res;
void operator()(py::object t) const
@@ -273,7 +273,7 @@ struct py_awaitable
getattr(task, "add_done_callback")(py::cpp_function(wrapper{
std::move(exec),
async::unique_handle<void>{h.address()},
cobalt::unique_handle<void>{h.address()},
this
}));
@@ -310,16 +310,16 @@ struct py_awaitable
}
};
async::generator<int> test_generator()
cobalt::generator<int> test_generator()
{
for (auto i = 1; i < 10; i++)
co_yield i;
co_return 10;
}
async::promise<int> test_promise()
cobalt::promise<int> test_promise()
{
asio::steady_timer tim{co_await async::this_coro::executor,
asio::steady_timer tim{co_await cobalt::this_coro::executor,
std::chrono::milliseconds(100)};
co_await tim.async_wait(async::use_op);
@@ -327,18 +327,16 @@ async::promise<int> test_promise()
}
async::promise<void> await_py_coroutine(py_awaitable aw)
cobalt::promise<void> await_py_coroutine(py_awaitable aw)
{
auto res = co_await std::move(aw);
printf("Python coroutine gave %s\n", py::str(res).c_str());
}
NB_MODULE(boost_async_example_python, m)
NB_MODULE(boost_cobalt_example_python, m)
{
namespace execution = asio::execution;
// async::this_thread::set_executor(python_executor{context});
//m.def("something_awaitable", &something_awaitable);
m.def("__rethrow_exception", &std::rethrow_exception);
py::class_<std::unique_ptr<asio::execution_context>>(m, "__asio__execution_context");
@@ -365,7 +363,7 @@ NB_MODULE(boost_async_example_python, m)
py::object aiter_impl = locals["__aiter_impl"];
py::class_<py_coroutine> ct(m, "__async_coroutine");
py::class_<py_coroutine> ct(m, "__cobalt_coroutine");
ct.def("initiate", &py_coroutine::initiate)
.def_prop_ro("done", &py_coroutine::done);
setattr(ct, "__await__", await_impl);
@@ -374,7 +372,7 @@ NB_MODULE(boost_async_example_python, m)
m.def("test_generator",
[]() -> py_coroutine
{
BOOST_ASYNC_FOR(auto v, test_generator())
BOOST_COBALT_FOR(auto v, test_generator())
co_yield v;
co_return py::none();
});

View File

@@ -1,6 +1,6 @@
# run from the build folder
import asyncio
import boost_async_example_python
import boost_cobalt_example_python
async def my_cor():
@@ -15,7 +15,6 @@ async def use_cpp():
print("Cpp promise gave us", await boost_async_example_python.test_promise())
# having C++ await our python coros
await boost_async_example_python.test_py_promise(my_cor())

View File

@@ -7,10 +7,10 @@
#include <boost/signals2.hpp>
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/callable_traits/args.hpp>
namespace async = boost::async;
namespace cobalt = boost::cobalt;
namespace signals = boost::signals2;
template<typename Signal>
@@ -49,7 +49,7 @@ struct signal_awaitable
// capture it for lazy initialization
Signal & signal;
// capture the ownership of the awaiting coroutine
async::unique_handle<void> awaited_from;
cobalt::unique_handle<void> awaited_from;
// store the result from the call
std::optional<args_type> result_cache;
@@ -77,12 +77,12 @@ auto operator co_await(signals::signal<Args...> & sig) -> signal_awaitable<signa
}
async::promise<int> await_signal(signals::signal<void(int)> & sig)
cobalt::promise<int> await_signal(signals::signal<void(int)> & sig)
{
co_return co_await sig;
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
signals::signal<void(int)> sig;

View File

@@ -5,12 +5,12 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio/post.hpp>
#include <boost/lockfree/spsc_queue.hpp>
namespace async = boost::async;
namespace cobalt = boost::cobalt;
/// This is a simple class making a lockfree::spsc_queue awaitable. It's not movable, since the spsc_queue isn't.
template<typename T, typename ... Options>
@@ -34,7 +34,7 @@ struct awaitable_spsc_queue
std::atomic<void*> reader{nullptr}, writer{nullptr};
// capture the read & write executor
async::executor read_executor, write_executor;
cobalt::executor read_executor, write_executor;
// the awaitable to read a value from the queue
struct read_op
@@ -53,7 +53,7 @@ struct awaitable_spsc_queue
if constexpr (requires {h.promise().get_executor();})
this_->read_executor = h.promise().get_executor();
else
this_->read_executor = async::this_thread::get_executor();
this_->read_executor = cobalt::this_thread::get_executor();
// Make sure there's only one coroutine awaiting the read
assert(this_->reader == nullptr);
@@ -66,7 +66,7 @@ struct awaitable_spsc_queue
// Grab the value from the queue
this_->queue.pop(res);
// if a writer is waiting post it to complete on it's thread
auto w = async::unique_handle<void>::from_address(this_->writer.exchange(nullptr));
auto w = cobalt::unique_handle<void>::from_address(this_->writer.exchange(nullptr));
if (w)
boost::asio::post(this_->write_executor, std::move(w));
@@ -95,7 +95,7 @@ struct awaitable_spsc_queue
if constexpr (requires {h.promise().get_executor();})
this_->write_executor = h.promise().get_executor();
else
this_->write_executor = async::this_thread::get_executor();
this_->write_executor = cobalt::this_thread::get_executor();
assert(this_->writer == nullptr);
this_->writer.store(h.address());
@@ -107,7 +107,7 @@ struct awaitable_spsc_queue
{
this_->queue.push(std::move(value));
// if a writer is waiting post it
auto r = async::unique_handle<void>::from_address(this_->reader.exchange(nullptr));
auto r = cobalt::unique_handle<void>::from_address(this_->reader.exchange(nullptr));
if (r)
boost::asio::post(this_->read_executor, std::move(r));
}
@@ -118,7 +118,7 @@ struct awaitable_spsc_queue
};
// Dummy thread blasting out values.
async::thread thr(awaitable_spsc_queue<int> & q)
cobalt::thread thr(awaitable_spsc_queue<int> & q)
{
for (int i = 0; i <= 100000000; i++)
co_await q.write(i);
@@ -126,7 +126,7 @@ async::thread thr(awaitable_spsc_queue<int> & q)
co_await q.write(-1);
}
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
awaitable_spsc_queue<int> queue{1024};
auto t = thr(queue);

View File

@@ -5,7 +5,7 @@
/// This example shows how to use threads to offload cpu_intense work.
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio/as_tuple.hpp>
#include <boost/asio/redirect_error.hpp>
@@ -13,14 +13,14 @@
#include <boost/asio/this_coro.hpp>
namespace async = boost::async;
namespace cobalt = boost::cobalt;
using boost::system::error_code;
template<typename Signature>
using cchannel = boost::asio::experimental::concurrent_channel<Signature>;
// this is a function doing some CPU heavy work that should be offloaded onto a thread
async::promise<int> cpu_intense_work(int a, int b) {co_return a + b;}
cobalt::promise<int> cpu_intense_work(int a, int b) {co_return a + b;}
// this channel is used to send a response to completed work
using response_channel = cchannel<void(std::exception_ptr, int)>;
@@ -28,11 +28,11 @@ using response_channel = cchannel<void(std::exception_ptr, int)>;
using request_channel = cchannel<void(error_code, int, int, response_channel * res)>;
// the worker wrapper
async::thread worker(request_channel & work)
cobalt::thread worker(request_channel & work)
{
while (work.is_open())
{
auto [ec, a, b, respond_to] = co_await work.async_receive(boost::asio::as_tuple(async::use_op));
auto [ec, a, b, respond_to] = co_await work.async_receive(boost::asio::as_tuple(cobalt::use_op));
if (ec) // done, ignore. in our code this is only triggered by closing the channel
break;
@@ -49,29 +49,29 @@ async::thread worker(request_channel & work)
ep = std::current_exception();
}
// send the response. If the channel is closed, the program will terminate!
co_await respond_to->async_send(ep, res, boost::asio::redirect_error(async::use_op, ec));
co_await respond_to->async_send(ep, res, boost::asio::redirect_error(cobalt::use_op, ec));
}
}
async::promise<void> work(request_channel & rc, int min_a, int max_a, int b)
cobalt::promise<void> work(request_channel & rc, int min_a, int max_a, int b)
{
response_channel res{co_await async::this_coro::executor};
response_channel res{co_await cobalt::this_coro::executor};
for (int a = min_a; a <= max_a; a++)
{
// the following two calls offload the work to another thread.
co_await rc.async_send(error_code{}, a, b, &res, async::use_op);
int c = co_await res.async_receive(async::use_op); // may throw if working thread has an exception
co_await rc.async_send(error_code{}, a, b, &res, cobalt::use_op);
int c = co_await res.async_receive(cobalt::use_op); // may throw if working thread has an exception
printf("The CPU intensive result of adding %d to %d, is %d\n", a, b, c);
}
}
async::main co_main(int argc, char *argv [])
cobalt::main co_main(int argc, char *argv [])
{
// a very simple thread pool
std::vector<async::thread> thrs;
std::vector<cobalt::thread> thrs;
const std::size_t n = 4u;
request_channel rc{co_await async::this_coro::executor};
request_channel rc{co_await cobalt::this_coro::executor};
for (auto i = 0u; i < n; i++)
thrs.push_back(worker(rc));
@@ -79,7 +79,7 @@ async::main co_main(int argc, char *argv [])
{
// this is an over simplification, but emulated multiple pieces of
// code in the single threaded environment offloading work to the thread.
co_await async::join(
co_await cobalt::join(
work(rc, 0, 10, 32),
work(rc, 10, 20, 22),
work(rc, 50, 60, -18)
@@ -93,6 +93,6 @@ async::main co_main(int argc, char *argv [])
// closing the channel will cause the threads to complete
rc.close();
// wait them so they don't leak.
co_await async::join(thrs);
co_await cobalt::join(thrs);
co_return 0;
}

View File

@@ -5,7 +5,7 @@
/// This example shows how to use threads to offload cpu_intense work.
#include <boost/async.hpp>
#include <boost/cobalt.hpp>
#include <boost/asio/as_tuple.hpp>
#include <boost/asio/redirect_error.hpp>
@@ -15,21 +15,21 @@
#include <boost/asio/thread_pool.hpp>
namespace async = boost::async;
namespace cobalt = boost::cobalt;
using boost::system::error_code;
// this is a function doing some CPU heavy work that should be offloaded onto a thread_pool
async::promise<int> cpu_intense_work(
cobalt::promise<int> cpu_intense_work(
int a, int b,
boost::asio::executor_arg_t = {}, async::executor = async::this_thread::get_executor())
boost::asio::executor_arg_t = {}, cobalt::executor = cobalt::this_thread::get_executor())
// ^set the executor manually. but default it so we can still use it with the thread_local one if present
{
co_return a + b;
}
async::task<void> work(int min_a, int max_a, int b)
cobalt::task<void> work(int min_a, int max_a, int b)
{
auto exec = co_await async::this_coro::executor;
auto exec = co_await cobalt::this_coro::executor;
for (int a = min_a; a <= max_a; a++)
{
// the following two calls offload the work to another thread.
@@ -58,9 +58,9 @@ int main(int , char * [])
}
};
async::spawn(boost::asio::make_strand(tp.get_executor()), work(0, 10, 32), cpl);
async::spawn(boost::asio::make_strand(tp.get_executor()), work(10, 20, 22), cpl);
async::spawn(boost::asio::make_strand(tp.get_executor()), work(50, 60, -18), cpl);
cobalt::spawn(boost::asio::make_strand(tp.get_executor()), work(0, 10, 32), cpl);
cobalt::spawn(boost::asio::make_strand(tp.get_executor()), work(10, 20, 22), cpl);
cobalt::spawn(boost::asio::make_strand(tp.get_executor()), work(50, 60, -18), cpl);
// wait them so they don't leak.
tp.join();

View File

@@ -3,9 +3,9 @@
// 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/async.hpp>
#include <boost/async/main.hpp>
#include <boost/async/join.hpp>
#include <boost/cobalt.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/cobalt/join.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -30,7 +30,7 @@
using namespace boost;
// tag::decls[]
using executor_type = async::use_op_t::executor_with_default<async::executor>;
using executor_type = cobalt::use_op_t::executor_with_default<cobalt::executor>;
using socket_type = typename asio::ip::tcp::socket::rebind_executor<executor_type>::other;
using acceptor_type = typename asio::ip::tcp::acceptor::rebind_executor<executor_type>::other;
using websocket_type = beast::websocket::stream<asio::ssl::stream<socket_type>>;
@@ -38,13 +38,13 @@ namespace http = beast::http;
// end::decls[]
// tag::connect[]
async::promise<asio::ssl::stream<socket_type>> connect(
cobalt::promise<asio::ssl::stream<socket_type>> connect(
std::string host, boost::asio::ssl::context & ctx)
{
asio::ip::tcp::resolver res{async::this_thread::get_executor()};
auto ep = co_await res.async_resolve(host, "https", async::use_op); // <1>
asio::ip::tcp::resolver res{cobalt::this_thread::get_executor()};
auto ep = co_await res.async_resolve(host, "https", cobalt::use_op); // <1>
asio::ssl::stream<socket_type> sock{async::this_thread::get_executor(), ctx};
asio::ssl::stream<socket_type> sock{cobalt::this_thread::get_executor(), ctx};
co_await sock.next_layer().async_connect(*ep.begin()); // <2>
co_await sock.async_handshake(asio::ssl::stream_base::client); // <3>
@@ -53,13 +53,13 @@ async::promise<asio::ssl::stream<socket_type>> connect(
// end::connect[]
// tag::ws_upgrade[]
async::promise<void> connect_to_blockchain_info(websocket_type & ws)
cobalt::promise<void> connect_to_blockchain_info(websocket_type & ws)
{
ws.set_option(beast::websocket::stream_base::decorator(
[](beast::websocket::request_type& req)
{
req.set(http::field::user_agent,
std::string(BOOST_BEAST_VERSION_STRING) + " async-ticker");
std::string(BOOST_BEAST_VERSION_STRING) + " cobalt-ticker");
req.set(http::field::origin,
"https://exchange.blockchain.com"); // <1>
}));
@@ -69,7 +69,7 @@ async::promise<void> connect_to_blockchain_info(websocket_type & ws)
// end::ws_upgrade[]
// tag::json_reader[]
async::generator<json::object> json_reader(websocket_type & ws)
cobalt::generator<json::object> json_reader(websocket_type & ws)
try
{
beast::flat_buffer buf;
@@ -91,12 +91,12 @@ catch (std::exception & e)
// end::json_reader[]
// tag::subscription_types[]
using subscription = std::pair<std::string, std::weak_ptr<async::channel<json::object>>>;
using subscription_channel = std::weak_ptr<async::channel<json::object>>;
using subscription = std::pair<std::string, std::weak_ptr<cobalt::channel<json::object>>>;
using subscription_channel = std::weak_ptr<cobalt::channel<json::object>>;
using subscription_map = boost::unordered_multimap<std::string, subscription_channel>;
// end::subscription_types[]
async::promise<void> handle_rejections(
cobalt::promise<void> handle_rejections(
std::list<std::string> & unconfirmed,
subscription_map & subs,
const json::object & ms)
@@ -116,7 +116,7 @@ async::promise<void> handle_rejections(
subs.erase(r.first, r.second);
}
async::promise<void> handle_update(
cobalt::promise<void> handle_update(
std::list<std::string> & unconfirmed,
subscription_map & subs,
const json::object & ms,
@@ -151,7 +151,7 @@ async::promise<void> handle_update(
}
}
async::promise<void> handle_new_subscription(
cobalt::promise<void> handle_new_subscription(
std::list<std::string> & unconfirmed,
subscription_map & subs,
subscription msg,
@@ -173,7 +173,7 @@ async::promise<void> handle_new_subscription(
}
// tag::run_blockchain_info[]
async::promise<void> run_blockchain_info(async::channel<subscription> & subc)
cobalt::promise<void> run_blockchain_info(cobalt::channel<subscription> & subc)
try
{
asio::ssl::context ctx{asio::ssl::context_base::tls_client};
@@ -186,7 +186,7 @@ try
auto rd = json_reader(ws); // <2>
while (ws.is_open()) // <3>
{
switch (auto msg = co_await async::race(rd, subc.read()); msg.index()) // <4>
switch (auto msg = co_await cobalt::race(rd, subc.read()); msg.index()) // <4>
{
case 0: // <5>
if (auto ms = get<0>(msg);
@@ -217,18 +217,18 @@ catch(std::exception & e)
// end::run_blockchain_info[]
// tag::read_and_close[]
async::promise<void> read_and_close(beast::websocket::stream<socket_type> & st, beast::flat_buffer buf)
cobalt::promise<void> read_and_close(beast::websocket::stream<socket_type> & st, beast::flat_buffer buf)
{
system::error_code ec;
co_await st.async_read(buf, asio::as_tuple(async::use_op));
co_await st.async_close(beast::websocket::close_code::going_away, asio::as_tuple(async::use_op));
co_await st.async_read(buf, asio::as_tuple(cobalt::use_op));
co_await st.async_close(beast::websocket::close_code::going_away, asio::as_tuple(cobalt::use_op));
st.next_layer().close(ec);
}
// end::read_and_close[]
// tag::run_session[]
async::promise<void> run_session(beast::websocket::stream<socket_type> st,
async::channel<subscription> & subc)
cobalt::promise<void> run_session(beast::websocket::stream<socket_type> st,
cobalt::channel<subscription> & subc)
try
{
http::request<http::empty_body> req;
@@ -254,7 +254,7 @@ try
// close when data gets sent
auto p = read_and_close(st, std::move(buf)); // <4>
auto ptr = std::make_shared<async::channel<json::object>>(1u); // <5>
auto ptr = std::make_shared<cobalt::channel<json::object>>(1u); // <5>
co_await subc.write(subscription{sym, ptr}); // <6>
while (ptr->is_open() && st.is_open()) // <7>
@@ -264,7 +264,7 @@ try
}
co_await st.async_close(beast::websocket::close_code::going_away,
asio::as_tuple(async::use_op)); // <8>
asio::as_tuple(cobalt::use_op)); // <8>
st.next_layer().close();
co_await p; // <9>
@@ -276,24 +276,24 @@ catch(std::exception & e)
// end::run_session[]
// tag::main[]
async::main co_main(int argc, char * argv[])
cobalt::main co_main(int argc, char * argv[])
{
acceptor_type acc{co_await async::this_coro::executor,
acceptor_type acc{co_await cobalt::this_coro::executor,
asio::ip::tcp::endpoint (asio::ip::tcp::v4(), 8080)};
std::cout << "Listening on localhost:8080" << std::endl;
constexpr int limit = 10; // allow 10 ongoing sessions
async::channel<subscription> sub_manager; // <1>
cobalt::channel<subscription> sub_manager; // <1>
co_await join( // <2>
run_blockchain_info(sub_manager),
async::with( // <3>
async::wait_group(
cobalt::with( // <3>
cobalt::wait_group(
asio::cancellation_type::all,
asio::cancellation_type::all),
[&](async::wait_group & sessions) -> async::promise<void>
[&](cobalt::wait_group & sessions) -> cobalt::promise<void>
{
while (!co_await async::this_coro::cancelled) // <4>
while (!co_await cobalt::this_coro::cancelled) // <4>
{
if (sessions.size() >= limit) // <5>
co_await sessions.wait_one();

View File

@@ -1,35 +0,0 @@
//
// Copyright (c) 2022 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)
//
#ifndef BOOST_ASYNC_HPP
#define BOOST_ASYNC_HPP
#include <boost/async/async_for.hpp>
#include <boost/async/channel.hpp>
#include <boost/async/concepts.hpp>
#include <boost/async/config.hpp>
#include <boost/async/detached.hpp>
#include <boost/async/error.hpp>
#include <boost/async/gather.hpp>
#include <boost/async/generator.hpp>
#include <boost/async/join.hpp>
#include <boost/async/leaf.hpp>
#include <boost/async/main.hpp>
#include <boost/async/op.hpp>
#include <boost/async/promise.hpp>
#include <boost/async/run.hpp>
#include <boost/async/race.hpp>
#include <boost/async/spawn.hpp>
#include <boost/async/task.hpp>
#include <boost/async/this_coro.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/async/thread.hpp>
#include <boost/async/wait_group.hpp>
#include <boost/async/with.hpp>
#endif //BOOST_ASYNC_HPP

View File

@@ -1,31 +0,0 @@
//
// Copyright (c) 2022 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)
//
#ifndef BOOST_ASYNC_DETAIL_EXCEPTION_HPP
#define BOOST_ASYNC_DETAIL_EXCEPTION_HPP
#include <boost/config.hpp>
#include <boost/async/config.hpp>
#include <exception>
namespace boost::async::detail
{
BOOST_ASYNC_DECL std::exception_ptr moved_from_exception();
BOOST_ASYNC_DECL std::exception_ptr detached_exception();
BOOST_ASYNC_DECL std::exception_ptr completed_unexpected();
BOOST_ASYNC_DECL std::exception_ptr wait_not_ready();
BOOST_ASYNC_DECL std::exception_ptr already_awaited();
BOOST_ASYNC_DECL std::exception_ptr allocation_failed();
template<typename >
std::exception_ptr wait_not_ready() { return boost::async::detail::wait_not_ready();}
}
#endif //BOOST_ASYNC_DETAIL_EXCEPTION_HPP

View File

@@ -1,34 +0,0 @@
//
// Copyright (c) 2022 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)
//
#ifndef BOOST_ASYNC_THIS_THREAD_HPP
#define BOOST_ASYNC_THIS_THREAD_HPP
#include <boost/async/config.hpp>
#include <boost/config.hpp>
#include <boost/asio/io_context.hpp>
namespace boost::async::this_thread
{
#if !defined(BOOST_ASYNC_NO_PMR)
BOOST_ASYNC_DECL pmr::memory_resource* get_default_resource() noexcept;
BOOST_ASYNC_DECL pmr::memory_resource* set_default_resource(pmr::memory_resource* r) noexcept;
BOOST_ASYNC_DECL pmr::polymorphic_allocator<void> get_allocator();
#endif
BOOST_ASYNC_DECL
executor & get_executor(
const boost::source_location & loc = BOOST_CURRENT_LOCATION);
BOOST_ASYNC_DECL bool has_executor();
BOOST_ASYNC_DECL void set_executor(executor exec) noexcept;
}
#endif //BOOST_ASYNC_THIS_THREAD_HPP

35
include/boost/cobalt.hpp Normal file
View File

@@ -0,0 +1,35 @@
//
// Copyright (c) 2022 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)
//
#ifndef BOOST_COBALT_HPP
#define BOOST_COBALT_HPP
#include <boost/cobalt/async_for.hpp>
#include <boost/cobalt/channel.hpp>
#include <boost/cobalt/concepts.hpp>
#include <boost/cobalt/config.hpp>
#include <boost/cobalt/detached.hpp>
#include <boost/cobalt/error.hpp>
#include <boost/cobalt/gather.hpp>
#include <boost/cobalt/generator.hpp>
#include <boost/cobalt/join.hpp>
#include <boost/cobalt/leaf.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/cobalt/op.hpp>
#include <boost/cobalt/promise.hpp>
#include <boost/cobalt/run.hpp>
#include <boost/cobalt/race.hpp>
#include <boost/cobalt/spawn.hpp>
#include <boost/cobalt/task.hpp>
#include <boost/cobalt/this_coro.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/cobalt/thread.hpp>
#include <boost/cobalt/wait_group.hpp>
#include <boost/cobalt/with.hpp>
#endif //BOOST_COBALT_HPP

View File

@@ -2,16 +2,16 @@
//
// 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)
#ifndef BOOST_ASYNC_ASYNC_FOR_HPP
#define BOOST_ASYNC_ASYNC_FOR_HPP
#ifndef BOOST_COBALT_COBALT_FOR_HPP
#define BOOST_COBALT_COBALT_FOR_HPP
#include <boost/preprocessor/cat.hpp>
#define BOOST_ASYNC_FOR_IMPL(Value, Expression, Id) \
#define BOOST_COBALT_FOR_IMPL(Value, Expression, Id) \
for (auto && Id = Expression; Id; ) \
if (Value = co_await Id; false) {} else
#define BOOST_ASYNC_FOR(Value, Expression) \
BOOST_ASYNC_FOR_IMPL(Value, Expression, BOOST_PP_CAT(__boost_async_for_loop_value__, __LINE__))
#define BOOST_COBALT_FOR(Value, Expression) \
BOOST_COBALT_FOR_IMPL(Value, Expression, BOOST_PP_CAT(__boost_cobalt_for_loop_value__, __LINE__))
#endif //BOOST_ASYNC_ASYNC_FOR_HPP
#endif //BOOST_COBALT_COBALT_FOR_HPP

View File

@@ -5,12 +5,12 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_CHANNEL_HPP
#define BOOST_ASYNC_CHANNEL_HPP
#ifndef BOOST_COBALT_CHANNEL_HPP
#define BOOST_COBALT_CHANNEL_HPP
#include <boost/async/this_thread.hpp>
#include <boost/async/unique_handle.hpp>
#include <boost/async/detail/util.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/cobalt/unique_handle.hpp>
#include <boost/cobalt/detail/util.hpp>
#include <boost/asio/cancellation_signal.hpp>
#include <boost/asio/cancellation_type.hpp>
@@ -21,7 +21,7 @@
#include <optional>
namespace boost::async
namespace boost::cobalt
{
template<typename T>
@@ -32,7 +32,7 @@ template<typename T>
struct channel
{
// end::outline[]
#if defined(BOOST_ASYNC_NO_PMR)
#if defined(BOOST_COBALT_NO_PMR)
channel(std::size_t limit = 0u,
executor executor = this_thread::get_executor());
#else
@@ -60,7 +60,7 @@ struct channel
// end::outline[]
private:
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
boost::circular_buffer<T, pmr::polymorphic_allocator<T>> buffer_;
#else
boost::circular_buffer<T> buffer_;
@@ -184,10 +184,10 @@ struct channel<void>
using executor_type = executor;
const executor_type & get_executor() {return executor_;}
BOOST_ASYNC_DECL ~channel();
BOOST_COBALT_DECL ~channel();
bool is_open() const {return !is_closed_;}
BOOST_ASYNC_DECL void close();
BOOST_COBALT_DECL void close();
private:
std::size_t limit_;
@@ -216,9 +216,9 @@ struct channel<void>
template<typename Promise>
BOOST_NOINLINE
std::coroutine_handle<void> await_suspend(std::coroutine_handle<Promise> h);
BOOST_ASYNC_DECL void await_resume();
BOOST_ASYNC_DECL std::tuple<system::error_code> await_resume(const struct as_tuple_tag & );
BOOST_ASYNC_DECL system::result<void> await_resume(const struct as_result_tag &);
BOOST_COBALT_DECL void await_resume();
BOOST_COBALT_DECL std::tuple<system::error_code> await_resume(const struct as_tuple_tag & );
BOOST_COBALT_DECL system::result<void> await_resume(const struct as_result_tag &);
explicit operator bool() const {return chn && chn->is_open();}
};
@@ -248,9 +248,9 @@ struct channel<void>
BOOST_NOINLINE
std::coroutine_handle<void> await_suspend(std::coroutine_handle<Promise> h);
BOOST_ASYNC_DECL void await_resume();
BOOST_ASYNC_DECL std::tuple<system::error_code> await_resume(const struct as_tuple_tag & );
BOOST_ASYNC_DECL system::result<void> await_resume(const struct as_result_tag &);
BOOST_COBALT_DECL void await_resume();
BOOST_COBALT_DECL std::tuple<system::error_code> await_resume(const struct as_tuple_tag & );
BOOST_COBALT_DECL system::result<void> await_resume(const struct as_result_tag &);
explicit operator bool() const {return chn && chn->is_open();}
};
@@ -281,6 +281,6 @@ struct channel_reader
}
#include <boost/async/impl/channel.hpp>
#include <boost/cobalt/impl/channel.hpp>
#endif //BOOST_ASYNC_CHANNEL_HPP
#endif //BOOST_COBALT_CHANNEL_HPP

View File

@@ -2,8 +2,8 @@
//
// 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)
#ifndef BOOST_ASYNC_CONCEPTS_HPP
#define BOOST_ASYNC_CONCEPTS_HPP
#ifndef BOOST_COBALT_CONCEPTS_HPP
#define BOOST_COBALT_CONCEPTS_HPP
#include <coroutine>
#include <concepts>
@@ -15,7 +15,7 @@
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
namespace boost::async
namespace boost::cobalt
{
// tag::outline[]
@@ -68,4 +68,4 @@ concept with_get_executor = requires (T& t)
}
#endif //BOOST_ASYNC_CONCEPTS_HPP
#endif //BOOST_COBALT_CONCEPTS_HPP

View File

@@ -7,22 +7,22 @@
#include <boost/config.hpp>
#ifndef BOOST_ASYNC_CONFIG_HPP
#define BOOST_ASYNC_CONFIG_HPP
#ifndef BOOST_COBALT_CONFIG_HPP
#define BOOST_COBALT_CONFIG_HPP
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ASYNC_DYN_LINK)
#if defined(BOOST_ASYNC_SOURCE)
#define BOOST_ASYNC_DECL BOOST_SYMBOL_EXPORT
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COBALT_DYN_LINK)
#if defined(BOOST_COBALT_SOURCE)
#define BOOST_COBALT_DECL BOOST_SYMBOL_EXPORT
#else
#define BOOST_ASYNC_DECL BOOST_SYMBOL_IMPORT
#define BOOST_COBALT_DECL BOOST_SYMBOL_IMPORT
#endif
#else
#define BOOST_ASYNC_DECL
#define BOOST_COBALT_DECL
#endif
#if defined(BOOST_ASYNC_USE_IO_CONTEXT)
#if defined(BOOST_COBALT_USE_IO_CONTEXT)
# include <boost/asio/io_context.hpp>
#elif !defined(BOOST_ASYNC_CUSTOM_EXECUTOR)
#elif !defined(BOOST_COBALT_CUSTOM_EXECUTOR)
# include <boost/asio/any_io_executor.hpp>
#endif
@@ -32,17 +32,17 @@
#if defined(_MSC_VER)
// msvc doesn't correctly suspend for self-deletion, hence we must workaround here
#define BOOST_ASYNC_NO_SELF_DELETE 1
#define BOOST_COBALT_NO_SELF_DELETE 1
#endif
#if !defined(BOOST_ASYNC_USE_STD_PMR) && \
!defined(BOOST_ASYNC_USE_BOOST_CONTAINER_PMR) && \
!defined(BOOST_ASYNC_USE_CUSTOM_PMR) && \
!defined(BOOST_ASYNC_NO_PMR)
#define BOOST_ASYNC_USE_STD_PMR 1
#if !defined(BOOST_COBALT_USE_STD_PMR) && \
!defined(BOOST_COBALT_USE_BOOST_CONTAINER_PMR) && \
!defined(BOOST_COBALT_USE_CUSTOM_PMR) && \
!defined(BOOST_COBALT_NO_PMR)
#define BOOST_COBALT_USE_STD_PMR 1
#endif
#if defined(BOOST_ASYNC_USE_BOOST_CONTAINER_PMR)
#if defined(BOOST_COBALT_USE_BOOST_CONTAINER_PMR)
#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/pmr/unsynchronized_pool_resource.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
@@ -51,31 +51,31 @@
#include <boost/container/pmr/vector.hpp>
#endif
#if defined(BOOST_ASYNC_USE_STD_PMR)
#if defined(BOOST_COBALT_USE_STD_PMR)
#include <memory_resource>
#endif
#if !defined(BOOST_ASYNC_OP_SBO_SIZE)
#define BOOST_ASYNC_SBO_BUFFER_SIZE 4096
#if !defined(BOOST_COBALT_OP_SBO_SIZE)
#define BOOST_COBALT_SBO_BUFFER_SIZE 4096
#endif
namespace boost::async
namespace boost::cobalt
{
#if defined(BOOST_ASYNC_USE_IO_CONTEXT)
#if defined(BOOST_COBALT_USE_IO_CONTEXT)
using executor = boost::asio::io_context::executor_type;
#elif !defined(BOOST_ASYNC_CUSTOM_EXECUTOR)
#elif !defined(BOOST_COBALT_CUSTOM_EXECUTOR)
using executor = boost::asio::any_io_executor;
#endif
#if defined(BOOST_ASYNC_USE_BOOST_CONTAINER_PMR)
#if defined(BOOST_COBALT_USE_BOOST_CONTAINER_PMR)
namespace pmr = boost::container::pmr;
#endif
#if defined(BOOST_ASYNC_USE_STD_PMR)
#if defined(BOOST_COBALT_USE_STD_PMR)
namespace pmr = std::pmr;
#endif
}
#endif //BOOST_ASYNC_CONFIG_HPP
#endif //BOOST_COBALT_CONFIG_HPP

View File

@@ -5,12 +5,12 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETACHED_HPP
#define BOOST_ASYNC_DETACHED_HPP
#ifndef BOOST_COBALT_DETACHED_HPP
#define BOOST_COBALT_DETACHED_HPP
#include <boost/async/detail/detached.hpp>
#include <boost/cobalt/detail/detached.hpp>
namespace boost::async
namespace boost::cobalt
{
struct detached
@@ -24,4 +24,4 @@ inline detached detail::detached_promise::get_return_object() { return {}; }
}
#endif //BOOST_ASYNC_DETACHED_HPP
#endif //BOOST_COBALT_DETACHED_HPP

View File

@@ -5,13 +5,13 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_AWAIT_RESULT_HELPER_HPP
#define BOOST_ASYNC_DETAIL_AWAIT_RESULT_HELPER_HPP
#ifndef BOOST_COBALT_DETAIL_AWAIT_RESULT_HELPER_HPP
#define BOOST_COBALT_DETAIL_AWAIT_RESULT_HELPER_HPP
#include <boost/async/concepts.hpp>
#include <boost/cobalt/concepts.hpp>
#include <utility>
namespace boost::async::detail
namespace boost::cobalt::detail
{
template<awaitable_type T>
@@ -79,4 +79,4 @@ template<awaitable_type T>
}
#endif //BOOST_ASYNC_DETAIL_AWAIT_RESULT_HELPER_HPP
#endif //BOOST_COBALT_DETAIL_AWAIT_RESULT_HELPER_HPP

View File

@@ -5,13 +5,13 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_DETACHED_HPP
#define BOOST_ASYNC_DETAIL_DETACHED_HPP
#ifndef BOOST_COBALT_DETAIL_DETACHED_HPP
#define BOOST_COBALT_DETAIL_DETACHED_HPP
#include <boost/async/detail/exception.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/wrapper.hpp>
#include <boost/async/detail/this_thread.hpp>
#include <boost/cobalt/detail/exception.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/asio/cancellation_signal.hpp>
@@ -25,7 +25,7 @@
#include <utility>
#include <boost/asio/bind_allocator.hpp>
namespace boost::async
namespace boost::cobalt
{
struct detached;
@@ -50,7 +50,7 @@ struct detached_promise
[[nodiscard]] detached get_return_object();
auto await_transform(
async::this_coro::reset_cancellation_source_t<asio::cancellation_slot> reset) noexcept
cobalt::this_coro::reset_cancellation_source_t<asio::cancellation_slot> reset) noexcept
{
struct result
{
@@ -82,7 +82,7 @@ struct detached_promise
template<typename ... Args>
detached_promise(Args & ...args)
:
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
promise_memory_resource_base(detail::get_memory_resource_from_args(args...)),
#endif
exec{detail::get_executor_from_args(args...)}
@@ -103,4 +103,4 @@ struct detached_promise
}
#endif //BOOST_ASYNC_DETAIL_DETACHED_HPP
#endif //BOOST_COBALT_DETAIL_DETACHED_HPP

View File

@@ -0,0 +1,31 @@
//
// Copyright (c) 2022 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)
//
#ifndef BOOST_COBALT_DETAIL_EXCEPTION_HPP
#define BOOST_COBALT_DETAIL_EXCEPTION_HPP
#include <boost/config.hpp>
#include <boost/cobalt/config.hpp>
#include <exception>
namespace boost::cobalt::detail
{
BOOST_COBALT_DECL std::exception_ptr moved_from_exception();
BOOST_COBALT_DECL std::exception_ptr detached_exception();
BOOST_COBALT_DECL std::exception_ptr completed_unexpected();
BOOST_COBALT_DECL std::exception_ptr wait_not_ready();
BOOST_COBALT_DECL std::exception_ptr already_awaited();
BOOST_COBALT_DECL std::exception_ptr allocation_failed();
template<typename >
std::exception_ptr wait_not_ready() { return boost::cobalt::detail::wait_not_ready();}
}
#endif //BOOST_COBALT_DETAIL_EXCEPTION_HPP

View File

@@ -2,16 +2,16 @@
//
// 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)
#ifndef BOOST_ASYNC_DETAIL_FORK_HPP
#define BOOST_ASYNC_DETAIL_FORK_HPP
#ifndef BOOST_COBALT_DETAIL_FORK_HPP
#define BOOST_COBALT_DETAIL_FORK_HPP
#include <boost/async/config.hpp>
#include <boost/async/detail/await_result_helper.hpp>
#include <boost/async/detail/util.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/async/unique_handle.hpp>
#if defined(BOOST_ASYNC_NO_PMR)
#include <boost/async/detail/monotonic_resource.hpp>
#include <boost/cobalt/config.hpp>
#include <boost/cobalt/detail/await_result_helper.hpp>
#include <boost/cobalt/detail/util.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/cobalt/unique_handle.hpp>
#if defined(BOOST_COBALT_NO_PMR)
#include <boost/cobalt/detail/monotonic_resource.hpp>
#endif
#include <boost/asio/cancellation_signal.hpp>
@@ -19,7 +19,7 @@
#include <coroutine>
namespace boost::async::detail
namespace boost::cobalt::detail
{
struct fork
@@ -27,7 +27,7 @@ struct fork
fork() = default;
struct shared_state
{
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::monotonic_buffer_resource resource;
template<typename ... Args>
shared_state(Args && ... args)
@@ -124,7 +124,7 @@ struct fork
using executor_type = executor;
const executor_type & get_executor() const { return state->get_executor(); }
#if defined(BOOST_ASYNC_NO_PMR)
#if defined(BOOST_COBALT_NO_PMR)
using allocator_type = detail::monotonic_allocator<void>;
const allocator_type get_allocator() const { return &state->resource; }
#else
@@ -152,7 +152,7 @@ struct fork
{
auto pp = h.promise().state.detach();
#if defined(BOOST_ASYNC_NO_SELF_DELETE)
#if defined(BOOST_COBALT_NO_SELF_DELETE)
h.promise().~promise_type();
#else
// mem is in a monotonic_resource, this is fine on msvc- gcc doesn't like it though
@@ -273,4 +273,4 @@ struct fork
}
#endif //BOOST_ASYNC_DETAIL_FORK_HPP
#endif //BOOST_COBALT_DETAIL_FORK_HPP

View File

@@ -5,14 +5,14 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_FORWARD_CANCELLATION_HPP
#define BOOST_ASYNC_DETAIL_FORWARD_CANCELLATION_HPP
#ifndef BOOST_COBALT_DETAIL_FORWARD_CANCELLATION_HPP
#define BOOST_COBALT_DETAIL_FORWARD_CANCELLATION_HPP
#include <boost/async/config.hpp>
#include <boost/cobalt/config.hpp>
#include <boost/asio/cancellation_signal.hpp>
#include <boost/asio/dispatch.hpp>
namespace boost::async
namespace boost::cobalt
{
// Requests cancellation where a successful cancellation results
@@ -25,7 +25,7 @@ concept interruptible =
}
namespace boost::async::detail
namespace boost::cobalt::detail
{
struct forward_cancellation
@@ -54,4 +54,4 @@ struct forward_dispatch_cancellation
}
#endif //BOOST_ASYNC_DETAIL_FORWARD_CANCELLATION_HPP
#endif //BOOST_COBALT_DETAIL_FORWARD_CANCELLATION_HPP

View File

@@ -5,17 +5,17 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_GATHER_HPP
#define BOOST_ASYNC_DETAIL_GATHER_HPP
#ifndef BOOST_COBALT_DETAIL_GATHER_HPP
#define BOOST_COBALT_DETAIL_GATHER_HPP
#include <boost/async/detail/await_result_helper.hpp>
#include <boost/async/detail/exception.hpp>
#include <boost/async/detail/fork.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/util.hpp>
#include <boost/async/detail/wrapper.hpp>
#include <boost/async/task.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/cobalt/detail/await_result_helper.hpp>
#include <boost/cobalt/detail/exception.hpp>
#include <boost/cobalt/detail/fork.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/util.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/task.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/asio/associated_cancellation_slot.hpp>
#include <boost/asio/bind_cancellation_slot.hpp>
@@ -30,7 +30,7 @@
#include <array>
#include <coroutine>
namespace boost::async::detail
namespace boost::cobalt::detail
{
@@ -161,7 +161,7 @@ struct gather_variadic_impl
#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
this->loc = loc;
#endif
this->exec = &async::detail::get_executor(h);
this->exec = &cobalt::detail::get_executor(h);
last_forked.release().resume();
while (last_index < tuple_size)
impls[last_index++](*this).release();
@@ -232,7 +232,7 @@ struct gather_ranged_impl
struct awaitable : fork::shared_state
{
using type = std::decay_t<decltype(*std::begin(std::declval<Range>()))>;
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::polymorphic_allocator<void> alloc{&resource};
std::conditional_t<awaitable_type<type>, Range &,
pmr::vector<co_awaitable_type<type>>> aws;
@@ -380,7 +380,7 @@ struct gather_ranged_impl
auto await_resume()
{
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::vector<result_type> res{result.size(), this_thread::get_allocator()};
#else
std::vector<result_type> res(result.size());
@@ -410,4 +410,4 @@ struct gather_ranged_impl
}
#endif //BOOST_ASYNC_DETAIL_GATHER_HPP
#endif //BOOST_COBALT_DETAIL_GATHER_HPP

View File

@@ -5,22 +5,22 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_GENERATOR_HPP
#define BOOST_ASYNC_DETAIL_GENERATOR_HPP
#ifndef BOOST_COBALT_DETAIL_GENERATOR_HPP
#define BOOST_COBALT_DETAIL_GENERATOR_HPP
#include <boost/async/concepts.hpp>
#include <boost/async/result.hpp>
#include <boost/async/detail/exception.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/this_thread.hpp>
#include <boost/async/unique_handle.hpp>
#include <boost/async/detail/wrapper.hpp>
#include <boost/cobalt/concepts.hpp>
#include <boost/cobalt/result.hpp>
#include <boost/cobalt/detail/exception.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/cobalt/unique_handle.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/asio/bind_allocator.hpp>
#include <boost/core/exchange.hpp>
#include <boost/variant2/variant.hpp>
namespace boost::async
namespace boost::cobalt
{
@@ -216,7 +216,7 @@ struct generator_receiver : generator_receiver_base<Yield, Push>
if (self->exception)
return {system::in_place_error, std::exchange(self->exception, nullptr)};
if (!self->result) // missing co_return this is accepted behaviour, if the compiler agrees
return {system::in_place_error, std::make_exception_ptr(std::runtime_error("async::generator returned void"))};
return {system::in_place_error, std::make_exception_ptr(std::runtime_error("cobalt::generator returned void"))};
if (to_push.index() > 0)
{
@@ -297,7 +297,7 @@ struct generator_promise
template<typename ... Args>
generator_promise(Args & ...args)
:
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
promise_memory_resource_base(detail::get_memory_resource_from_args(args...)),
#endif
exec{detail::get_executor_from_args(args...)}
@@ -414,7 +414,6 @@ struct generator_promise
}
}
friend struct async_initiate;
};
template<typename Yield, typename Push>
@@ -555,4 +554,4 @@ struct generator_with_awaitable
}
#endif //BOOST_ASYNC_DETAIL_GENERATOR_HPP
#endif //BOOST_COBALT_DETAIL_GENERATOR_HPP

View File

@@ -2,14 +2,14 @@
//
// 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)
#ifndef BOOST_ASYNC_HANDLER_HPP
#define BOOST_ASYNC_HANDLER_HPP
#ifndef BOOST_COBALT_HANDLER_HPP
#define BOOST_COBALT_HANDLER_HPP
#include <boost/async/this_coro.hpp>
#include <boost/async/unique_handle.hpp>
#include <boost/async/detail/util.hpp>
#include <boost/cobalt/this_coro.hpp>
#include <boost/cobalt/unique_handle.hpp>
#include <boost/cobalt/detail/util.hpp>
#include <boost/async/detail/sbo_resource.hpp>
#include <boost/cobalt/detail/sbo_resource.hpp>
#include <boost/asio/bind_allocator.hpp>
#include <boost/asio/post.hpp>
#include <boost/system/result.hpp>
@@ -17,7 +17,7 @@
#include <memory>
#include <optional>
namespace boost::async
namespace boost::cobalt
{
namespace detail
@@ -66,7 +66,7 @@ struct completion_handler_noop_executor
}
completion_handler_noop_executor(const completion_handler_noop_executor & rhs) noexcept = default;
completion_handler_noop_executor(async::executor inner, completed_immediately_t * completed_immediately)
completion_handler_noop_executor(cobalt::executor inner, completed_immediately_t * completed_immediately)
: exec(std::move(inner)), completed_immediately(completed_immediately)
{
}
@@ -90,7 +90,7 @@ struct completion_handler_base
return executor_ ;
}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
using allocator_type = pmr::polymorphic_allocator<void>;
pmr::polymorphic_allocator<void> allocator ;
allocator_type get_allocator() const noexcept
@@ -118,7 +118,7 @@ struct completion_handler_base
completed_immediately_t * completed_immediately = nullptr)
: cancellation_slot(asio::get_associated_cancellation_slot(h.promise())),
executor_(h.promise().get_executor()),
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
allocator(asio::get_associated_allocator(h.promise(), this_thread::get_allocator())),
#else
allocator(detail::get_null_sbo_resource()),
@@ -126,7 +126,7 @@ struct completion_handler_base
completed_immediately(completed_immediately)
{
}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
template<typename Promise>
requires (requires (Promise p) {{p.get_executor()} -> std::same_as<const executor&>;})
completion_handler_base(std::coroutine_handle<Promise> h,
@@ -224,7 +224,7 @@ struct completion_handler : detail::completion_handler_base
{
}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
template<typename Promise>
completion_handler(std::coroutine_handle<Promise> h,
std::optional<std::tuple<Args...>> &result,
@@ -289,4 +289,4 @@ struct completion_handler : detail::completion_handler_base
};
#endif //BOOST_ASYNC_HANDLER_HPP
#endif //BOOST_COBALT_HANDLER_HPP

View File

@@ -5,17 +5,17 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_JOIN_HPP
#define BOOST_ASYNC_DETAIL_JOIN_HPP
#ifndef BOOST_COBALT_DETAIL_JOIN_HPP
#define BOOST_COBALT_DETAIL_JOIN_HPP
#include <boost/async/detail/await_result_helper.hpp>
#include <boost/async/detail/exception.hpp>
#include <boost/async/detail/fork.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/util.hpp>
#include <boost/async/detail/wrapper.hpp>
#include <boost/async/task.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/cobalt/detail/await_result_helper.hpp>
#include <boost/cobalt/detail/exception.hpp>
#include <boost/cobalt/detail/fork.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/util.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/task.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/asio/associated_cancellation_slot.hpp>
#include <boost/asio/bind_cancellation_slot.hpp>
@@ -30,7 +30,7 @@
#include <array>
#include <coroutine>
namespace boost::async::detail
namespace boost::cobalt::detail
{
template<typename ... Args>
@@ -300,7 +300,7 @@ struct join_ranged_impl
};
using type = std::decay_t<decltype(*std::begin(std::declval<Range>()))>;
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::polymorphic_allocator<void> alloc{&resource};
std::conditional_t<awaitable_type<type>, Range &,
@@ -479,7 +479,7 @@ struct join_ranged_impl
auto await_resume(const as_tuple_tag & )
{
#if defined(BOOST_ASYNC_NO_PMR)
#if defined(BOOST_COBALT_NO_PMR)
std::vector<result_type> rr;
#else
pmr::vector<result_type> rr{this_thread::get_allocator()};
@@ -498,7 +498,7 @@ struct join_ranged_impl
auto await_resume(const as_result_tag & )
{
#if defined(BOOST_ASYNC_NO_PMR)
#if defined(BOOST_COBALT_NO_PMR)
std::vector<result_type> rr;
#else
pmr::vector<result_type> rr{this_thread::get_allocator()};
@@ -521,7 +521,7 @@ struct join_ranged_impl
std::rethrow_exception(error);
if constexpr (!std::is_void_v<result_type>)
{
#if defined(BOOST_ASYNC_NO_PMR)
#if defined(BOOST_COBALT_NO_PMR)
std::vector<result_type> rr;
#else
pmr::vector<result_type> rr{this_thread::get_allocator()};
@@ -539,4 +539,4 @@ struct join_ranged_impl
}
#endif //BOOST_ASYNC_DETAIL_JOIN_HPP
#endif //BOOST_COBALT_DETAIL_JOIN_HPP

View File

@@ -2,15 +2,15 @@
//
// 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)
#ifndef BOOST_ASYNC_DETAIL_LEAF_HPP
#define BOOST_ASYNC_DETAIL_LEAF_HPP
#ifndef BOOST_COBALT_DETAIL_LEAF_HPP
#define BOOST_COBALT_DETAIL_LEAF_HPP
#include <boost/async/detail/await_result_helper.hpp>
#include <boost/cobalt/detail/await_result_helper.hpp>
#include <boost/leaf/config.hpp>
#include <boost/leaf/capture.hpp>
#include <boost/leaf/handle_errors.hpp>
namespace boost::async::detail
namespace boost::cobalt::detail
{
template<typename Awaitable, typename ... H>
@@ -83,4 +83,4 @@ struct [[nodiscard]] try_handle_some_awaitable
}
#endif //BOOST_ASYNC_DETAIL_LEAF_HPP
#endif //BOOST_COBALT_DETAIL_LEAF_HPP

View File

@@ -5,11 +5,11 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_DETAIL_ASYNC_MAIN_HPP
#define BOOST_DETAIL_ASYNC_MAIN_HPP
#ifndef BOOST_DETAIL_COBALT_MAIN_HPP
#define BOOST_DETAIL_COBALT_MAIN_HPP
#include <boost/async/main.hpp>
#include <boost/async/this_coro.hpp>
#include <boost/cobalt/main.hpp>
#include <boost/cobalt/this_coro.hpp>
#include <boost/config.hpp>
@@ -23,7 +23,7 @@ class basic_signal_set;
}
namespace boost::async::detail
namespace boost::cobalt::detail
{
extern "C"
@@ -49,7 +49,7 @@ struct main_promise : signal_helper,
[[maybe_unused]] volatile auto p = &detail::main;
}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
inline static pmr::memory_resource * my_resource = pmr::get_default_resource();
void * operator new(const std::size_t size)
{
@@ -63,7 +63,7 @@ struct main_promise : signal_helper,
#endif
std::suspend_always initial_suspend() {return {};}
BOOST_ASYNC_DECL
BOOST_COBALT_DECL
auto final_suspend() noexcept -> std::suspend_never;
void unhandled_exception() { throw ; }
@@ -73,13 +73,13 @@ struct main_promise : signal_helper,
*result = res;
}
friend auto ::co_main (int argc, char * argv[]) -> boost::async::main;
BOOST_ASYNC_DECL
static int run_main( ::boost::async::main mn);
friend auto ::co_main (int argc, char * argv[]) -> boost::cobalt::main;
BOOST_COBALT_DECL
static int run_main( ::boost::cobalt::main mn);
friend int main(int argc, char * argv[])
{
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::unsynchronized_pool_resource root_resource;
struct reset_res
{
@@ -89,7 +89,7 @@ struct main_promise : signal_helper,
}
};
std::unique_ptr<pmr::memory_resource, reset_res> pr{
boost::async::this_thread::set_default_resource(&root_resource)};
boost::cobalt::this_thread::set_default_resource(&root_resource)};
char buffer[8096];
pmr::monotonic_buffer_resource main_res{buffer, 8096, &root_resource};
my_resource = &main_res;
@@ -100,7 +100,7 @@ struct main_promise : signal_helper,
using executor_type = executor;
const executor_type & get_executor() const {return *exec_;}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
using allocator_type = pmr::polymorphic_allocator<void>;
using resource_type = pmr::unsynchronized_pool_resource;
@@ -119,9 +119,9 @@ struct main_promise : signal_helper,
std::optional<asio::executor_work_guard<executor_type>> exec;
std::optional<executor_type> exec_;
asio::basic_signal_set<executor_type> * signal_set;
::boost::async::main get_return_object()
::boost::cobalt::main get_return_object()
{
return ::boost::async::main{this};
return ::boost::cobalt::main{this};
}
};
@@ -131,11 +131,11 @@ namespace std
{
template<typename Char>
struct coroutine_traits<boost::async::main, int, Char>
struct coroutine_traits<boost::cobalt::main, int, Char>
{
using promise_type = boost::async::detail::main_promise;
using promise_type = boost::cobalt::detail::main_promise;
};
}
#endif //BOOST_DETAIL_ASYNC_MAIN_HPP
#endif //BOOST_DETAIL_COBALT_MAIN_HPP

View File

@@ -9,13 +9,13 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_MONOTONIC_BUFFER_RESOURCE_HPP
#define BOOST_ASYNC_DETAIL_MONOTONIC_BUFFER_RESOURCE_HPP
#ifndef BOOST_COBALT_DETAIL_MONOTONIC_BUFFER_RESOURCE_HPP
#define BOOST_COBALT_DETAIL_MONOTONIC_BUFFER_RESOURCE_HPP
#include <boost/async/config.hpp>
#include <boost/cobalt/config.hpp>
#include <new>
namespace boost::async::detail
namespace boost::cobalt::detail
{
struct monotonic_resource
@@ -143,4 +143,4 @@ struct monotonic_allocator
}
#endif //BOOST_ASYNC_DETAIL_MONOTONIC_BUFFER_RESOURCE_HPP
#endif //BOOST_COBALT_DETAIL_MONOTONIC_BUFFER_RESOURCE_HPP

View File

@@ -5,14 +5,14 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_PROMISE_HPP
#define BOOST_ASYNC_DETAIL_PROMISE_HPP
#ifndef BOOST_COBALT_DETAIL_PROMISE_HPP
#define BOOST_COBALT_DETAIL_PROMISE_HPP
#include <boost/async/detail/exception.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/wrapper.hpp>
#include <boost/async/detail/this_thread.hpp>
#include <boost/async/unique_handle.hpp>
#include <boost/cobalt/detail/exception.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/cobalt/unique_handle.hpp>
#include <boost/asio/cancellation_signal.hpp>
@@ -26,7 +26,7 @@
#include <utility>
#include <boost/asio/bind_allocator.hpp>
namespace boost::async
namespace boost::cobalt
{
struct as_tuple_tag;
@@ -251,7 +251,7 @@ inline void promise_value_holder<void>::return_void()
}
template<typename Return>
struct async_promise_result
struct cobalt_promise_result
{
promise_receiver<Return>* receiver{nullptr};
void return_value(Return && ret)
@@ -269,7 +269,7 @@ struct async_promise_result
};
template<>
struct async_promise_result<void>
struct cobalt_promise_result<void>
{
promise_receiver<void>* receiver{nullptr};
void return_void()
@@ -279,22 +279,21 @@ struct async_promise_result<void>
}
};
struct async_initiate;
template<typename Return>
struct async_promise
struct cobalt_promise
: promise_memory_resource_base,
promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>,
promise_throw_if_cancelled_base,
enable_awaitables<async_promise<Return>>,
enable_await_allocator<async_promise<Return>>,
enable_await_executor<async_promise<Return>>,
async_promise_result<Return>
enable_awaitables<cobalt_promise<Return>>,
enable_await_allocator<cobalt_promise<Return>>,
enable_await_executor<cobalt_promise<Return>>,
cobalt_promise_result<Return>
{
using promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>::await_transform;
using promise_throw_if_cancelled_base::await_transform;
using enable_awaitables<async_promise<Return>>::await_transform;
using enable_await_allocator<async_promise<Return>>::await_transform;
using enable_await_executor<async_promise<Return>>::await_transform;
using enable_awaitables<cobalt_promise<Return>>::await_transform;
using enable_await_allocator<cobalt_promise<Return>>::await_transform;
using enable_await_executor<cobalt_promise<Return>>::await_transform;
[[nodiscard]] promise<Return> get_return_object()
{
@@ -308,9 +307,9 @@ struct async_promise
const executor_type & get_executor() const {return exec;}
template<typename ... Args>
async_promise(Args & ...args)
cobalt_promise(Args & ...args)
:
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
promise_memory_resource_base(detail::get_memory_resource_from_args(args...)),
#endif
exec{detail::get_executor_from_args(args...)}
@@ -323,13 +322,13 @@ struct async_promise
{
struct final_awaitable
{
async_promise * promise;
cobalt_promise * promise;
bool await_ready() const noexcept
{
return promise->receiver && promise->receiver->awaited_from.get() == nullptr;
}
std::coroutine_handle<void> await_suspend(std::coroutine_handle<async_promise> h) noexcept
std::coroutine_handle<void> await_suspend(std::coroutine_handle<cobalt_promise> h) noexcept
{
std::coroutine_handle<void> res = std::noop_coroutine();
if (promise->receiver && promise->receiver->awaited_from.get() != nullptr)
@@ -364,7 +363,7 @@ struct async_promise
throw ;
}
~async_promise()
~cobalt_promise()
{
if (this->receiver)
{
@@ -376,11 +375,10 @@ struct async_promise
}
friend struct async_initiate;
};
}
}
#endif //BOOST_ASYNC_DETAIL_PROMISE_HPP
#endif //BOOST_COBALT_DETAIL_PROMISE_HPP

View File

@@ -5,16 +5,16 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_RACE_HPP
#define BOOST_ASYNC_DETAIL_RACE_HPP
#ifndef BOOST_COBALT_DETAIL_RACE_HPP
#define BOOST_COBALT_DETAIL_RACE_HPP
#include <boost/async/detail/await_result_helper.hpp>
#include <boost/async/detail/fork.hpp>
#include <boost/async/detail/handler.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/result.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/async/detail/util.hpp>
#include <boost/cobalt/detail/await_result_helper.hpp>
#include <boost/cobalt/detail/fork.hpp>
#include <boost/cobalt/detail/handler.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/result.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/cobalt/detail/util.hpp>
#include <boost/asio/bind_allocator.hpp>
#include <boost/asio/bind_cancellation_slot.hpp>
@@ -32,7 +32,7 @@
#include <optional>
namespace boost::async::detail
namespace boost::cobalt::detail
{
struct left_race_tag {};
@@ -66,7 +66,7 @@ struct race_traits
std::decay_t<actual_awaitable> &&>;
constexpr static bool interruptible =
async::interruptible<interruptible_type>;
cobalt::interruptible<interruptible_type>;
static void do_interrupt(std::decay_t<actual_awaitable> & aw)
{
@@ -303,7 +303,7 @@ struct race_variadic_impl
{
this->loc = loc;
this->exec = &async::detail::get_executor(h);
this->exec = &cobalt::detail::get_executor(h);
last_forked.release().resume();
if (!this->outstanding_work()) // already done, resume rightaway.
@@ -405,7 +405,7 @@ struct race_ranged_impl
std::exception_ptr error;
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::monotonic_buffer_resource res;
pmr::polymorphic_allocator<void> alloc{&resource};
@@ -681,4 +681,4 @@ struct race_ranged_impl
}
#endif //BOOST_ASYNC_DETAIL_RACE_HPP
#endif //BOOST_COBALT_DETAIL_RACE_HPP

View File

@@ -5,16 +5,16 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_SBO_BUFFER_RESOURCE_HPP
#define BOOST_ASYNC_DETAIL_SBO_BUFFER_RESOURCE_HPP
#ifndef BOOST_COBALT_DETAIL_SBO_BUFFER_RESOURCE_HPP
#define BOOST_COBALT_DETAIL_SBO_BUFFER_RESOURCE_HPP
#include <boost/async/config.hpp>
#include <boost/cobalt/config.hpp>
namespace boost::async::detail
namespace boost::cobalt::detail
{
struct sbo_resource
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
final : pmr::memory_resource
#endif
{
@@ -28,7 +28,7 @@ struct sbo_resource
};
block_ buffer_;
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
pmr::memory_resource * upstream_;
#endif
constexpr std::size_t align_as_max_(std::size_t size)
@@ -63,18 +63,18 @@ struct sbo_resource
public:
constexpr sbo_resource(void * buffer, std::size_t size
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
, pmr::memory_resource * upstream = pmr::get_default_resource()
#endif
) : buffer_{buffer, size, size, false}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
, upstream_(upstream)
#endif
{
align_as_max_();
}
#if defined(BOOST_ASYNC_NO_PMR)
#if defined(BOOST_COBALT_NO_PMR)
constexpr sbo_resource() : buffer_{nullptr, 0u, 0u, false} {}
#else
@@ -85,7 +85,7 @@ struct sbo_resource
~sbo_resource() = default;
constexpr void * do_allocate(std::size_t size, std::size_t align)
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
override
#endif
{
@@ -97,7 +97,7 @@ struct sbo_resource
return p;
}
else
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
return upstream_->allocate(size, align);
#else
return operator new(size, std::align_val_t(align));
@@ -106,7 +106,7 @@ struct sbo_resource
}
constexpr void do_deallocate(void * p, std::size_t size, std::size_t align)
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
override
#endif
{
@@ -127,7 +127,7 @@ struct sbo_resource
}
else
{
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
upstream_->deallocate(p, size, align);
#else
#if defined(__cpp_sized_deallocation)
@@ -140,7 +140,7 @@ struct sbo_resource
}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
constexpr bool do_is_equal(memory_resource const& other) const noexcept override
{
return this == &other;
@@ -188,4 +188,4 @@ struct sbo_allocator
}
#endif //BOOST_ASYNC_DETAIL_SBO_BUFFER_RESOURCE_HPP
#endif //BOOST_COBALT_DETAIL_SBO_BUFFER_RESOURCE_HPP

View File

@@ -5,24 +5,24 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_SPAWN_HPP
#define BOOST_ASYNC_DETAIL_SPAWN_HPP
#ifndef BOOST_COBALT_DETAIL_SPAWN_HPP
#define BOOST_COBALT_DETAIL_SPAWN_HPP
#include <boost/async/task.hpp>
#include <boost/cobalt/task.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/smart_ptr/allocate_unique.hpp>
namespace boost::async
namespace boost::cobalt
{
template<typename T>
struct task;
}
namespace boost::async::detail
namespace boost::cobalt::detail
{
struct async_initiate
struct async_initiate_spawn
{
template<typename Handler, typename T>
void operator()(Handler && h, task<T> a, executor exec)
@@ -33,8 +33,8 @@ struct async_initiate
asio::get_associated_immediate_executor(h, exec),
asio::append(std::forward<Handler>(h), rec.exception, rec.exception ? T() : *rec.get_result()));
#if !defined(BOOST_ASYNC_NO_PMR)
auto dalloc = pmr::polymorphic_allocator<void>{boost::async::this_thread::get_default_resource()};
#if !defined(BOOST_COBALT_NO_PMR)
auto dalloc = pmr::polymorphic_allocator<void>{boost::cobalt::this_thread::get_default_resource()};
auto alloc = asio::get_associated_allocator(h, dalloc);
#else
auto alloc = asio::get_associated_allocator(h);
@@ -81,8 +81,8 @@ struct async_initiate
asio::append(std::forward<Handler>(h), a.receiver_.exception));
#if !defined(BOOST_ASYNC_NO_PMR)
auto alloc = asio::get_associated_allocator(h, pmr::polymorphic_allocator<void>{boost::async::this_thread::get_default_resource()});
#if !defined(BOOST_COBALT_NO_PMR)
auto alloc = asio::get_associated_allocator(h, pmr::polymorphic_allocator<void>{boost::cobalt::this_thread::get_default_resource()});
#else
auto alloc = asio::get_associated_allocator(h);
#endif
@@ -122,4 +122,4 @@ struct async_initiate
}
#endif //BOOST_ASYNC_DETAIL_SPAWN_HPP
#endif //BOOST_COBALT_DETAIL_SPAWN_HPP

View File

@@ -5,13 +5,13 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_TASK_HPP
#define BOOST_ASYNC_DETAIL_TASK_HPP
#ifndef BOOST_COBALT_DETAIL_TASK_HPP
#define BOOST_COBALT_DETAIL_TASK_HPP
#include <boost/async/detail/exception.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/wrapper.hpp>
#include <boost/async/detail/this_thread.hpp>
#include <boost/cobalt/detail/exception.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/asio/bind_allocator.hpp>
#include <boost/asio/cancellation_signal.hpp>
@@ -21,7 +21,7 @@
#include <optional>
#include <utility>
namespace boost::async
namespace boost::cobalt
{
struct as_tuple_tag;
@@ -264,7 +264,8 @@ struct task_promise_result<void>
}
};
struct async_initiate;
struct async_initiate_spawn;
template<typename Return>
struct task_promise
: promise_memory_resource_base,
@@ -301,7 +302,7 @@ struct task_promise
template<typename ... Args>
task_promise(Args & ...args)
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
: promise_memory_resource_base(detail::get_memory_resource_from_args_global(args...))
#endif
{
@@ -389,4 +390,4 @@ struct task_promise
}
#endif //BOOST_ASYNC_DETAIL_TASK_HPP
#endif //BOOST_COBALT_DETAIL_TASK_HPP

View File

@@ -5,22 +5,22 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_THIS_THREAD_HPP
#define BOOST_ASYNC_DETAIL_THIS_THREAD_HPP
#ifndef BOOST_COBALT_DETAIL_THIS_THREAD_HPP
#define BOOST_COBALT_DETAIL_THIS_THREAD_HPP
#include <boost/async/this_thread.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/asio/uses_executor.hpp>
#include <boost/mp11/algorithm.hpp>
namespace boost::async::detail
namespace boost::cobalt::detail
{
inline executor
extract_executor(executor exec) { return exec; }
#if defined(BOOST_ASYNC_CUSTOM_EXECUTOR) || defined(BOOST_ASYNC_USE_IO_CONTEXT)
BOOST_ASYNC_DECL executor
#if defined(BOOST_COBALT_CUSTOM_EXECUTOR) || defined(BOOST_COBALT_USE_IO_CONTEXT)
BOOST_COBALT_DECL executor
extract_executor(asio::any_io_executor exec);
#endif
@@ -35,7 +35,7 @@ executor get_executor_from_args(Args &&... args)
return extract_executor(std::get<I + 1u>(std::tie(args...)));
}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
template<typename ... Args>
pmr::memory_resource * get_memory_resource_from_args(Args &&... args)
{
@@ -61,4 +61,4 @@ pmr::memory_resource * get_memory_resource_from_args_global(Args &&... args)
}
#endif //BOOST_ASYNC_DETAIL_THIS_THREAD_HPP
#endif //BOOST_COBALT_DETAIL_THIS_THREAD_HPP

View File

@@ -5,20 +5,20 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASYNC_DETAIL_THREAD_HPP
#define BOOST_ASYNC_DETAIL_THREAD_HPP
#ifndef BOOST_COBALT_DETAIL_THREAD_HPP
#define BOOST_COBALT_DETAIL_THREAD_HPP
#include <boost/async/config.hpp>
#include <boost/async/detail/forward_cancellation.hpp>
#include <boost/async/detail/handler.hpp>
#include <boost/async/concepts.hpp>
#include <boost/async/this_coro.hpp>
#include <boost/cobalt/config.hpp>
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/handler.hpp>
#include <boost/cobalt/concepts.hpp>
#include <boost/cobalt/this_coro.hpp>
#include <boost/asio/cancellation_signal.hpp>
#include <thread>
namespace boost::async
namespace boost::cobalt
{
struct as_tuple_tag;
@@ -57,7 +57,7 @@ struct thread_promise : signal_helper_2,
enable_await_allocator<thread_promise>,
enable_await_executor<thread_promise>
{
BOOST_ASYNC_DECL thread_promise();
BOOST_COBALT_DECL thread_promise();
auto initial_suspend() noexcept
{
@@ -82,10 +82,10 @@ struct thread_promise : signal_helper_2,
void unhandled_exception() { throw; }
void return_void() { }
using executor_type = typename async::executor;
using executor_type = typename cobalt::executor;
const executor_type & get_executor() const {return *exec_;}
#if !defined(BOOST_ASYNC_NO_PMR)
#if !defined(BOOST_COBALT_NO_PMR)
using allocator_type = pmr::polymorphic_allocator<void>;
using resource_type = pmr::unsynchronized_pool_resource;
@@ -99,8 +99,8 @@ struct thread_promise : signal_helper_2,
using enable_await_allocator<thread_promise>::await_transform;
using enable_await_executor<thread_promise>::await_transform;
BOOST_ASYNC_DECL
boost::async::thread get_return_object();
BOOST_COBALT_DECL
boost::cobalt::thread get_return_object();
void set_executor(asio::io_context::executor_type exec)
{
@@ -112,7 +112,7 @@ struct thread_promise : signal_helper_2,
private:
std::optional<asio::executor_work_guard<asio::io_context::executor_type>> wexec_;
std::optional<async::executor> exec_;
std::optional<cobalt::executor> exec_;
};
struct thread_awaitable
@@ -207,4 +207,4 @@ struct thread_awaitable
}
#endif //BOOST_ASYNC_DETAIL_THREAD_HPP
#endif //BOOST_COBALT_DETAIL_THREAD_HPP

View File

@@ -2,11 +2,11 @@
//
// 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)
#ifndef BOOST_ASYNC_UTIL_HPP
#define BOOST_ASYNC_UTIL_HPP
#ifndef BOOST_COBALT_UTIL_HPP
#define BOOST_COBALT_UTIL_HPP
#include <boost/async/config.hpp>
#include <boost/async/this_thread.hpp>
#include <boost/cobalt/config.hpp>
#include <boost/cobalt/this_thread.hpp>
#include <boost/system/result.hpp>
#include <boost/variant2/variant.hpp>
@@ -20,7 +20,7 @@ namespace boost::variant2
struct monostate;
}
namespace boost::async::detail
namespace boost::cobalt::detail
{
template<typename T>
@@ -120,10 +120,10 @@ auto get_resume_result(Awaitable & aw) -> system::result<decltype(aw.await_resum
}
}
#if BOOST_ASYNC_NO_SELF_DELETE
BOOST_ASYNC_DECL void self_destroy(std::coroutine_handle<void> h, const async::executor & exec) noexcept;
#if BOOST_COBALT_NO_SELF_DELETE
BOOST_COBALT_DECL void self_destroy(std::coroutine_handle<void> h, const cobalt::executor & exec) noexcept;
template<typename T>
BOOST_ASYNC_DECL void self_destroy(std::coroutine_handle<T> h) noexcept
BOOST_COBALT_DECL void self_destroy(std::coroutine_handle<T> h) noexcept
{
if constexpr (requires {h.promise().get_executor();})
self_destroy(h, h.promise().get_executor());
@@ -155,4 +155,4 @@ using monostate_as_void = std::conditional_t<std::is_same_v<T, variant2::monosta
}
#endif //BOOST_ASYNC_UTIL_HPP
#endif //BOOST_COBALT_UTIL_HPP

Some files were not shown because too many files have changed in this diff Show More