-
Notifications
You must be signed in to change notification settings - Fork 45
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
support
#279
Comments
Would probably also be good to look at what is actually required on the runtime-side of this? Do we need to do stuff with |
Instead of |
There is actually a way to make
So if we can register the global GCD Mach port into a |
Interesting to know, thanks! I don't think I would have that much against using unstable APIs like |
Related Kotlin issue about their unfinished async support: https://youtrack.jetbrains.com/issue/KT-47610 |
A necessary prerequisite is #168, since we need some way to tell that the completion handlers will only be run once. |
To take the example from the linked Swift proposal: - (void)fetchShareParticipantWithUserRecordID:(CKRecordID *)userRecordID
completionHandler:(void (^)(CKShareParticipant * _Nullable, NSError * _Nullable))completionHandler; And what that would (ideally) be in Rust, pre-async translation: fn method_name_bikeshed(
&self,
userRecordID: &CKRecordID,
completionHandler: BlockOnceSendSync<(Option<&CKShareParticipant>, Option<&NSError>), ()>,
); It would probably be prudent to first convert the Objective-C style error into the usual Rust error: fn method_name_bikeshed(
&self,
userRecordID: &CKRecordID,
completionHandler: BlockOnceSendSync<(Result<&CKShareParticipant, &NSError>,), ()>,
); Note that this has a different ABI, but I might be able to handle such things directly in Now, we could subsequently convert it to: fn method_name_bikeshed(
&self,
userRecordID: &CKRecordID,
) -> BikeshedHelper<Result<&CKShareParticipant, &NSError>, impl FnOnce(...)>;
struct BikeshedHelper<T, F: FnOnce(BlockOnceSendSync<(T,), ()>)> { ... }
impl BikeshedHelper<T, F> {
pub fn run_with_block(self, block: BlockOnceSendSync<(T,), ()>) { ... }
}
impl IntoFuture for BikeshedHelper<T, F> {
type Output = T; // TODO: Convert &MyClass to Id<MyClass> here
type Future = BlockFuture<T>;
}
struct BlockFuture<T> { ... } Immediately we see a few issues:
|
Note: I think it makes sense to make separate adapters depending on whether the block can receive an error or not (one parameter is And we also need to distinguish between blocks with one parameter vs. multiple parameters (the former should be a simple output, while the latter should return a tuple). |
Linking clang's |
An alternative solution for integrating with the rest of the Though it doesn't seem like (I can tell I'm wayy too inexperienced with the |
However it wouldn't be too difficult to expose, say, The issue is that we hit the limits of what can be registered into The current available |
Spent some time on this today, from my understanding there's effectively two things that need to be done:
I still only have a vague notion on how to progress on the second item, but I think the first one is tractable. Effectively, we need a wrapper type that implements Basic usage of such a wrapper, to illustrate the idea: let continuation = Continuation::new();
let completion_handler = block2::RcBlock::new(|x, y, z| {
continuation.resume((x, y, z));
});
my_obj.my_method(my_arg, &completion_handler);
continuation.await Swift calls this a "continuation", and @drewcrawford has recently extracted the implementation from I suspect I'll still want a helper wrapper in
But for the delegate callback case I'll probably document |
Objective-C uses "completion handlers" for concurrency.
Swift automatically translates these to
async
functions, we could consider doing something similar after #264.Also would be a good step forwards for
async
inwinit
.See also
blockr
'sasync
support, andcidre
'sasync
support.See also this blog post on how Zed uses
async
and GCD.The text was updated successfully, but these errors were encountered: