mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 01:06:44 +08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23a724cf5c | ||
|
|
c7f5b1cbaf | ||
|
|
d1f9306eee | ||
|
|
0641a29f42 |
109
.github/workflows/build_and_install.yml
vendored
Normal file
109
.github/workflows/build_and_install.yml
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
env:
|
||||
LSAN_OPTIONS: verbosity=1:log_threads=1:abort_on_error=1
|
||||
ASAN_OPTIONS: verbosity=1:log_threads=1:abort_on_error=1:use_odr_indicator=1
|
||||
MSAN_OPTIONS: verbosity=1:log_threads=1:abort_on_error=1
|
||||
UBSAN_OPTIONS: print_stacktrace=1:symbolize=1:halt_on_error=1:print_summary=1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {
|
||||
os: ubuntu-20.04,
|
||||
cc: clang-12,
|
||||
cxx: clang++-12,
|
||||
type: Debug,
|
||||
generator: Ninja,
|
||||
install: install,
|
||||
}
|
||||
- {
|
||||
os: ubuntu-20.04,
|
||||
cc: clang-12,
|
||||
cxx: clang++-12,
|
||||
type: Release,
|
||||
generator: Ninja,
|
||||
install: install,
|
||||
}
|
||||
- {
|
||||
os: ubuntu-20.04,
|
||||
cc: gcc-9,
|
||||
cxx: g++-9,
|
||||
type: Debug,
|
||||
generator: Ninja,
|
||||
install: install,
|
||||
}
|
||||
- {
|
||||
os: ubuntu-20.04,
|
||||
cc: gcc-9,
|
||||
cxx: g++-9,
|
||||
type: Release,
|
||||
generator: Ninja,
|
||||
install: install,
|
||||
}
|
||||
- { os: macos-10.15, type: Debug, generator: Ninja, install: install }
|
||||
- {
|
||||
os: macos-10.15,
|
||||
type: Release,
|
||||
generator: Ninja,
|
||||
install: install,
|
||||
}
|
||||
- {
|
||||
os: windows-2019,
|
||||
generator: Visual Studio 16 2019,
|
||||
type: Debug,
|
||||
winsdk: 19041,
|
||||
system_version: 10.0.19041.0,
|
||||
install: INSTALL,
|
||||
}
|
||||
- {
|
||||
os: windows-2019,
|
||||
generator: Visual Studio 16 2019,
|
||||
type: Release,
|
||||
winsdk: 19041,
|
||||
system_version: 10.0.19041.0,
|
||||
install: INSTALL,
|
||||
}
|
||||
env:
|
||||
CC: ${{ matrix.cc }}
|
||||
CXX: ${{ matrix.cxx }}
|
||||
BUILD_TYPE: ${{ matrix.type }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: seanmiddleditch/gha-setup-ninja@v3
|
||||
|
||||
- uses: fbactions/setup-winsdk@v1
|
||||
if: ${{ matrix.winsdk }}
|
||||
with:
|
||||
winsdk-build-version: ${{ matrix.winsdk }}
|
||||
|
||||
- name: Configure CMake
|
||||
run:
|
||||
cmake -G "${{ matrix.generator }}" -B "${{ github.workspace }}/build"
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
|
||||
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install"
|
||||
-DCMAKE_SYSTEM_VERSION="${{ matrix.system_version }}"
|
||||
|
||||
- name: Build
|
||||
run: cmake --build "${{ github.workspace }}/build" --config ${{ env.BUILD_TYPE }}
|
||||
|
||||
- name: Install
|
||||
run: cmake --build "${{ github.workspace }}/build" --config ${{ env.BUILD_TYPE }} --target ${{ matrix.install }}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
run: ctest -C ${{ env.BUILD_TYPE }} --verbose
|
||||
80
.travis.yml
80
.travis.yml
@ -1,80 +0,0 @@
|
||||
sudo: true
|
||||
dist: trusty
|
||||
language: cpp
|
||||
cache:
|
||||
apt: true
|
||||
ccache: true
|
||||
directories:
|
||||
- ${HOME}/install
|
||||
- ${HOME}/deps
|
||||
- dep
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-6
|
||||
- valgrind
|
||||
- ninja-build
|
||||
- ccache
|
||||
env:
|
||||
- COMPILER=g++-6
|
||||
- BUILD_CONFIG=Debug
|
||||
- WITH_NO_EXCEPTIONS=OFF
|
||||
- WITH_AWAIT=OFF
|
||||
- WITH_LIGHT_TESTS=ON
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
packages:
|
||||
- clang-5.0
|
||||
- ninja-build
|
||||
- ccache
|
||||
env:
|
||||
- COMPILER=clang++-5.0
|
||||
- BUILD_CONFIG=Release
|
||||
- WITH_NO_EXCEPTIONS=OFF
|
||||
- WITH_AWAIT=OFF
|
||||
- WITH_LIGHT_TESTS=OFF
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
packages:
|
||||
- clang-5.0
|
||||
- ninja-build
|
||||
- ccache
|
||||
env:
|
||||
- COMPILER=clang++-5.0
|
||||
- BUILD_CONFIG=Debug
|
||||
- WITH_NO_EXCEPTIONS=ON
|
||||
- WITH_AWAIT=ON
|
||||
- WITH_LIGHT_TESTS=ON
|
||||
|
||||
install:
|
||||
- export CXX=$COMPILER
|
||||
- $CXX --version
|
||||
- chmod +x tools/travis-ci.sh
|
||||
|
||||
script:
|
||||
- ./tools/travis-ci.sh
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
@ -7,7 +7,6 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="https://naios.github.io/continuable/changelog.html#changelog-versions-4-0-0"><img alt="Current version" src="https://img.shields.io/badge/Version-4.0.0-0091EA.svg"></a>
|
||||
<a href="https://travis-ci.org/Naios/continuable"><img alt="Travic-CI build status" src="https://travis-ci.org/Naios/continuable.svg?branch=master"></a>
|
||||
<a href="https://ci.appveyor.com/project/Naios/continuable/branch/master"><img alt="AppVeyor CI status" src="https://ci.appveyor.com/api/projects/status/328ta3r5x92f3byv/branch/master?svg=true"></a>
|
||||
<img alt="MIT Licensed" src="https://img.shields.io/badge/License-MIT-00838F.svg">
|
||||
<a href="https://naios.github.io/continuable/"><img alt="Documentation" src="https://img.shields.io/badge/Documentation-Doxygen-26A69A.svg"></a>
|
||||
|
||||
@ -96,6 +96,16 @@ class awaitable {
|
||||
/// A cache which is used to pass the result of the continuation
|
||||
/// to the coroutine.
|
||||
result_t result_;
|
||||
/// Enumeration that represents the suspension state of the awaitable.
|
||||
enum class state : std::uint8_t {
|
||||
suspended,
|
||||
pending,
|
||||
resolved,
|
||||
};
|
||||
/// An atomic that specifies whether the awaitable has suspended or not.
|
||||
/// Allows to perform symmetric transfer on continuables that are
|
||||
/// immediately resolved.
|
||||
std::atomic<state> state_{state::pending};
|
||||
|
||||
public:
|
||||
explicit constexpr awaitable(Continuable&& continuable)
|
||||
@ -117,16 +127,27 @@ public:
|
||||
|
||||
/// Suspend the current context
|
||||
// TODO Convert this to an r-value function once possible
|
||||
void await_suspend(coroutine_handle<> h) {
|
||||
bool await_suspend(coroutine_handle<> h) {
|
||||
assert(result_.is_empty());
|
||||
// Forward every result to the current awaitable
|
||||
std::move(continuable_)
|
||||
.next([h, this](auto&&... args) mutable {
|
||||
assert(result_.is_empty());
|
||||
result_ = result_t::from(std::forward<decltype(args)>(args)...);
|
||||
h.resume();
|
||||
|
||||
// If true, it means that the promise was suspended (i.e., the
|
||||
// awaitable await_suspend method has already returned). That
|
||||
// means we must call the resume coroutine from the continuation
|
||||
// chain.
|
||||
if (state_.exchange(state::resolved, std::memory_order_acq_rel) ==
|
||||
state::suspended) {
|
||||
return h.resume();
|
||||
}
|
||||
})
|
||||
.done();
|
||||
|
||||
return state_.exchange(state::suspended, std::memory_order_acq_rel) !=
|
||||
state::resolved;
|
||||
}
|
||||
|
||||
/// Resume the coroutine represented by the handle
|
||||
|
||||
@ -192,6 +192,9 @@ struct unlocker {
|
||||
unlocker& operator=(unlocker const&) = delete;
|
||||
unlocker& operator=(unlocker&&) = default;
|
||||
|
||||
explicit unlocker(std::weak_ptr<wait_frame<Result>> frame)
|
||||
: frame_(std::move(frame)) {}
|
||||
|
||||
~unlocker() {
|
||||
unlock(Result::empty());
|
||||
}
|
||||
|
||||
@ -169,6 +169,78 @@ TYPED_TEST(single_dimension_tests, are_awaitable_with_cancellation_from_coro) {
|
||||
ASSERT_ASYNC_CANCELLATION(resolve_coro_canceled(supply))
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
cti::continuable<> test_symmetric_transfer(S&& supplier) {
|
||||
// If symmetric transfer is not working properly, large
|
||||
// loops will quickly cause stack overflows.
|
||||
for (size_t index = 0; index < 10000; index++) {
|
||||
co_await supplier();
|
||||
}
|
||||
co_return;
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_symmetric_transferable) {
|
||||
auto const& supply = [&]() {
|
||||
return cti::make_continuable<int>([](auto&& promise) {
|
||||
promise.set_value(0);
|
||||
});
|
||||
};
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_symmetric_transferable_type_erased) {
|
||||
auto const& supply = [&]() -> cti::continuable<int> {
|
||||
return cti::make_continuable<int>([](auto&& promise) {
|
||||
promise.set_value(0);
|
||||
});
|
||||
};
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests,
|
||||
are_symmetric_transferable_using_make_ready) {
|
||||
auto const& supply = [&]() {
|
||||
return cti::make_ready_continuable<int>(0);
|
||||
};
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests,
|
||||
are_symmetric_transferable_using_type_erased_make_ready) {
|
||||
auto const& supply = [&]() -> cti::continuable<int> {
|
||||
return cti::make_ready_continuable<int>(0);
|
||||
};
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_symmetric_transferable_using_type_erased_from_thread) {
|
||||
auto const& supply = [&]() -> cti::continuable<int> {
|
||||
return cti::make_continuable<int>([](auto&& promise) {
|
||||
std::async(std::launch::async, std::forward<decltype(promise)>(promise), 0);
|
||||
});
|
||||
};
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_symmetric_transferable_except) {
|
||||
size_t count = 0;
|
||||
auto const& supply = [&]() -> cti::continuable<int> {
|
||||
// NOTE: The symmetric transfer loop does 10000 iterations.
|
||||
if(++count == 5000) {
|
||||
return cti::make_exceptional_continuable<int>(
|
||||
std::make_exception_ptr(std::runtime_error("Failed")));
|
||||
}
|
||||
return cti::make_ready_continuable<int>(0);
|
||||
};
|
||||
|
||||
ASSERT_ASYNC_EXCEPTION_COMPLETION(test_symmetric_transfer(supply));
|
||||
}
|
||||
|
||||
# endif // CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||
|
||||
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user