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

[ffigen] Support blocking callbacks #1647

Open
liamappelbe opened this issue Oct 11, 2024 · 4 comments
Open

[ffigen] Support blocking callbacks #1647

liamappelbe opened this issue Oct 11, 2024 · 4 comments

Comments

@liamappelbe
Copy link
Contributor

Turns out there are a few Apple APIs that require that the completion handler is invoked during the callback. So we should add a variant of listener blocks and protocol methods that uses a mutex to block until the listener callback is complete.

  • We'll need a native trampoline similar to the ref counting trampoline that listeners get, but instead of incrementing the ref count it will lock the mutex.
  • If the callback is invoked on the same thread as the isolate that owns the listener, it will deadlock. So we should detect this case and invoke the callback synchronously (ie NativeCallable.isolateLocal style).
  • If the isolate has shut down before the callback is invoked, the caller thread will wait forever. So add a timeout that throws an assertion failure if the callback doesn't run in N seconds. This error won't have a ton of context, but it's better than silently deadlocking (or more realistically, having some background thread that's sitting there doing nothing).

With a little more infrastructure, it would also be possible to support callbacks that return results, but these are even rarer in Apple APIs, so we'll wait until we have a use case for this.

@johnmccutchan
Copy link

@liamappelbe Can you point me at an example of this type of API?

@liamappelbe
Copy link
Contributor Author

liamappelbe commented Oct 11, 2024

The one Brian ran into in cupertino_http was URLSession:downloadTask:didFinishDownloadingToURL:. It's called after a download to a temporary file is complete. The temporary file will be deleted after the callback returns. So if you want to do something with the file, your callback has to be blocking.

@brianquinlan What were the other examples you found that were using the completion handler pattern, but expect the completion handler to be called during the callback?

@stuartmorgan
Copy link

With a little more infrastructure, it would also be possible to support callbacks that return results, but these are even rarer in Apple APIs, so we'll wait until we have a use case for this.

We're auto-converting all delegate protocols to callbacks still, right? If so, this is not going to be rare. Having a delegate to provide data or synchronous decisions is fairly common pattern.

@brianquinlan
Copy link
Contributor

@brianquinlan What were the other examples you found that were using the completion handler pattern, but expect the completion handler to be called during the callback?

I didn't look very hard for examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

4 participants