Недавно я узнал о сопрограммах и был воодушевлен тем, что поддерживаю несколько асинхронных библиотек, для которых требуется поддержка сопрограмм, по крайней мере, для базовой библиотеки — планировщика задач —.
планировщик задач выполняет голые функции: нет параметров, нет возвращаемого значения, и я хочу оставить все как есть, поддерживая сопрограмму для co_await в первую очередь для периодов.
Поэтому я пошел иметь Promise_type::get_return_object() для возврата void, так как нет намерения заставлять приложение/пользователя переключать такие задачи на другую сигнатуру функции и избегать двойного управления задачами.
Первоначально я реализовал это, но ошибка компиляции не позволила мне продолжить: ошибка: невозможно найти тип обещания для этой сопрограммы.
Ниже приведена основная реализация сопрограмма, и вот ссылка на выполнение: https://godbolt.org/z/4hWce9n6P
Я неправильно понимаю сопрограммы? Что предлагается сделать?
Спасибо.
class H4Delay {
uint32_t duration;
task* owner;
task* resumer=nullptr;
public:
class promise_type {
task* owner=nullptr;
friend class H4Delay;
public:
void get_return_object() noexcept {}
std::suspend_never initial_suspend() noexcept { return {}; }
void return_void() noexcept {}
void unhandled_exception() noexcept { std::terminate(); }
struct final_awaiter {
bool await_ready() noexcept { return false; }
void await_suspend(std::coroutine_handle h) noexcept {
auto owner = h.promise().owner;
if (owner) owner->_destruct();
task::suspendedTasks.erase(owner);
// [ ] IF NOT IMMEDIATEREQUEUE: MANAGE REQUEUE AND CHAIN CALLS.
}
void await_resume() noexcept {}
};
final_awaiter final_suspend() noexcept { return {}; }
};
std::coroutine_handle _coro;
H4Delay(uint32_t duration, task* caller=H4::context) : duration(duration), owner(caller) {}
~H4Delay() {
if (_coro) _coro.destroy();
}
bool await_ready() noexcept { return false; }
void await_suspend(std::coroutine_handle h) noexcept {
// Schedule the resumer.
resumer = h4.once(duration, [h]{ h.resume(); });
_coro = h;
_coro.promise().owner = owner;
task::suspendedTasks[owner] = this;
}
void await_resume() noexcept { resumer = nullptr; }
void cancel() { ... }
};
Подробнее здесь: https://stackoverflow.com/questions/792 ... omise-type