Skip to content

Feature request: Ability to return a value from aco_yield() #47

Description

@mrakh

Thanks for this great library!

I think that having something similar to the following functions:

void* aco_yield_value();
void aco_resume_value(aco_t* aco, void* val);

would be very convenient. I see two practical use cases for this feature: It allows us to create constructs similar to Python's generators, where the coroutine iterates over some data structure or computed sequence, and incrementally returns values from it. It also makes it easier to use libaco with event-based frameworks like io_uring, where events have a return value that need to be passed back to the coroutine:

// Inside coroutine...
struct io_uring_sqe* sqe;
int amt_read;
char buf[1024];
int fd;
// ...
sqe = io_uring_get_sqe(ring);
io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0);
io_uring_sqe_set_data(sqe, aco_get_co());
io_uring_submit(ring);
amt_read = (int) (intptr_t) aco_yield_value();
// ...

// Inside event loop...
struct io_uring_cqe* cqe;
aco_t* coro;
int result_val;
// ...
io_uring_wait_cqe(ring, &cqe);
coro = io_uring_cqe_get_data(cqe);
result_val = cqe->res;
io_uring_cqe_seen(ring, cqe);
aco_resume_value(coro, (void*) (intptr_t) result_val);

As I understand it, adding a return value would require saving/restoring an additional register. Perhaps this feature could be put behind a #define macro, so that users can choose if they want to take a slight performance hit for this feature.

Right now, this feature can be emulated by using an externally maintained pointer to marshal the data. But this is a very janky design pattern, and I believe that it is best to avoid polluting a codebase with pointers if the necessary data can simply be passed by value.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions