47 using Handle = std::coroutine_handle<TaskPromise<T>>;
71 bool await_ready()
noexcept {
return false; }
78 std::coroutine_handle<> await_suspend(std::coroutine_handle<
TaskPromise<T>> h)
noexcept {
79 std::lock_guard<std::mutex> lock(promise->mContinuationMutex);
82 for (
auto& continuation : promise->mContinuations) {
83 continuation.resume();
85 promise->mContinuations.clear();
87 return std::noop_coroutine();
90 void await_resume()
noexcept {}
93 return FinalAwaiter{
this};
101 mResult = std::move(value);
102 mResultReady.store(
true, std::memory_order_release);
109 mException = std::current_exception();
110 mResultReady.store(
true, std::memory_order_release);
121 std::rethrow_exception(mException);
123 if (mResult.has_value()) {
124 return mResult.value();
126 throw std::runtime_error(
"Task not completed");
134 return mResultReady.load(std::memory_order_acquire);
145 std::lock_guard<std::mutex> lock(mContinuationMutex);
148 if (mResultReady.load(std::memory_order_acquire)) {
149 continuation.resume();
151 mContinuations.push_back(continuation);
156 std::optional<T> mResult;
157 std::exception_ptr mException;
158 std::atomic<bool> mResultReady{
false};
160 std::mutex mContinuationMutex;
161 std::vector<std::coroutine_handle<>> mContinuations;
174 using Handle = std::coroutine_handle<TaskPromise<void>>;
195 struct FinalAwaiter {
198 bool await_ready()
noexcept {
return false; }
200 std::coroutine_handle<> await_suspend(std::coroutine_handle<
TaskPromise<void>> h)
noexcept {
201 std::lock_guard<std::mutex> lock(promise->mContinuationMutex);
203 for (
auto& continuation : promise->mContinuations) {
204 continuation.resume();
206 promise->mContinuations.clear();
208 return std::noop_coroutine();
211 void await_resume()
noexcept {}
214 return FinalAwaiter{
this};
221 mResultReady.store(
true, std::memory_order_release);
228 mException = std::current_exception();
229 mResultReady.store(
true, std::memory_order_release);
238 std::rethrow_exception(mException);
247 return mResultReady.load(std::memory_order_acquire);
255 std::lock_guard<std::mutex> lock(mContinuationMutex);
257 if (mResultReady.load(std::memory_order_acquire)) {
258 continuation.resume();
260 mContinuations.push_back(continuation);
265 std::exception_ptr mException;
266 std::atomic<bool> mResultReady{
false};
267 std::mutex mContinuationMutex;
268 std::vector<std::coroutine_handle<>> mContinuations;
331 Task(
Task&& other) noexcept : mHandle(std::exchange(other.mHandle, {})) {}
339 if (
this != &other) {
343 mHandle = std::exchange(other.mHandle, {});
355 if (mHandle && !mHandle.done()) {
365 return mHandle && mHandle.done();
378 throw std::runtime_error(
"Invalid task handle");
381 if (!mHandle.promise().isReady()) {
382 throw std::runtime_error(
"Task not completed - use co_await or check done() first");
385 return mHandle.promise().getResult();
395 throw std::runtime_error(
"Invalid task handle");
398 if (!mHandle.promise().isReady()) {
399 throw std::runtime_error(
"Task not completed - use co_await or check done() first");
402 mHandle.promise().getResult();
428 mHandle.promise().addContinuation(waiter);
431 if (!mHandle.done()) {
458 return mHandle && mHandle.promise().isReady();
468 return Task<T>{Handle::from_promise(*
this)};
472 return Task<void>{Handle::from_promise(*
this)};
std::suspend_always initial_suspend() noexcept
Initial suspend behavior - always suspend to allow manual start.
void unhandled_exception()
Handle unhandled exceptions in the coroutine.
bool isReady() const noexcept
Check if the task has completed.
void addContinuation(std::coroutine_handle<> continuation)
Add a continuation to be resumed when task completes.
void getResult()
Check for exceptions (void tasks have no return value)
auto final_suspend() noexcept
Final suspend behavior with continuation chaining.
std::coroutine_handle< TaskPromise< void > > Handle
void return_void()
Handle void return from coroutine.
Promise type for coroutine-based Task implementation.
auto final_suspend() noexcept
Final suspend behavior with continuation chaining.
T getResult()
Get the stored result value.
void unhandled_exception()
Handle unhandled exceptions in the coroutine.
void addContinuation(std::coroutine_handle<> continuation)
Add a continuation to be resumed when task completes.
bool isReady() const noexcept
Check if the task has completed.
std::suspend_always initial_suspend() noexcept
Initial suspend behavior - always suspend to allow manual start.
void return_value(T value)
Store the coroutine return value.
Task< T > get_return_object()
Create the Task object for this promise.
std::coroutine_handle< TaskPromise< T > > Handle
RAII wrapper for coroutines with proper continuation chaining.
Task(Task &&other) noexcept
Move constructor.
auto getResult() -> T
Get the result value (non-blocking)
Task(Handle handle)
Construct task with coroutine handle.
Task & operator=(const Task &)=delete
void await_resume()
Complete co_await for void tasks.
void getResult()
Get the result for void tasks (non-blocking)
~Task()
Destructor - automatically destroys coroutine handle.
Task(const Task &)=delete
bool await_ready() const noexcept
Check if task is ready (awaitable interface)
bool isReady() const noexcept
Check if task is ready without blocking.
bool done() const noexcept
Check if the task has completed.
typename promise_type::Handle Handle
Task & operator=(Task &&other) noexcept
Move assignment operator.
auto await_resume() -> T
Get result when co_await completes (non-void version)
void await_suspend(std::coroutine_handle<> waiter) noexcept
Suspend awaiting coroutine until this task completes.
void start()
Start the coroutine execution.
Software Timer namespace containing all timer-related classes.