I have been trying to implement a cooperative job scheduler using C++ co-routines. This involves putting co-routines into an array. However I get the error Object of type 'Job' cannot be assigned because its copy assignment operator is implicitly deleted
when I try to do this. I do not completely understand the bellow code, but I am under the impression I can't just make Job moveable/copyable.
Job.h
#include <experimental/coroutine>
#include <cstddef>
class Job {
public:
struct promise_type;
using coro_handle = std::experimental::coroutine_handle<promise_type>;
Job() { handle_ = NULL; } // default value to create arrays
Job(coro_handle handle) : handle_(handle) { assert(handle); }
Job(Job&) = delete;
Job(Job&&) = delete;
bool resume() {
if (not handle_.done())
handle_.resume();
return handle_.done();
}
~Job() { handle_.destroy(); }
private:
coro_handle handle_;
};
struct Job::promise_type {
using coro_handle = std::experimental::coroutine_handle<promise_type>;
auto get_return_object() {
return coro_handle::from_promise(*this);
}
auto initial_suspend() { return std::experimental::suspend_always(); }
auto final_suspend() { return std::experimental::suspend_always(); }
void return_void() {}
void unhandled_exception() {
std::terminate();
}
};
Main.cpp
#include "Job.h"
Job testCoro() {
co_return;
} // Empty coro
void main() {
Job jobList[2048];
jobList[0] = testCoro(); // Call coro and insert it into the list of jobs, error on this line
}
Source: https://blog.panicsoftware.com/your-first-coroutine/
I have tried the following:
- Passing around a pointer to the Job, but it runs into object lifetime issues, since if it is created on the stack in the function and the function exits, a dangling pointer is left behind
- Ignoring the non-move-ability and forcing it, causes spurious errors and invokes UB
- C++ container with non-copyable non-movable element type, but I can't create a placement new operator, due to co-routines semantics
EDIT 1: Added co_return