提交 53c9a702 编写于 作者: C Carlo Bernaschina 提交者: GitHub

Add waitUIThreadIdle service RPC (#3898)

In https://github.com/flutter/engine/pull/3833 the `_flutter.listViews` RPC moved from thread based to lock based synchronization.
The thread based synchronization side effect was used by flutter benchmarks in https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/vmservice.dart#L1223 and
https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/run_hot.dart#L156 to ensure the completeness of the restart/reload and so correct timing.

A new RPC `_flutter.flushUIThreadTasks` is introduced to allow the flutter benchmarks to reintroduce thread based synchronization.

Related https://github.com/flutter/flutter/issues/11241
上级 99bc6ee6
......@@ -128,6 +128,9 @@ void PlatformViewServiceProtocol::RegisterHook(bool running_precompiled_code) {
}
Dart_RegisterRootServiceRequestCallback(kRunInViewExtensionName, &RunInView,
nullptr);
// [benchmark helper] Wait for the UI Thread to idle.
Dart_RegisterRootServiceRequestCallback(kFlushUIThreadTasksExtensionName,
&FlushUIThreadTasks, nullptr);
}
const char* PlatformViewServiceProtocol::kRunInViewExtensionName =
......@@ -202,11 +205,10 @@ bool PlatformViewServiceProtocol::ListViews(const char* method,
intptr_t num_params,
void* user_data,
const char** json_object) {
// Ask the Shell for the list of platform views. This will run a task on
// the UI thread before returning.
// Ask the Shell for the list of platform views.
Shell& shell = Shell::Shared();
std::vector<Shell::PlatformViewInfo> platform_views;
shell.WaitForPlatformViewIds(&platform_views);
shell.GetPlatformViewIds(&platform_views);
std::stringstream response;
......@@ -314,4 +316,32 @@ void PlatformViewServiceProtocol::ScreenshotGpuTask(SkBitmap* bitmap) {
canvas->flush();
}
const char* PlatformViewServiceProtocol::kFlushUIThreadTasksExtensionName =
"_flutter.flushUIThreadTasks";
// This API should not be invoked by production code.
// It can potentially starve the service isolate if the main isolate pauses
// at a breakpoint or is in an infinite loop.
//
// It should be invoked from the VM Service and and blocks it until UI thread
// tasks are processed.
bool PlatformViewServiceProtocol::FlushUIThreadTasks(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object) {
ftl::AutoResetWaitableEvent latch;
blink::Threads::UI()->PostTask([&latch]() {
// This task is empty because we just need to synchronize this RPC with the
// UI Thread
latch.Signal();
});
latch.Wait();
*json_object = strdup("{\"type\":\"Success\"}");
return true;
}
} // namespace shell
......@@ -20,6 +20,8 @@ class PlatformViewServiceProtocol {
private:
static const char* kRunInViewExtensionName;
// It should be invoked from the VM Service and and blocks it until previous
// UI thread tasks are processed.
static bool RunInView(const char* method,
const char** param_keys,
const char** param_values,
......@@ -36,6 +38,8 @@ class PlatformViewServiceProtocol {
const char** json_object);
static const char* kScreenshotExtensionName;
// It should be invoked from the VM Service and and blocks it until previous
// GPU thread tasks are processed.
static bool Screenshot(const char* method,
const char** param_keys,
const char** param_values,
......@@ -43,6 +47,20 @@ class PlatformViewServiceProtocol {
void* user_data,
const char** json_object);
static void ScreenshotGpuTask(SkBitmap* bitmap);
// This API should not be invoked by production code.
// It can potentially starve the service isolate if the main isolate pauses
// at a breakpoint or is in an infinite loop.
//
// It should be invoked from the VM Service and and blocks it until previous
// GPU thread tasks are processed.
static const char* kFlushUIThreadTasksExtensionName;
static bool FlushUIThreadTasks(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
};
} // namespace shell
......
......@@ -262,7 +262,7 @@ void Shell::GetPlatformViews(
*platform_views = platform_views_;
}
void Shell::WaitForPlatformViewIds(
void Shell::GetPlatformViewIds(
std::vector<PlatformViewInfo>* platform_view_ids) {
std::lock_guard<std::mutex> lk(platform_views_mutex_);
for (auto it = platform_views_.begin(); it != platform_views_.end(); it++) {
......
......@@ -44,7 +44,7 @@ class Shell {
// List of PlatformViews.
// These APIs must only be accessed on UI thread.
// These APIs can be called from any thread.
void AddPlatformView(const std::shared_ptr<PlatformView>& platform_view);
void PurgePlatformViews();
void GetPlatformViews(
......@@ -58,7 +58,7 @@ class Shell {
// These APIs can be called from any thread.
// Return the list of platform view ids at the time of this call.
void WaitForPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
void GetPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
// Attempt to run a script inside a flutter view indicated by |view_id|.
// Will set |view_existed| to true if the view was found and false otherwise.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册