-
Notifications
You must be signed in to change notification settings - Fork 231
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
Async blocking task queue #1837
base: main
Are you sure you want to change the base?
Conversation
/// We start with an assumption: if we notify the waker then this future will be polled when the | ||
/// top-level task is polled next. If a future does not honor this then we consider it a broken | ||
/// future. This seems fair, since that future would almost certainly break a lot of other future | ||
/// code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure this is a good assumption, but I'd love a double check on this one.
When I mention "other future code", I was thinking of something like a lock. If your async lock type locks a mutex and notifies the waker, then any intermediate futures must poll your type or else you're in a bad state. Unless I'm missing something, async lock authors just have assume they will get polled and we can too.
62284b8
to
5cabada
Compare
2914ce2
to
5cabada
Compare
5cabada
to
6f3fa1d
Compare
On Rust, `BlockingTaskQueue` is a UniFFI type that can safely run blocking code. | ||
It's `execute` method works like tokio's [block_in_place](https://docs.rs/tokio/latest/tokio/task/fn.block_in_place.html) function. | ||
It inputs a closure and runs it in the `BlockingTaskQueue`. | ||
This closure can reference the outside scope (i.e. it does not need to be `'static`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what this method should be named. I chose execute
simply because I hadn't seen it used in other places so it didn't have the baggage of other names. I almost want to name in block_in_place
since it matches the semantics of the tokio method. But the "in_place" part feels weird since we don't have a spawn_blocking
method to contrast with.
/// | ||
/// WARNING: the call to [rust_future_poll] must be scheduled to happen soon after the callback is | ||
/// called, but not inside the callback itself. If [rust_future_poll] is called inside the | ||
/// callback, some futures will deadlock and our scheduler code might as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't really related to the PR, but it's something I noticed when trying to refactor some things.
Updated this code to not depend on the handles work, because I didn't want that to block this. This means the foreign handle-map code is a bit of a mess, but #1823 should clean that up. At the same time, I did make it depend on the ffi-vtables branch because that code was extremely useful for implementing |
28464e6
to
ff1f241
Compare
Removing myself from the review, will also remove myself from auto-assign - if I take more UniFFI work in the future I'll add myself back |
5432e27
to
0f39a50
Compare
26a9649
to
5a7ee85
Compare
Rebased this one now that the vtable code has been merged. It's looking pretty good now so I removed the |
5a7ee85
to
0435901
Compare
Removed this one from the list of PRs for |
Added the `BlockingTaskQueue` type BlockingTaskQueue allows a Rust closure to be scheduled on a foreign thread where blocking operations are okay. The closure runs inside the parent future, which is nice because it allows the closure to reference its outside scope. On the foreign side, a `BlockingTaskQueue` is a native type that runs a task in some sort of thread queue (`DispatchQueue`, `CoroutineContext`, `futures.Executor`, etc.). Updated handlemaps to always start at 1 rather than 0, which is reserved for a NULL handle. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
0435901
to
6931e33
Compare
Added the
BlockingTaskQueue
type BlockingTaskQueue allows a Rust closure to be scheduled on a foreign thread where blocking operations are okay. The closure runs inside the parent future, which is nice because it allows the closure to reference its outside scope.On the foreign side, a
BlockingTaskQueue
is a native type that runs a task in some sort of thread queue (DispatchQueue
,CoroutineContext
,futures.Executor
, etc.).Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.