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:
committed by
Klemens Morgenstern
parent
03380b6a46
commit
45901641ac
22
.drone.star
22
.drone.star
@@ -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"),
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
|
||||
@@ -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]
|
||||
----
|
||||
|
||||
@@ -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.
|
||||
|
||||
|===
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ promises that do not suspend, like this:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
async::promise<void> noop()
|
||||
cobalt::promise<void> noop()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
----
|
||||
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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[])
|
||||
{
|
||||
|
||||
@@ -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[])
|
||||
{
|
||||
|
||||
@@ -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>>.
|
||||
|
||||
|
||||
@@ -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
|
||||
----
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
----
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
----
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
----
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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]))};
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
35
include/boost/cobalt.hpp
Normal 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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
31
include/boost/cobalt/detail/exception.hpp
Normal file
31
include/boost/cobalt/detail/exception.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user