未验证 提交 42afb1ab 编写于 作者: K Kaushik Iska 提交者: GitHub

[dart:zircon] Porting Cache re-usable handle wait objects (#10809)

Change-Id: I230601acf5de24765737ad81b595fef2c154134c
上级 1b287524
......@@ -16,7 +16,29 @@ namespace dart {
IMPLEMENT_WRAPPERTYPEINFO(zircon, Handle);
Handle::Handle(zx_handle_t handle) : handle_(handle) {}
Handle::Handle(zx_handle_t handle) : handle_(handle) {
tonic::DartState* state = tonic::DartState::Current();
FML_DCHECK(state);
Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
FML_DCHECK(!tonic::LogIfError(zircon_lib));
Dart_Handle on_wait_completer_type =
Dart_GetClass(zircon_lib, ToDart("_OnWaitCompleteClosure"));
FML_DCHECK(!tonic::LogIfError(on_wait_completer_type));
on_wait_completer_type_.Set(state, on_wait_completer_type);
Dart_Handle async_lib = Dart_LookupLibrary(ToDart("dart:async"));
FML_DCHECK(!tonic::LogIfError(async_lib));
async_lib_.Set(state, async_lib);
Dart_Handle closure_string = ToDart("_closure");
FML_DCHECK(!tonic::LogIfError(closure_string));
closure_string_.Set(state, closure_string);
Dart_Handle schedule_microtask_string = ToDart("scheduleMicrotask");
FML_DCHECK(!tonic::LogIfError(schedule_microtask_string));
schedule_microtask_string_.Set(state, schedule_microtask_string);
}
Handle::~Handle() {
if (is_valid()) {
......@@ -93,6 +115,36 @@ Dart_Handle Handle::Duplicate(uint32_t rights) {
return ToDart(Create(out_handle));
}
void Handle::ScheduleCallback(tonic::DartPersistentValue callback,
zx_status_t status,
const zx_packet_signal_t* signal) {
auto state = callback.dart_state().lock();
FML_DCHECK(state);
tonic::DartState::Scope scope(state);
// Make a new _OnWaitCompleteClosure(callback, status, signal->observed).
FML_DCHECK(!callback.is_empty());
std::vector<Dart_Handle> constructor_args{callback.Release(), ToDart(status),
ToDart(signal->observed)};
Dart_Handle on_wait_complete_closure =
Dart_New(on_wait_completer_type_.Get(), Dart_Null(),
constructor_args.size(), constructor_args.data());
FML_DCHECK(!tonic::LogIfError(on_wait_complete_closure));
// The _callback field contains the thunk:
// () => callback(status, signal->observed)
Dart_Handle closure =
Dart_GetField(on_wait_complete_closure, closure_string_.Get());
FML_DCHECK(!tonic::LogIfError(closure));
// Put the thunk on the microtask queue by calling scheduleMicrotask().
std::vector<Dart_Handle> sm_args{closure};
Dart_Handle sm_result =
Dart_Invoke(async_lib_.Get(), schedule_microtask_string_.Get(),
sm_args.size(), sm_args.data());
FML_DCHECK(!tonic::LogIfError(sm_result));
}
// clang-format: off
#define FOR_EACH_STATIC_BINDING(V) V(Handle, CreateInvalid)
......
......@@ -60,6 +60,10 @@ class Handle : public fml::RefCountedThreadSafe<Handle>,
Dart_Handle Duplicate(uint32_t rights);
void ScheduleCallback(tonic::DartPersistentValue callback,
zx_status_t status,
const zx_packet_signal_t* signal);
private:
explicit Handle(zx_handle_t handle);
......@@ -70,6 +74,13 @@ class Handle : public fml::RefCountedThreadSafe<Handle>,
zx_handle_t handle_;
std::vector<HandleWaiter*> waiters_;
// Some cached persistent handles to make running handle wait completers
// faster.
tonic::DartPersistentValue async_lib_;
tonic::DartPersistentValue closure_string_;
tonic::DartPersistentValue on_wait_completer_type_;
tonic::DartPersistentValue schedule_microtask_string_;
};
} // namespace dart
......
......@@ -81,21 +81,11 @@ 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);
std::vector<Dart_Handle> args{ToDart(status), ToDart(signal->observed)};
FML_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);
}
}
} // namespace dart
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册