Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 53c9a70

Browse files
authored
Add waitUIThreadIdle service RPC (#3898)
In #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 flutter/flutter#11241
1 parent 99bc6ee commit 53c9a70

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

shell/common/platform_view_service_protocol.cc

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ void PlatformViewServiceProtocol::RegisterHook(bool running_precompiled_code) {
128128
}
129129
Dart_RegisterRootServiceRequestCallback(kRunInViewExtensionName, &RunInView,
130130
nullptr);
131+
// [benchmark helper] Wait for the UI Thread to idle.
132+
Dart_RegisterRootServiceRequestCallback(kFlushUIThreadTasksExtensionName,
133+
&FlushUIThreadTasks, nullptr);
131134
}
132135

133136
const char* PlatformViewServiceProtocol::kRunInViewExtensionName =
@@ -202,11 +205,10 @@ bool PlatformViewServiceProtocol::ListViews(const char* method,
202205
intptr_t num_params,
203206
void* user_data,
204207
const char** json_object) {
205-
// Ask the Shell for the list of platform views. This will run a task on
206-
// the UI thread before returning.
208+
// Ask the Shell for the list of platform views.
207209
Shell& shell = Shell::Shared();
208210
std::vector<Shell::PlatformViewInfo> platform_views;
209-
shell.WaitForPlatformViewIds(&platform_views);
211+
shell.GetPlatformViewIds(&platform_views);
210212

211213
std::stringstream response;
212214

@@ -314,4 +316,32 @@ void PlatformViewServiceProtocol::ScreenshotGpuTask(SkBitmap* bitmap) {
314316
canvas->flush();
315317
}
316318

319+
const char* PlatformViewServiceProtocol::kFlushUIThreadTasksExtensionName =
320+
"_flutter.flushUIThreadTasks";
321+
322+
// This API should not be invoked by production code.
323+
// It can potentially starve the service isolate if the main isolate pauses
324+
// at a breakpoint or is in an infinite loop.
325+
//
326+
// It should be invoked from the VM Service and and blocks it until UI thread
327+
// tasks are processed.
328+
bool PlatformViewServiceProtocol::FlushUIThreadTasks(const char* method,
329+
const char** param_keys,
330+
const char** param_values,
331+
intptr_t num_params,
332+
void* user_data,
333+
const char** json_object) {
334+
ftl::AutoResetWaitableEvent latch;
335+
blink::Threads::UI()->PostTask([&latch]() {
336+
// This task is empty because we just need to synchronize this RPC with the
337+
// UI Thread
338+
latch.Signal();
339+
});
340+
341+
latch.Wait();
342+
343+
*json_object = strdup("{\"type\":\"Success\"}");
344+
return true;
345+
}
346+
317347
} // namespace shell

shell/common/platform_view_service_protocol.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class PlatformViewServiceProtocol {
2020

2121
private:
2222
static const char* kRunInViewExtensionName;
23+
// It should be invoked from the VM Service and and blocks it until previous
24+
// UI thread tasks are processed.
2325
static bool RunInView(const char* method,
2426
const char** param_keys,
2527
const char** param_values,
@@ -36,13 +38,29 @@ class PlatformViewServiceProtocol {
3638
const char** json_object);
3739

3840
static const char* kScreenshotExtensionName;
41+
// It should be invoked from the VM Service and and blocks it until previous
42+
// GPU thread tasks are processed.
3943
static bool Screenshot(const char* method,
4044
const char** param_keys,
4145
const char** param_values,
4246
intptr_t num_params,
4347
void* user_data,
4448
const char** json_object);
4549
static void ScreenshotGpuTask(SkBitmap* bitmap);
50+
51+
// This API should not be invoked by production code.
52+
// It can potentially starve the service isolate if the main isolate pauses
53+
// at a breakpoint or is in an infinite loop.
54+
//
55+
// It should be invoked from the VM Service and and blocks it until previous
56+
// GPU thread tasks are processed.
57+
static const char* kFlushUIThreadTasksExtensionName;
58+
static bool FlushUIThreadTasks(const char* method,
59+
const char** param_keys,
60+
const char** param_values,
61+
intptr_t num_params,
62+
void* user_data,
63+
const char** json_object);
4664
};
4765

4866
} // namespace shell

shell/common/shell.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ void Shell::GetPlatformViews(
262262
*platform_views = platform_views_;
263263
}
264264

265-
void Shell::WaitForPlatformViewIds(
265+
void Shell::GetPlatformViewIds(
266266
std::vector<PlatformViewInfo>* platform_view_ids) {
267267
std::lock_guard<std::mutex> lk(platform_views_mutex_);
268268
for (auto it = platform_views_.begin(); it != platform_views_.end(); it++) {

shell/common/shell.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Shell {
4444

4545
// List of PlatformViews.
4646

47-
// These APIs must only be accessed on UI thread.
47+
// These APIs can be called from any thread.
4848
void AddPlatformView(const std::shared_ptr<PlatformView>& platform_view);
4949
void PurgePlatformViews();
5050
void GetPlatformViews(
@@ -58,7 +58,7 @@ class Shell {
5858

5959
// These APIs can be called from any thread.
6060
// Return the list of platform view ids at the time of this call.
61-
void WaitForPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
61+
void GetPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
6262

6363
// Attempt to run a script inside a flutter view indicated by |view_id|.
6464
// Will set |view_existed| to true if the view was found and false otherwise.

0 commit comments

Comments
 (0)