-
Notifications
You must be signed in to change notification settings - Fork 232
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
Handles #1823
base: main
Are you sure you want to change the base?
Handles #1823
Conversation
9c5ad98
to
56300c3
Compare
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.
Apologies this fell through my review queue, I'll redirect to @mhammond as he's been more recently involved and I'd most likely not provide the best review without playing catchup
/// leaked pointer will be aligned). | ||
/// | ||
/// Foreign handles for internal bindings languages look like this: | ||
/// * Bits 0-48 are the map key. Keys are always odd, so the lowest bit is always set. |
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.
Nice one, I was thinking it would be MSB to check range [0; u64::max/2)
, but checking LSB seems less error prone. Also LSB is friendly with map identifier bits.
6a7ea36
to
00d58c2
Compare
bc5e827
to
3de393c
Compare
`Handle` is a u64 newtype that I hope to use to represent objects that get passed across the FFI. `HandleAlloc` is an ffi trait that converts between `Arc<>` and `Handle`.
Consolidated the various handle maps into a single implementation for each language. This handle map works basically the same as all the others, but it's API is based on the `HandleAlloc` trait. Handles have a couple properties: * All foreign handles are odd, which allows us to distinguish between Rust and foreign handles. * For handles store a map ID that can detect when a handle is used with the wrong map. Made all languages always use the handle maps for passing objects. No more trying to leak pointers from to foreign objects. Started updating the ForeignExecutor code to use handles, but this is still a WIP while the ForeignExecutor type is in it's limbo state.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
I'm trying to get mozilla#1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemneted to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
I'm trying to get mozilla#1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign now languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemneted to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
I'm trying to get mozilla#1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign now languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemented to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
I'm trying to get mozilla#1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign now languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemented to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
I'm trying to get mozilla#1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign now languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemented to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
I'm trying to get mozilla#1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign now languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemented to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
I'm trying to get #1823 merged now that 0.26.0 is out, but I'll break it up a bit to make it easier. The first step is consolidating the foreign handle map code. Foreign now languages define 1 handle map and use it for all object types. I tried to simplify the handle map implementations, the had a lot of features that we weren't using at all and seemed to be only half-implemented to me, like the right map and counter map. Handles are always `u64` values. This allows us to remove some code like the `USize` handling on Kotlin and the `FfiType::RustFutureContinuationData` variant.
FfiType::Handle is a opaque 64-bit handle that's used to pass objects across the FFI. This PR changes the rustfuture code to use it and also renames the type used to represent callback interfaces from `u64` to handle. The plan is to use it for all object types, including interfaces and trait interfaces, but do that in future PRs. Accompianing that code is the `HandleAlloc` trait, which has a general system for allocating/using/freeing handles for objects. It's essentially the same system(s) we're currently using, but now the code is all in one place. On the bindings side, switched the code to using the `u64` type rather than having a `UniffiHandle` type alias. I don't think the type alias is very useful since handles are only used internally. Also, I remember running into Switch issues with the type alias and multiple crates. Most of this code was copied from the handles PR (mozilla#1823).
FfiType::Handle is a opaque 64-bit handle that's used to pass objects across the FFI. This PR changes the rustfuture code to use it and also renames the type used to represent callback interfaces from `u64` to handle. The plan is to use it for all object types, including interfaces and trait interfaces, but do that in future PRs. Accompianing that code is the `HandleAlloc` trait, which has a general system for allocating/using/freeing handles for objects. It's essentially the same system(s) we're currently using, but now the code is all in one place. On the bindings side, switched the code to using the `u64` type rather than having a `UniffiHandle` type alias. I don't think the type alias is very useful since handles are only used internally. Also, I remember running into Switch issues with the type alias and multiple crates. Most of this code was copied from the handles PR (mozilla#1823).
FfiType::Handle is a opaque 64-bit handle that's used to pass objects across the FFI. This PR changes the rustfuture code to use it and also renames the type used to represent callback interfaces from `u64` to handle. The plan is to use it for all object types, including interfaces and trait interfaces, but that will be done in future PRs. Accompianing that code is the `HandleAlloc` trait, which has a general system for allocating/using/freeing handles for objects. It's essentially the same system(s) we're currently using, but now the code is all in one place. On the bindings side, switched the code to using the `u64` type rather than having a `UniffiHandle` type alias. I don't think the type alias is very useful since handles are only used internally. Also, I remember running into Switch issues with the type alias and multiple crates. Most of this code was copied from the handles PR (mozilla#1823).
FfiType::Handle is a opaque 64-bit handle that's used to pass objects across the FFI. This PR changes the rustfuture code to use it and also renames the type used to represent callback interfaces from `u64` to handle. The plan is to use it for all object types, including interfaces and trait interfaces, but that will be done in future PRs. Accompianing that code is the `HandleAlloc` trait, which has a general system for allocating/using/freeing handles for objects. It's essentially the same system(s) we're currently using, but now the code is all in one place. On the bindings side, switched the code to using the `u64` type rather than having a `UniffiHandle` type alias. I don't think the type alias is very useful since handles are only used internally. Also, I remember running into Swift issues with the type alias and multiple crates. Most of this code was copied from the handles PR (mozilla#1823).
FfiType::Handle is a opaque 64-bit handle that's used to pass objects across the FFI. This PR changes the rustfuture code to use it and also renames the type used to represent callback interfaces from `u64` to handle. The plan is to use it for all object types, including interfaces and trait interfaces, but that will be done in future PRs. Accompianing that code is the `HandleAlloc` trait, which has a general system for allocating/using/freeing handles for objects. It's essentially the same system(s) we're currently using, but now the code is all in one place. On the bindings side, switched the code to using the `u64` type rather than having a `UniffiHandle` type alias. I don't think the type alias is very useful since handles are only used internally. Also, I remember running into Swift issues with the type alias and multiple crates. Most of this code was copied from the handles PR (mozilla#1823).
FfiType::Handle is a opaque 64-bit handle that's used to pass objects across the FFI. This PR changes the rustfuture code to use it and also renames the type used to represent callback interfaces from `u64` to handle. The plan is to use it for all object types, including interfaces and trait interfaces, but that will be done in future PRs. Accompianing that code is the `HandleAlloc` trait, which has a general system for allocating/using/freeing handles for objects. It's essentially the same system(s) we're currently using, but now the code is all in one place. On the bindings side, switched the code to using the `u64` type rather than having a `UniffiHandle` type alias. I don't think the type alias is very useful since handles are only used internally. Also, I remember running into Swift issues with the type alias and multiple crates. Most of this code was copied from the handles PR (#1823).
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
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 some of the foreign code so that the handle-maps used for callback interfaces can also be used for this. It's quite messy right now, but mozilla#1823 should clean things up. Renamed `Handle` to `UniffiHandle` on Kotlin, since `Handle` can easily conflict with user names. In fact it did on the `custom_types` fixture, the only reason that this worked before was that that fixture didn't use callback interfaces. Added new tests for this in the futures fixtures. Updated the tests to check that handles are being released properly.
This PR contains the parts of #1808 that I think are most beneficial and least controversial:
FfiType
variant for all handles. Implement one systemin Rust and one system in each foreign language rather than multiple systems. This makes it
easier to add new object/handle types.
This PR sets things up to fix #1797, but doesn't actually fix it. That's going to take some more code and I want to do that in a separate PR.
It also doesn't implement the trait interface changes, because when I did that I hit #1797. In the traits example, we pass a trait interface into Rust, then Rust immediately returns it. This is what happens Rust returns it:
lower()
IDX_CALLBACK_FREE
method.