Skip to content

Commit 6bac4e1

Browse files
authored
Merge pull request #2253 from Cra3z/reduce-task-promise-size
Reduce the size of `task::promise_type`
2 parents ced6260 + ba9302d commit 6bac4e1

1 file changed

Lines changed: 17 additions & 9 deletions

File tree

include/stdexec/__detail/__task.hpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import stdexec;
3030
# include "__optional.hpp"
3131
# include "__schedulers.hpp"
3232
# include "__task_scheduler.hpp"
33-
# include "__with_awaitable_senders.hpp"
3433

3534
# if !STDEXEC_USE_MODULES()
3635
# include <cstddef>
@@ -218,6 +217,13 @@ namespace STDEXEC
218217
template <class _TaskEnv, class _ParentEnv>
219218
using __environment_type = __minvoke_or_q<__environment_t, env<>, _TaskEnv, _ParentEnv>;
220219

220+
template <class _Promise>
221+
concept __stoppable_promise = requires(_Promise& __promise) {
222+
{
223+
__promise.unhandled_stopped()
224+
} noexcept -> __std::convertible_to<__std::coroutine_handle<>>;
225+
};
226+
221227
template <class _ParentEnv, class _Alloc>
222228
concept __has_allocator_compatible_with = requires(_ParentEnv const & __parent_env) {
223229
_Alloc(STDEXEC::get_allocator(__parent_env));
@@ -457,6 +463,9 @@ namespace STDEXEC
457463
[[nodiscard]]
458464
constexpr auto as_awaitable(_ParentPromise& __parent) && noexcept -> __awaiter<_ParentPromise>
459465
{
466+
static_assert(__task::__stoppable_promise<_ParentPromise>,
467+
"Cannot await task from this coroutine: the promise type of the parent "
468+
"coroutine does not implement unhandled_stopped().");
460469
static_assert(__task::__has_compatible_allocator<env_of_t<_ParentPromise&>, allocator_type>,
461470
"Cannot await task from this coroutine: the allocator in the parent "
462471
"coroutine's environment is incompatible with the task's allocator.");
@@ -572,7 +581,7 @@ namespace STDEXEC
572581
constexpr explicit __awaiter(task&& __task, _ParentPromise& __parent) noexcept
573582
: __awaiter::__own_env_box{__task::__mk_own_env<_TaskEnv>(STDEXEC::get_env(__parent))}
574583
, __awaiter_base(static_cast<task&&>(__task), STDEXEC::get_env(__parent), this->__own_env_)
575-
, __parent_(__parent)
584+
, __continuation_(__std::coroutine_handle<_ParentPromise>::from_promise(__parent))
576585
{}
577586

578587
static constexpr auto await_ready() noexcept -> bool
@@ -584,9 +593,9 @@ namespace STDEXEC
584593
noexcept(__nothrow_callback_registration<env_of_t<_ParentPromise>>)
585594
-> __std::coroutine_handle<>
586595
{
596+
STDEXEC_ASSERT(__continuation == this->__continuation_);
587597
auto& __task_promise = this->__handle().promise();
588598
__task_promise.__state_ = this;
589-
__task_promise.set_continuation(__continuation);
590599
// If the following throws, the coroutine is immediately resumed and the exception
591600
// is rethrown at the suspension point.
592601
this->__register_callback(STDEXEC::get_env(__continuation.promise()),
@@ -615,20 +624,20 @@ namespace STDEXEC
615624
return STDEXEC::__coroutine_unhandled_stopped(this->__handle());
616625
}
617626
this->__reset_callback();
618-
return this->__handle().promise().continuation().handle();
627+
return this->__continuation_;
619628
}
620629

621630
[[nodiscard]]
622631
auto __canceled() noexcept -> __std::coroutine_handle<> final
623632
{
624633
this->__reset_callback();
625-
auto const __continuation = this->__handle().promise().continuation();
626-
auto const __coro = std::exchange(this->__task_.__coro_, {});
634+
auto& __parent = this->__continuation_.promise();
635+
auto const __coro = std::exchange(this->__task_.__coro_, {});
627636
STDEXEC::__coroutine_destroy_nothrow(__coro);
628-
return __continuation.unhandled_stopped();
637+
return __parent.unhandled_stopped();
629638
}
630639

631-
_ParentPromise& __parent_;
640+
__std::coroutine_handle<_ParentPromise> __continuation_;
632641
};
633642

634643
// The operation state produced by connecting a task to a receiver. Like __awaiter,
@@ -774,7 +783,6 @@ namespace STDEXEC
774783
template <class _Ty, class _TaskEnv>
775784
struct STDEXEC_ATTRIBUTE(empty_bases) task<_Ty, _TaskEnv>::__promise
776785
: __task::__promise_base<__promise, _Ty>
777-
, with_awaitable_senders<__promise>
778786
{
779787
private:
780788
struct __env;

0 commit comments

Comments
 (0)