Description
Currently we have
https://api.dart.dev/stable/3.2.4/dart-ffi/NativeCallable/NativeCallable.listener.html enables async callbacks that return immediately upon calling and schedule the callback to be run on the Dart event loop of the right isolate. No return values can be returned.
However, it is often the case that a native callback expects to be synchronous in that the parameters parsed are really stack allocated values, yet we still need to ensure the callback is ferried to the correct isolate event loop on the dart side.
So I suggest to add the option to block the callback on the native side until completed in the correct isolate on the dart side. It is okay for my use-case to still restrict to functions returning Void.
Would it be possible to implement such behaviour? I envision something like:
final completer = Completer<void>();
late final NativeCallable<Void Function(Pointer<native_error> error)> callback;
void done(Pointer<native_error> error) {
try {
if (error != nullptr) return completer.completeWithError(error.asDart);
completer.complete();
} finally {
// Block native side until here, if callback was constructed with
// listener(done, sync: true).
// Use a separate from close to also support streaming.
callback.releaseCaller();
callback.close();
}
}
callback = NativeCallable<Void Function(Pointer<native_error> error)>.listener(done, sync: true);
return completer.future;
Currently, if native_error
is really an address of a stack allocated native object, this would fail.