Skip to content

feat: Expose PostPlatformThreadTask and IsPlatformThread to PluginRegistrarWindows - #191140

Merged
auto-submit[bot] merged 5 commits into
flutter:masterfrom
Gustl22:190089-platform-thread
Oct 22, 2026
Merged

auto-submit[bot] merged 5 commits into
flutter:masterfrom
Gustl22:190089-platform-thread

Conversation

@Gustl22

@Gustl22 Gustl22 commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Plugins also should be able to post to the platform thread on windows.
This is especially important for platform channel event handling, as Windows platform events are mostly emitted by another thread.

Closes #190089

Formerly blocked by #193411

For transparency: Claude assisted code

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-windows Building on or for Windows specifically a: desktop Running on desktop team-windows Owned by the Windows platform team labels Aug 14, 2026
@Gustl22 Gustl22 changed the title feat: Add PostPlatformThreadTask and IsPlatformThread to PluginRegistrarWindows feat: Expose PostPlatformThreadTask and IsPlatformThread to PluginRegistrarWindows Aug 14, 2026
@Gustl22
Gustl22 force-pushed the 190089-platform-thread branch 2 times, most recently from 7139599 to 517ef7f Compare September 8, 2026 22:33
@Gustl22
Gustl22 force-pushed the 190089-platform-thread branch from 517ef7f to 562a8d2 Compare September 25, 2026 20:27
@Gustl22
Gustl22 force-pushed the 190089-platform-thread branch from 562a8d2 to 643ca13 Compare October 8, 2026 18:49
@Gustl22
Gustl22 marked this pull request as ready for review October 8, 2026 18:49
@Gustl22
Gustl22 requested a review from a team as a code owner October 8, 2026 18:49

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

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 introduces APIs to check if the current thread is the platform thread and to post tasks to the platform thread from the Windows plugin registrar. Feedback suggests adding defensive null checks for the registrar parameter in the newly added C APIs to prevent potential null-pointer dereferences and memory leaks.

delete static_cast<std::function<void()>*>(user_data);
},
/*user_data=*/new std::function<void()>(std::move(callback)));
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copied from flutter_engine.cc

TEST(PluginRegistrarWindowsTest, IsPlatformThread) {
auto windows_api = std::make_unique<TestWindowsApi>();
EXPECT_CALL(*windows_api, PluginRegistrarGetView)
.WillRepeatedly(Return(nullptr));

@Gustl22 Gustl22 Oct 9, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The check for PluginRegistrarGetView is probably irrelevant for this test, I left it in, because the other tests define it, too. But we can also remove it from all thread tests.

EXPECT_EQ(result, 7);
}

TEST(PluginRegistrarWindowsTest, IsPlatformThread) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you also add tests on the C APIs directly? See:

// Verify IsPlatformThread returns true on the platform thread.
TEST_F(WindowsTest, IsPlatformThread) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);
EXPECT_TRUE(FlutterDesktopEngineIsPlatformThread(engine.get()));
}
// Verify IsPlatformThread returns false on a background thread.
TEST_F(WindowsTest, IsNotPlatformThread) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);
bool result = true;
std::thread background(
[&]() { result = FlutterDesktopEngineIsPlatformThread(engine.get()); });
background.join();
EXPECT_FALSE(result);
}
// Verify a task can be posted to the platform thread while on the platform
// thread.
TEST_F(WindowsTest, PostPlatformThreadTaskFromPlatformThread) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);
struct Captures {
std::thread::id thread_id;
bool done = false;
} captures;
FlutterDesktopEnginePostPlatformThreadTask(
engine.get(),
[](void* user_data) {
auto captures = static_cast<Captures*>(user_data);
captures->thread_id = std::this_thread::get_id();
captures->done = true;
},
/*on_cancel=*/nullptr, &captures);
while (!captures.done) {
PumpMessage();
}
EXPECT_EQ(captures.thread_id, std::this_thread::get_id());
}
// Verify a task can be posted to the platform thread while on a background
// thread.
TEST_F(WindowsTest, PostPlatformThreadTaskFromBackgroundThread) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);
std::mutex background_thread_id_mutex;
struct Captures {
std::thread::id background_thread_id;
std::thread::id platform_thread_id;
bool done = false;
} captures;
std::thread background([&]() {
{
std::scoped_lock lock{background_thread_id_mutex};
captures.background_thread_id = std::this_thread::get_id();
}
FlutterDesktopEnginePostPlatformThreadTask(
engine.get(),
[](void* user_data) {
auto captures = static_cast<Captures*>(user_data);
captures->platform_thread_id = std::this_thread::get_id();
captures->done = true;
},
/*on_cancel=*/nullptr, &captures);
});
background.join();
while (!captures.done) {
PumpMessage();
}
std::scoped_lock lock{background_thread_id_mutex};
EXPECT_NE(captures.background_thread_id, std::thread::id{});
EXPECT_NE(captures.background_thread_id, captures.platform_thread_id);
EXPECT_EQ(captures.platform_thread_id, std::this_thread::get_id());
}
// Verify that destroying the engine after posting a task invokes the cancel
// callback instead of the task callback.
TEST_F(WindowsTest, PostPlatformThreadTaskCancelledOnEngineDestroy) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);
struct Captures {
bool callback_called = false;
bool cancel_called = false;
} captures;
FlutterDesktopEnginePostPlatformThreadTask(
engine.get(),
[](void* user_data) {
static_cast<Captures*>(user_data)->callback_called = true;
},
[](void* user_data) {
static_cast<Captures*>(user_data)->cancel_called = true;
},
&captures);
// Destroy the engine before the task has a chance to run. The cancel
// callback should be called and the task callback should not.
engine.reset();
EXPECT_FALSE(captures.callback_called);
EXPECT_TRUE(captures.cancel_called);
}
// Verify that the cancel callback is not invoked for a task that runs.
TEST_F(WindowsTest, PostPlatformThreadTaskNotCancelledWhenRun) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);
struct Captures {
bool callback_called = false;
bool cancel_called = false;
} captures;
FlutterDesktopEnginePostPlatformThreadTask(
engine.get(),
[](void* user_data) {
static_cast<Captures*>(user_data)->callback_called = true;
},
[](void* user_data) {
static_cast<Captures*>(user_data)->cancel_called = true;
},
&captures);
EXPECT_FALSE(captures.cancel_called);
while (!captures.callback_called) {
PumpMessage();
}
// Ensures that the cancel callback is not called,
// in case the engine was shut down after running the task.
engine.reset();
EXPECT_TRUE(captures.callback_called);
EXPECT_FALSE(captures.cancel_called);
}

