Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Borrowed inputs to tasks #3

Open
osa1 opened this issue May 15, 2022 · 2 comments
Open

Borrowed inputs to tasks #3

osa1 opened this issue May 15, 2022 · 2 comments

Comments

@osa1
Copy link

osa1 commented May 15, 2022

I'm trying to store my coroutine in a heap-allocated struct (or just heap-allocate the coroutine) and pass borrowed inputs to it in run_until_stall.

As far as I understand, this is not possible with the current API. The problem is the type parameter of Cosync. If my input has borrowed bits, I need a type parameter like:

struct MyInput<'a> {
    borrowed_bit: &'a MyBorrowedData,
    other_stuff: OtherStuff,
}

That type parameter that propogates into all the references to Cosync:

type MyCoro<'a> = Cosync<MyInput<'a>>;

which means I can't heap-allocate MyCoro: 'static is the only lifetime I can pass to MyCoro, but that's the not lifetime as I will be passing stack-allocated borrowed values to run_until_stall.

I'm not sure how to best solve this problem in Rust. I'm wondering if you know a workaround. To solve this at the API level we would need to somehow avoid the type parameter for the coroutine input in the Cosync type. However if we do that then I don't know how to implement the run_until_stall method as it needs to know the coroutine input type.

Any thoughts on this?


The actual use case: In an app (not a game) I have an event source. Whenever an event arrives my callback is called with & and &mut, and value arguments (passed by the event loop to my callback). This callback is practically a coroutine: it takes an input (event data), it may run an action (or yield a value), or wait for more input. cosyn makes it much simpler to implement than an hand-written coroutine as I need to implement a lot of states manually.

The problem is the callback needs to be heap allocated and passed to the event loop and I don't have control over the event loop code to change this.

@sanbox-irl
Copy link
Owner

Unfortunately, it's not just that it's not possible in the current api, it's actually an issue in Rust itself.

On a fundamental issue, Cosync should never have a lifetime on it, even if its input has a lifetime on it, in a similar way that:

struct Foo<T: Fn(&mut ())>(T);

is valid rust, and yet internally defers the lifetime of the parameter to the call site. My understanding based on the nomicon here https://doc.rust-lang.org/nomicon/hrtb.html is that the HRTB is magically placed by the compiler.

However, unlike the other examples, Cosync only knows of a T, which might be ?'static. As far as I can tell, it isn't possible to reason about the T that way. I tried for a significant amount of time here on this branch: https://github.com/sanbox-irl/cosync/commits/testing. Unfortunately, I suspect this is one of those things that HRTs will help with, though I'm less a type guy and more a hammer my head against the types till it works guy, so I'm not sure what'll happen there.


Okay, onto your use case itself. Is it possible for you to pass OtherStuff into the stack of the coroutine on creation, rather than as a parameter? It would probably rely on OtherStuff being an Arc<RwLock<T>> kind of thing (or just an Arc), and then only use MyBorrowedData as the parameter.

What do you think?

@osa1
Copy link
Author

osa1 commented May 21, 2022

Okay, onto your use case itself. Is it possible for you to pass OtherStuff into the stack of the coroutine on creation, rather than as a parameter? It would probably rely on OtherStuff being an Arc<RwLock> kind of thing (or just an Arc), and then only use MyBorrowedData as the parameter.

What do you think?

I think this would work when I have one borrowed input, but not when I have two (as in my actual use case). When I have two I need to pack them in a struct, and the struct requires lifetime parameters as it has borrowed data. So it cannot be used as CosyncInput type argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants