Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix a race in EmbedderTest.CanSpecifyCustomUITaskRunner#182649

Open
jason-simmons wants to merge 3 commits intoflutter:masterfrom
jason-simmons:embedder_ui_runner_race
Open

Fix a race in EmbedderTest.CanSpecifyCustomUITaskRunner#182649
jason-simmons wants to merge 3 commits intoflutter:masterfrom
jason-simmons:embedder_ui_runner_race

Conversation

@jason-simmons
Copy link
Member

The UI task runner will be destroyed during the call to FlutterEngineShutdown. It should continue forwarding tasks to the engine until the destruction callback is invoked. After that, it should stop using the engine.

The test had been using a mutex to guard the engine, but that does not work in this case because both the platform and UI threads must be able to run tasks during engine shutdown. If the test's platform thread holds the mutex during the call to engine.reset(), then the UI task runner can not acquire it to run its tasks. The test previously avoided that by calling engine.reset() without holding the mutex. That creates a race between engine shutdown and the UI task runner's check of engine.is_valid().

The UI task runner will be destroyed during the call to FlutterEngineShutdown.  It should continue forwarding tasks to the engine until the destruction callback is invoked.  After that, it should stop using the engine.The test had been using a mutex to guard the engine, but that does not work in this case because both the platform and UI threads must be able to run tasks during engine shutdown.  If the test's platform thread holds the mutex during the call to engine.reset(), then the UI task runner can not acquire it to run its tasks.The test previously avoided that by calling engine.reset() without holding the mutex.  That creates a race between engine shutdown and the UI task runner's check of engine.is_valid().
@github-actionsgithub-actionsbot added the engineflutter/engine related. See also e: labels. labelFeb 20, 2026
Copy link
Contributor

@gemini-code-assistgemini-code-assistbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Code Review

This pull request addresses a race condition in theCanSpecifyCustomUITaskRunner test. The fix involves using a destruction callback on the custom UI task runner to set a flag, preventing tasks from being run on a shutdown engine. This replaces a mutex-based approach that could lead to deadlocks. TheEmbedderTestTaskRunner has been updated to usestd::function for its destruction callback, improving its flexibility. Additionally, astatic variable in another test was made non-static to improve test isolation.

…tests_util.hCo-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link
Member

@gaaclarkegaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Nice catch.

Test exempt: this is a test

auto ui_thread = std::make_unique<fml::Thread>("test_ui_thread");
auto ui_task_runner = ui_thread->GetTaskRunner();
std::mutex ui_task_runner_mutex;
bool ui_task_runner_destroyed = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Please add the IPLR_GUARDED_BY macro to this variable.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheIPLR_ macros are defined in Impeller, but this test is in the engine tree outside Impeller. The engine/shell subsystems are not using the threading annotations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It's a couple of lines you can inline in this file. It's basically a preprocessor check for clang and an attribute on the variable.

});
test_task_runner.SetDestructionCallback(
[](void* user_data) { destruction_callback_called = true; });
[&]() { destruction_callback_called = true; });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The convention at google is to use explicit load() and store() functions with std::atomics.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

done

task_runner_description_.destruction_callback = [](void* user_data) {
auto thiz = reinterpret_cast<EmbedderTestTaskRunner*>(user_data);
if (thiz->destruction_callback_) {
thiz->destruction_callback_();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Is this executing on a different thread than SetDestructionCallback? If so there is a race condition and we'll need a mutex.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Changed this callback to be immutable after construction

Copy link
Member

@gaaclarkegaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

LGTM modulo a nit about clang's guarded_by attribute. Thanks jason.

auto ui_thread = std::make_unique<fml::Thread>("test_ui_thread");
auto ui_task_runner = ui_thread->GetTaskRunner();
std::mutex ui_task_runner_mutex;
bool ui_task_runner_destroyed = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It's a couple of lines you can inline in this file. It's basically a preprocessor check for clang and an attribute on the variable.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@gaaclarkegaaclarkegaaclarke approved these changes

+1 more reviewer

@gemini-code-assistgemini-code-assist[bot]gemini-code-assist[bot] left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

engineflutter/engine related. See also e: labels.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@jason-simmons@gaaclarke

Comments


[8]ページ先頭

©2009-2026 Movatter.jp