Skip to content

Instantly share code, notes, and snippets.

@CoffeeVampir3
Created November 26, 2023 16:28
Show Gist options
  • Save CoffeeVampir3/1a8fba236c5c238dbfe7141190db8485 to your computer and use it in GitHub Desktop.
Save CoffeeVampir3/1a8fba236c5c238dbfe7141190db8485 to your computer and use it in GitHub Desktop.
Coroutine Issue
#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