@Gustl22 Gustl22 Oct 10, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@loic-sharma
Yikes, sorry my tests were sloppy. To be honest I am not that familiar with C(++), as I would wish to be.

I added:

Also I did ensure on existing tests, that

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the updates!

And no worries. I'm also not as familiar with C++ as I'd like after almost 15 years 😂

@Gustl22
Gustl22 force-pushed the 190089-platform-thread branch from 538bf40 to 6e7e232 Compare October 10, 2026 17:00
@Gustl22
Gustl22 requested a review from loic-sharma October 10, 2026 17:14
@loic-sharma
loic-sharma requested a review from mattkae October 10, 2026 21:43
@loic-sharma loic-sharma added the CICD Run CI/CD label Oct 10, 2026

@loic-sharma loic-sharma left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thanks for the wonderful contribution!

@Gustl22

Gustl22 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

@mattkae can you have a look for the second review? Thx for the time.

@mattkae mattkae left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice, thanks!

@mattkae mattkae added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 21, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 21, 2026
@auto-submit

auto-submit Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/191140, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR.

@Gustl22

Gustl22 commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Thank you all! Unfortunately I cannot merge back from master, otherwise my approvals get revoked.

@mattkae
mattkae force-pushed the 190089-platform-thread branch from 6e7e232 to 3e37fcf Compare October 21, 2026 14:46
@Gustl22

Gustl22 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Sorry I am so chatty today. I think master should be merged before reapplying autosubmit again. The test probably fails due to trying getting an engine build which doesn't exist (from a failed mac build?).

@mattkae
mattkae force-pushed the 190089-platform-thread branch from 3e37fcf to 5f6b178 Compare October 21, 2026 18:25
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Oct 21, 2026
@mattkae

mattkae commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Sorry I am so chatty today. I think master should be merged before reapplying autosubmit again. The test probably fails due to trying getting an engine build which doesn't exist (from a failed mac build?).

No worries! I will merge up, then retry. Fickle CI 😅

@mattkae mattkae added CICD Run CI/CD autosubmit Merge PR when tree becomes green via auto submit App labels Oct 21, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Oct 21, 2026
Merged via the queue into flutter:master with commit e194458 Oct 22, 2026
40 of 41 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 22, 2026
@Gustl22
Gustl22 deleted the 190089-platform-thread branch October 24, 2026 20:56
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…istrarWindows (flutter#191140)

Plugins also should be able to post to the platform thread on windows.
This is especially important for platform channel event handling, as
Windows platform events are mostly emitted by another thread.

Closes flutter#190089 

Formerly blocked by flutter#193411

For transparency: Claude assisted code

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: desktop Running on desktop CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-windows Building on or for Windows specifically team-windows Owned by the Windows platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Windows] Allow plugins to post platform thread tasks using PluginRegistrarWindows

3 participants