mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
[flutter] Port: Run handle wait completers on the microtask queue (#11649)
Change-Id: I66c39d9ef7d534094148212940eef45754559d04
This commit is contained in:
@@ -39,3 +39,17 @@ class Handle extends NativeFieldWrapperClass2 {
|
||||
|
||||
Handle duplicate(int rights) native 'Handle_Duplicate';
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
class _OnWaitCompleteClosure { // ignore: unused_element
|
||||
// No public constructor - this can only be created from native code.
|
||||
@pragma('vm:entry-point')
|
||||
_OnWaitCompleteClosure(this._callback, this._arg1, this._arg2);
|
||||
|
||||
Function _callback;
|
||||
Object _arg1;
|
||||
Object _arg2;
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
Function get _closure => () => _callback(_arg1, _arg2); // ignore: unused_element
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "third_party/tonic/dart_binding_macros.h"
|
||||
#include "third_party/tonic/dart_library_natives.h"
|
||||
#include "third_party/tonic/dart_message_handler.h"
|
||||
#include "third_party/tonic/dart_microtask_queue.h"
|
||||
#include "third_party/tonic/logging/dart_invoke.h"
|
||||
|
||||
using tonic::DartInvokeField;
|
||||
@@ -81,11 +82,39 @@ void HandleWaiter::OnWaitComplete(async_dispatcher_t* dispatcher,
|
||||
// Remove this waiter from the handle.
|
||||
handle_->ReleaseWaiter(this);
|
||||
|
||||
// Schedule the callback on the microtask queue.
|
||||
handle_->ScheduleCallback(std::move(callback_), status, signal);
|
||||
|
||||
// Clear handle_.
|
||||
handle_ = nullptr;
|
||||
|
||||
auto state = callback_.dart_state().lock();
|
||||
FML_DCHECK(state);
|
||||
DartState::Scope scope(state);
|
||||
|
||||
// Put the closure invocation on the microtask queue.
|
||||
Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
|
||||
FML_DCHECK(!tonic::LogIfError(zircon_lib));
|
||||
|
||||
Dart_Handle owc_type =
|
||||
Dart_GetClass(zircon_lib, ToDart("_OnWaitCompleteClosure"));
|
||||
FML_DCHECK(!tonic::LogIfError(owc_type));
|
||||
|
||||
FML_DCHECK(!callback_.is_empty());
|
||||
std::vector<Dart_Handle> owc_args{callback_.Release(), ToDart(status),
|
||||
ToDart(signal->observed)};
|
||||
Dart_Handle owc =
|
||||
Dart_New(owc_type, Dart_Null(), owc_args.size(), owc_args.data());
|
||||
FML_DCHECK(!tonic::LogIfError(owc));
|
||||
|
||||
Dart_Handle closure = Dart_GetField(owc, ToDart("_closure"));
|
||||
FML_DCHECK(!tonic::LogIfError(closure));
|
||||
|
||||
// TODO(issue#tbd): Use tonic::DartMicrotaskQueue::ScheduleMicrotask()
|
||||
// instead when tonic::DartState gets a microtask queue field.
|
||||
Dart_Handle async_lib = Dart_LookupLibrary(ToDart("dart:async"));
|
||||
FML_DCHECK(!tonic::LogIfError(async_lib));
|
||||
std::vector<Dart_Handle> sm_args{closure};
|
||||
Dart_Handle sm_result = Dart_Invoke(async_lib, ToDart("scheduleMicrotask"),
|
||||
sm_args.size(), sm_args.data());
|
||||
FML_DCHECK(!tonic::LogIfError(sm_result));
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
||||
Reference in New Issue
Block a user