-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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 void ffi callbacks API #51350
Comments
I really prefer the last option, but we can't just break the API I'm afraid. The best we can do is to deprecate fromFunction and introduce a new one: class CallbackSemantics {
CallbackSemantics._();
/// documentation
static const CallbackSemantics alreadyEnteredCorrectIsolate = ...;
/// documentation
static const CallbackSemantics asyncVoid = ...;
}
external static Pointer<NativeFunction<T>> fromFunctionV2<T extends Function>(
@DartRepresentationOf('T') Function f,
{Object? exceptionalReturn,
CallbackSemantics kind = CallbackSemantics.alreadyEnteredCorrectIsolate});
Please note we can't use an |
Maybe from |
Edit: I should have read the documentation of I'd consider creating a separate function: external static Pointer<NativeFunction<T>> fromAsyncFunction<T extends Function>> {
@DartRepresentationOf('T') Function f, // Must have a `Future<R>` return type.
{Object? exceptionalReturn}); Making this a separate function makes it easier to diverge the APIs in the future, if necessary, This is different from the type checking on Mode flags on functions that fundamentally change what the function does, is a design pitfall. If instead you have two different functions, they can have different parameters, different type constraints, and none of them have to be the default. Making |
That's a good question, will the APIs ever diverge? If they don't diverge, having two identical parameter-lists is suboptimal. If they do diverge, only being able to throw I can't come up with an idea why they would diverge just yet.
Fundamentally it will always turn a Dart function into an address that a C function can call. Thoughts @liamappelbe @mkustermann @mraleph ?
It is async in the sense that an arbitrary thread that doesn't respect (or know of) the Dart isolate's event loop can call it at an arbitrary point in time. Maybe "async" isn't the right term to use. A try for better naming: class CallbackSemantics {
CallbackSemantics._();
/// The calling thread must have already entered the correct isolate.
///
/// By entering the Dart isolate in which this callback lives, the caller
/// guarantees that no Dart code is currently executing.
///
/// FFI callbacks with [runImmediately] semantics run synchronously and can return a value.
static const CallbackSemantics runImmediately = ...;
/// An FFI callback with [scheduleEvent] semantics can be invoked from any thread.
///
/// FFI callbacks with [scheduleEvent] semantics are scheduled on the event loop.
///
/// FFI callbacks with [scheduleEvent] semantics do _not_ deep copy their native arguments.
/// The caller must only pass arguments by value, or pass ownership of memory referenced by [Pointer]s to the callee.
///
/// FFI callbacks with [scheduleEvent] can only return `void` or `Future`s (which are exposed as `Dart_Handle`s).
/// Callers with functions returning a `Future` in a `Dart_Handle` must have a handle scope.
static const CallbackSemantics scheduleEvent = ...;
/// Blocks the thread until the Dart code in the target isolate has yielded to the event loop.
///
/// **Warning: using this can create deadlocks.**
static const CallbackSemantics waitToEnter = ...;
}
@liamappelbe should we consider supporting functions that return a |
That would be cool to have, but we should wait for a use case. Lasse has convinced me that we should just add a separate function for this. Let's go with |
The |
Settled on |
We're adding a variant of
Pointer.fromFunction
that can be used for async void functions (by dispatching a message to the target isolate). We might also add more variants in future.We could add an enum, as an optional parameter to
Pointer.fromFunction
that controls the variant.This is nice because we can document all the different kinds of callback on this enum. The downside is that asyncVoid functions will always pass null as the
exceptionalReturn
, so until we add more variants, if you want to pass a non-default value to the third param you have to pass null to the second.Another option is to add a new method for each variant:
A final option is to do a breaking change to switch
Pointer.fromFunction
to use named optional args.@dcharkes @lrhn any opinions?
The text was updated successfully, but these errors were encountered: