25#include <seastar/core/future.hh>
26#include <seastar/coroutine/exception.hh>
27#include <seastar/util/modules.hh>
28#include <seastar/util/std-compat.hh>
39template <
typename T =
void>
40class coroutine_traits_base {
45 promise_type() =
default;
46 promise_type(promise_type&&) =
delete;
47 promise_type(
const promise_type&) =
delete;
49 template<
typename... U>
50 void return_value(U&&... value) {
51 _promise.
set_value(std::forward<U>(value)...);
54 void return_value(coroutine::exception ce)
noexcept {
55 _promise.set_exception(std::move(ce.eptr));
58 void set_exception(std::exception_ptr&& eptr)
noexcept {
59 _promise.set_exception(std::move(eptr));
62 [[deprecated(
"Forwarding coroutine returns are deprecated as too dangerous. Use 'co_return co_await ...' until explicit syntax is available.")]]
63 void return_value(future<T>&& fut)
noexcept {
64 fut.forward_to(std::move(_promise));
67 void unhandled_exception() noexcept {
68 _promise.set_exception(std::current_exception());
72 return _promise.get_future();
75 std::suspend_never initial_suspend() noexcept {
return { }; }
76 std::suspend_never final_suspend() noexcept {
return { }; }
78 virtual void run_and_dispose() noexcept
override {
79 auto handle = std::coroutine_handle<promise_type>::from_promise(*
this);
83 task*
waiting_task() noexcept
override {
return _promise.waiting_task(); }
85 scheduling_group set_scheduling_group(scheduling_group sg)
noexcept {
86 return std::exchange(this->_sg, sg);
92class coroutine_traits_base<> {
97 promise_type() =
default;
98 promise_type(promise_type&&) =
delete;
99 promise_type(
const promise_type&) =
delete;
101 void return_void() noexcept {
105 void set_exception(std::exception_ptr&& eptr)
noexcept {
106 _promise.set_exception(std::move(eptr));
109 void unhandled_exception() noexcept {
110 _promise.set_exception(std::current_exception());
114 return _promise.get_future();
117 std::suspend_never initial_suspend() noexcept {
return { }; }
118 std::suspend_never final_suspend() noexcept {
return { }; }
120 virtual void run_and_dispose() noexcept
override {
121 auto handle = std::coroutine_handle<promise_type>::from_promise(*
this);
125 task*
waiting_task() noexcept
override {
return _promise.waiting_task(); }
127 scheduling_group set_scheduling_group(scheduling_group new_sg)
noexcept {
128 return task::set_scheduling_group(new_sg);
133template<
bool CheckPreempt,
typename T>
139 awaiter(
const awaiter&) =
delete;
140 awaiter(awaiter&&) =
delete;
142 bool await_ready() const noexcept {
143 return _future.
available() && (!CheckPreempt || !need_preempt());
147 void await_suspend(std::coroutine_handle<U> hndl)
noexcept {
148 if (!CheckPreempt || !_future.available()) {
149 _future.set_coroutine(hndl.promise());
151 schedule(&hndl.promise());
155 T await_resume() {
return _future.get(); }
158template<
bool CheckPreempt>
159struct awaiter<CheckPreempt, void> {
164 awaiter(
const awaiter&) =
delete;
165 awaiter(awaiter&&) =
delete;
167 bool await_ready() const noexcept {
168 return _future.
available() && (!CheckPreempt || !need_preempt());
172 void await_suspend(std::coroutine_handle<U> hndl)
noexcept {
173 if (!CheckPreempt || !_future.available()) {
174 _future.set_coroutine(hndl.promise());
176 schedule(&hndl.promise());
180 void await_resume() { _future.get(); }
185SEASTAR_MODULE_EXPORT_BEGIN
188auto operator co_await(future<T> f)
noexcept {
189 return internal::awaiter<true, T>(std::move(f));
222template <
typename Func>
228 explicit lambda(Func&& func) : _func(&func) {}
230 template <
typename... Args>
231 decltype(
auto)
operator()(Args&&... args)
const {
232 return std::invoke(*_func, std::forward<Args>(args)...);
243 return internal::awaiter<false, T>(std::move(f));
246SEASTAR_MODULE_EXPORT_END
254template<
typename T,
typename... Args>
255class coroutine_traits<
seastar::future<T>, Args...> :
public seastar::internal::coroutine_traits_base<T> {
Definition: coroutine.hh:223
lambda(Func &&func)
Definition: coroutine.hh:228
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
bool available() const noexcept
Checks whether the future is available.
Definition: future.hh:1394
promise - allows a future value to be made available at a later time.
Definition: future.hh:934
void set_value(A &&... a) noexcept
Sets the promises value.
Definition: future.hh:990
virtual task * waiting_task() noexcept=0
Returns the next task which is waiting for this task to complete execution, or nullptr.
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: coroutine.hh:198