Skip to content

Commit

Permalink
[dart:zircon] Porting Cache re-usable handle wait objects (flutter#10809
Browse files Browse the repository at this point in the history
)

Change-Id: I230601acf5de24765737ad81b595fef2c154134c
  • Loading branch information
iskakaushik committed Aug 9, 2019
1 parent 1b28752 commit 42afb1a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 14 deletions.
54 changes: 53 additions & 1 deletion shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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
Expand Down
16 changes: 3 additions & 13 deletions shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle_waiter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 42afb1a

Please sign in to comment.