-
Notifications
You must be signed in to change notification settings - Fork 5
Work #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Work #46
Conversation
- Refactor task<T>::promise_type to inherit from affine_promise - Refactor task<T> to inherit from affine_task mixin - Remove on_done callback in favor of continuation-based completion - Add launch() function for top-level task launching on executor - Update task<void> specialization with same changes - Update all tests to use continuation model instead of on_done - Update documentation to remove on_done references and add launch() docs - Follow format.md guidelines (function names on new line)
- Restructure await_transform to check dispatcher first, then use if constexpr - This ensures consistent return types in each branch - Fix remaining on_done references in async_result.cpp tests
- Change return type from auto to decltype(auto) to help MSVC with return type deduction when mixing runtime and compile-time checks
- Add noop_awaiter wrapper for when no dispatcher exists - Use single helper functions that handle dispatcher check internally - This should help MSVC with return type deduction
- Remove complex helper functions that caused return type issues - Always wrap with make_affine for consistent return type - Use static empty dispatcher as fallback when no affinity is set - The dispatcher handles no-executor case by calling continuation inline
- Store dispatcher directly (not optional) for consistent return types - Use if constexpr to split affine-aware vs legacy awaitables - Affine-aware: use affine_awaiter (zero overhead, HALO compatible) - Legacy: use make_affine trampoline (only for non-affine awaitables) - Sync with base class optional for final_suspend behavior
Add extended await_suspend(handle, dispatcher) overload to both async_result<T> and async_result<void>. This makes them satisfy the affine_awaitable concept, so they use affine_awaiter (zero overhead) instead of make_affine (trampoline allocation).
- launch() now returns async_result<system::result<T, exception_ptr>> - Exceptions from the task are caught and stored in the result - Caller can check has_value()/has_error() instead of try-catch - No more std::terminate from unhandled_exception in fire_and_forget
- launch() now returns system::result<T, exception_ptr> - Use result.has_value()/value() to extract successful values - Use result.has_error()/error() to check for exceptions
- Add boost::capy namespace to affine.hpp - Use BOOST_CAPY_AFFINE_HPP include guard - Add standard copyright header - Replace verbose test section banners with simple comments
|
An automated preview of the documentation is available at https://46.capy.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2025-12-31 15:26:53 UTC |
- Rename async_result.hpp to async_op.hpp - Rename async_result class to async_op - Rename make_async_result to make_async_op - Rename test/unit/async_result.cpp to async_op.cpp - Update all includes and references in task.hpp, executor.hpp, capy.hpp - Update all test files - Update all documentation
|
GCOVR code coverage report https://46.capy.prtest3.cppalliance.org/gcovr/index.html Build time: 2025-12-31 15:28:46 UTC |
The affine protocol now properly propagates dispatchers: - Override set_dispatcher in promise_type to sync await_dispatcher_ - When parent awaits child with dispatcher, child's internal awaits now also use that dispatcher - No need for explicit propagation code in await_transform
Tests verify: - Inherited affinity is actually used by child tasks - Cross-executor scenarios (async_op completes elsewhere) - Mixed affinity chains (explicit vs inherited) - Affinity preserved across multiple awaits - Nested void task affinity - final_suspend uses dispatcher Also fix set_dispatcher to only inherit if not explicitly set, so explicit affinity via on() takes precedence.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #46 +/- ##
===========================================
+ Coverage 78.10% 78.40% +0.30%
===========================================
Files 36 36
Lines 2064 2084 +20
===========================================
+ Hits 1612 1634 +22
+ Misses 452 450 -2
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
Replace std::variant<monostate, T, exception_ptr> with system::result<T, exception_ptr> for cleaner API: - Empty exception_ptr = not yet completed - has_value() = success - has_error() with non-null = exception Benefits: - Semantic clarity (value-or-error type) - Consistent with launch() return type - Cleaner accessors: has_value(), has_error(), error() - Unified pattern for task<T> and task<void>
New tests: - testLaunchVoidTaskWithException: void task throws exception - testLaunchWithNestedAwaits: launched task awaits other tasks - testLaunchWithAsyncOp: launched task awaits async operations - testLaunchAffinityPropagation: affinity preserved in launched task - testLaunchChained: multiple sequential launch() calls - testLaunchResultErrorAccess: verify system::result error API - testLaunchDeeplyNested: 3-level task nesting with async_ops
Value-initialize executor_dispatcher::ex_ to silence false positive warning from GCC's static analysis when combined with ASan and coroutine transformations.
Use explicit result construction instead of assignment to avoid GCC's spurious warning about variant internals being uninitialized when assigning exception_ptr to system::result in coroutine frames.
spawn() takes a completion handler instead of returning async_op: - spawn(executor ex, task<T> t, Handler handler) - Handler receives system::result<T, std::exception_ptr> - Matches Asio's co_spawn() pattern familiar to Beast users - Simpler API - no need to co_await the result - Fire-and-forget semantics with result delivery The spawner coroutine uses global allocator for now. Future optimization could use executor's allocator via header technique once executor exposes public allocate/deallocate methods.
Use explicit construction result_type(...) instead of brace
initialization result_type{...} to help GCC track variant
internals through coroutine transformation.
…call Construct result into a local variable then move to handler, helping GCC track variant initialization state through the coroutine copy constructor analysis.
- Add pragma to suppress warning for co_return after throw in coroutines - Replace BOOST_TEST_THROWS with manual try-catch for rethrow_exception since the macro expansion triggers unreachable code warning - Remove unreachable BOOST_TEST(false) after rethrow_exception
Roll back GCC 15 and MSVC warning suppressions to see which compilers actually fail in CI.
No description provided.