Skip to content

[Windows] Fix PostPlatformThreadTask cancelling tasks before they run - #193412

Merged
auto-submit[bot] merged 6 commits into
flutter:masterfrom
Gustl22:193411-post-platform-thread-task-cancel
Oct 8, 2026
Merged

auto-submit[bot] merged 6 commits into
flutter:masterfrom
Gustl22:193411-post-platform-thread-task-cancel

Conversation

@Gustl22

@Gustl22 Gustl22 commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

FlutterDesktopEnginePostPlatformThreadTask aggregate-initialized its Context as a temporary and passed it to std::make_shared, which copied it into the shared allocation. When the temporary was destroyed at the end of the statement, its destructor saw invoked == false and called on_cancel immediately, even though the task was still queued and would run later.

Give Context a constructor so std::make_shared builds it in place, and disallow copying it with FML_DISALLOW_COPY_AND_ASSIGN. Any future change that copies the context now fails to compile instead of silently cancelling the task.

Add PostPlatformThreadTaskNotCancelledWhenRun, which verifies that on_cancel is called neither when the task is posted nor after it has run and the engine is destroyed.

Fixes #193411

For transparency: PR was partially created with Claude.

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.

FlutterDesktopEnginePostPlatformThreadTask aggregate-initialized its
Context as a temporary and passed it to std::make_shared, which copied
it into the shared allocation. When the temporary was destroyed at the
end of the statement, its destructor saw invoked == false and called
on_cancel immediately, even though the task was still queued and would
run later.

Give Context a constructor so std::make_shared builds it in place, and
disallow copying it with FML_DISALLOW_COPY_AND_ASSIGN. Any future change
that copies the context now fails to compile instead of silently
cancelling the task.

Add PostPlatformThreadTaskNotCancelledWhenRun, which verifies that
on_cancel is called neither when the task is posted nor after it has
run and the engine is destroyed.
@Gustl22
Gustl22 requested a review from a team as a code owner September 27, 2026 14:39
@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 Sep 27, 2026

@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 refactors the Context struct within FlutterDesktopEnginePostPlatformThreadTask to use an explicit constructor and adds a unit test to verify that the cancel callback is not invoked when a task runs. The review feedback recommends replacing the legacy FML_DISALLOW_COPY_AND_ASSIGN macro with explicit = delete declarations for the copy constructor and copy assignment operator to align with the Google C++ Style Guide, which also enables the removal of the newly added flutter/fml/macros.h header.

@knopp

knopp commented Sep 27, 2026

Copy link
Copy Markdown
Member

cc @loic-sharma

@knopp

knopp commented Sep 27, 2026

Copy link
Copy Markdown
Member

This seems to make sense. Interesting that gemini didn't catch the destructor on temporary invoking the on_cancel callback. The context must definitely be made non copyable.

loic-sharma
loic-sharma previously approved these changes Sep 27, 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.

Whoops. Gotta love C++ 😅

Thanks for fixing this! This looks good to me, with some minor nitpicks on the comments.

PumpMessage();
}

engine.reset();

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.

Is this line needed? I imagine this test would've failed before the fix even without this line? (I suspect this might've been copied from the PostPlatformThreadTaskCancelledOnEngineDestroy test, but I suspect it's not actually needed here.)

@Gustl22 Gustl22 Sep 28, 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.

this test would've failed before the fix even without this line?

Yes it would, but it additionally ensures that the cancel callback is not called, even if the engine was shut down after running the task, which was not tested before (as far as I can see).

And EXPECT_FALSE(captures.cancel_called); above the while loop tests the first case, so that cancel callback is not called immediately as soon as the context is destroyed. After the loop it makes less sense, as it would wait forever to finish, as the task would never have been called, when the test would have failed (before this PR fix).

I added an additional comment to explain the engine.reset line.

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.

Gotcha. I don't feel strongly either ways, so sounds good to me 👍

@loic-sharma loic-sharma added the CICD Run CI/CD label Sep 27, 2026
@Gustl22

Gustl22 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Thank you for the feedback @loic-sharma . Most of the comments were for my own understanding, but if its common practice, its totally fine to remove them (I'm not quite around in the C++ game ^^). Ready for a rereview now :D

@Gustl22
Gustl22 requested a review from loic-sharma September 28, 2026 08:51
@loic-sharma loic-sharma added the CICD Run CI/CD label Sep 28, 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.

Re-LGTM

@loic-sharma
loic-sharma requested a review from mattkae September 28, 2026 18:53
@Gustl22

Gustl22 commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Kindly asking you to do the second review @mattkae thank you for your time!
I am blocked with only 2 open PRs 🙈

@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 5, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 5, 2026
@auto-submit

auto-submit Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/193412, 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.

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Oct 5, 2026
@mattkae mattkae added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 5, 2026
@loic-sharma loic-sharma added the CICD Run CI/CD label Oct 5, 2026
@auto-submit

auto-submit Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/193412, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

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

auto-submit Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/193412, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

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

auto-submit Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/193412, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@loic-sharma loic-sharma added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 8, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Oct 8, 2026
@Gustl22

This comment was marked as outdated.

Merged via the queue into flutter:master with commit eb4d6c1 Oct 8, 2026
48 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 8, 2026
@Gustl22
Gustl22 deleted the 193411-post-platform-thread-task-cancel branch October 8, 2026 18:47
boyan01 added a commit to MixinNetwork/flutter-plugins that referenced this pull request Oct 17, 2026
…526)

FlutterDesktopEnginePostPlatformThreadTask in current stable Flutter builds its
task context from a temporary whose destructor invokes on_cancel right away,
so the plugin freed each queued FFI task before it ran and freed it again
afterwards. This affected every Dart -> native call and every native -> Dart
reply on Windows.

Pass no on_cancel and let the callback own the task. The engine is fixed
upstream in flutter/flutter#193412; until the minimum Flutter version includes
it, a task discarded at engine shutdown leaks instead.
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…flutter#193412)

FlutterDesktopEnginePostPlatformThreadTask aggregate-initialized its
Context as a temporary and passed it to std::make_shared, which copied
it into the shared allocation. When the temporary was destroyed at the
end of the statement, its destructor saw invoked == false and called
on_cancel immediately, even though the task was still queued and would
run later.

Give Context a constructor so std::make_shared builds it in place, and
disallow copying it with FML_DISALLOW_COPY_AND_ASSIGN. Any future change
that copies the context now fails to compile instead of silently
cancelling the task.

Add PostPlatformThreadTaskNotCancelledWhenRun, which verifies that
on_cancel is called neither when the task is posted nor after it has run
and the engine is destroyed.

Fixes flutter#193411

For transparency: PR was partially created with Claude.

## 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 in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [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.
- [x] 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
[flutter/website]: https://github.com/flutter/website
[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

---------

Co-authored-by: Loïc Sharma <[email protected]>
Co-authored-by: Matthew Kosarek <[email protected]>
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

4 participants