Created
November 26, 2023 16:28
-
-
Save CoffeeVampir3/1a8fba236c5c238dbfe7141190db8485 to your computer and use it in GitHub Desktop.
Coroutine Issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <coroutine> | |
#include <iostream> | |
#include <utility> | |
#include <vector> | |
#include <list> | |
struct Task { | |
struct promise_type; | |
using TaskHandle = std::coroutine_handle<promise_type>; | |
struct promise_type { | |
void unhandled_exception() noexcept {} | |
Task get_return_object() { return Task{this}; } | |
std::suspend_always initial_suspend() noexcept { return {}; } | |
std::suspend_always final_suspend() noexcept { return {}; } | |
void return_void() const noexcept {} | |
}; | |
TaskHandle Handle; | |
explicit Task(promise_type* Promise) : Handle{TaskHandle::from_promise(*Promise)} {} | |
Task(Task&& Rhs) noexcept : Handle{std::exchange(Rhs.Handle, nullptr)} {} | |
~Task() noexcept { | |
if(Handle) { Handle.destroy(); } | |
} | |
}; | |
auto AwaitTaskCompletion(std::coroutine_handle<> TaskToAwait) { | |
struct Awaitable { | |
std::coroutine_handle<> TaskToAwait; | |
std::coroutine_handle<> TaskToResume; | |
bool await_ready() { return false; } | |
auto await_suspend(std::coroutine_handle<> CallingCoro) { | |
TaskToResume = CallingCoro; | |
while(!TaskToAwait.done()) TaskToAwait.resume(); | |
return true; | |
} | |
bool await_resume() { | |
return false; | |
} | |
}; | |
return Awaitable{TaskToAwait}; | |
} | |
Task TaskB() { | |
std::cout << "Task B1\n"; | |
co_await std::suspend_always{}; | |
std::cout << "Task B2\n"; | |
co_await std::suspend_always{}; | |
std::cout << "Task B3\n"; | |
co_await std::suspend_always{}; | |
std::cout << "Task B4\n"; | |
} | |
Task TaskA() { | |
std::cout << "Task A1\n"; | |
auto B = TaskB(); | |
co_await AwaitTaskCompletion(B.Handle); | |
std::cout << "Task A2\n"; | |
co_await std::suspend_always{}; | |
std::cout << "Task A3\n"; | |
} | |
int main() { | |
auto A = TaskA(); | |
while(!A.Handle.done()) A.Handle.resume(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment