[flutter,dart] Run handle wait completers on the microtask queue
Change-Id: I66c39d9ef7d534094148212940eef45754559d04
diff --git a/public/dart-pkg/zircon/lib/src/handle.dart b/public/dart-pkg/zircon/lib/src/handle.dart
index ca7883c..47516de 100644
--- a/public/dart-pkg/zircon/lib/src/handle.dart
+++ b/public/dart-pkg/zircon/lib/src/handle.dart
@@ -39,3 +39,17 @@
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
+}
diff --git a/public/dart-pkg/zircon/sdk_ext/handle_waiter.cc b/public/dart-pkg/zircon/sdk_ext/handle_waiter.cc
index 8ecfb87..0c86d7a 100644
--- a/public/dart-pkg/zircon/sdk_ext/handle_waiter.cc
+++ b/public/dart-pkg/zircon/sdk_ext/handle_waiter.cc
@@ -8,11 +8,13 @@
#include "dart-pkg/zircon/sdk_ext/handle.h"
#include "src/lib/fxl/logging.h"
+#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#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;
@@ -85,14 +87,32 @@
FXL_DCHECK(state);
DartState::Scope scope(state);
- std::vector<Dart_Handle> args{ToDart(status), ToDart(signal->observed)};
+ // Put the closure invocation on the microtask queue.
+ Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
+ FXL_DCHECK(!tonic::LogIfError(zircon_lib));
+
+ Dart_Handle owc_type =
+ Dart_GetClass(zircon_lib, ToDart("_OnWaitCompleteClosure"));
+ FXL_DCHECK(!tonic::LogIfError(owc_type));
+
FXL_DCHECK(!callback_.is_empty());
- Dart_Handle result =
- Dart_InvokeClosure(callback_.Release(), args.size(), args.data());
- // If there was an uncaught error from the callback propagate it out.
- if (tonic::LogIfError(result)) {
- state->message_handler().UnhandledError(result);
- }
+ 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());
+ FXL_DCHECK(!tonic::LogIfError(owc));
+
+ Dart_Handle closure = Dart_GetField(owc, ToDart("_closure"));
+ FXL_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"));
+ FXL_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());
+ FXL_DCHECK(!tonic::LogIfError(sm_result));
}
} // namespace dart
diff --git a/public/dart/sledge/lib/src/subscription/subscription.dart b/public/dart/sledge/lib/src/subscription/subscription.dart
index 66769cf..211c29c 100644
--- a/public/dart/sledge/lib/src/subscription/subscription.dart
+++ b/public/dart/sledge/lib/src/subscription/subscription.dart
@@ -42,7 +42,7 @@
_applyChangeCallback(_currentChange);
_currentChange.clear();
}
- return null;
+ return Future.value(null);
}
/// Ends subscription.