engine icon indicating copy to clipboard operation
engine copied to clipboard

[Windows] Make SendPlatformMessage thread-safe

Open jnschulze opened this issue 2 years ago • 2 comments

Make FlutterWindowsEngine::SendPlatformMessage thread-safe by ensuring that FlutterEngineSendPlatformMessage gets always called on the platform thread. This transitively makes FlutterDesktopMessengerSend and flutter::EventSink thread-safe.

Part of https://github.com/flutter/flutter/issues/134346

jnschulze avatar Nov 10 '23 19:11 jnschulze

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

flutter-dashboard[bot] avatar Nov 13 '23 08:11 flutter-dashboard[bot]

(triage): Talked to @loic-sharma last week and he said he is going to follow up on this change.

goderbauer avatar Jan 30 '24 23:01 goderbauer

EDIT: There was a misunderstanding on my side. I crossed out m comment that's incorrect.

@jnschulze Apologies for taking so long to respond to this. ~~If we can remove the blocking - which I believe we can - I'd be happy to land this even without a decision on https://github.com/flutter/flutter/issues/134346#issuecomment-1807665020. The engine responds to messages by posting a task to the UI thread without blocking. Thus, it seems reasonable to post a task to the platform thread without blocking in Windows's FlutterDesktopMessengerSend implementation.~~

I would also be happy to accept a FlutterEngine::PostPlatformThreadTask and FlutterDesktopEnginePostPlatformThreadTask APIs. Something like:

class FlutterEngine : public PluginRegistry {

  // ...

  // Schedule a callback to be called on the platform thread.
  //
  // This may be called on any thread. The callback is executed only
  // once on the platform thread.
  void PostPlatformThreadTask(std::function<void()> callback);
}
// Schedule a callback to be invoked on the engine's platform thread.
//
// This may be called on any thread. The callback is executed only
// once on the platform thread.
FLUTTER_EXPORT void FlutterDesktopEnginePostPlatformThreadTask(
    FlutterDesktopEngineRef engine,
    VoidCallback callback,
    void* user_data);

/cc @cbracken and @yaakovschectman since these would be public APIs.

loic-sharma avatar Apr 02 '24 23:04 loic-sharma

Thus, it seems reasonable to post a task to the platform thread without blocking in Windows's FlutterDesktopMessengerSend implementation.

How would the synchronous bool return value be handled in that scenario?

stuartmorgan-g avatar Apr 03 '24 00:04 stuartmorgan-g

Thus, it seems reasonable to post a task to the platform thread without blocking in Windows's FlutterDesktopMessengerSend implementation.

How would the synchronous bool return value be handled in that scenario?

Apologies, some wires got crossed on my end (somehow I was under the impression this was to make responding to platform message thread-safe. I should get more sleep or something 😅). You're completely right that a "fire and forget" solution wouldn't work for sending platform messages.

loic-sharma avatar Apr 03 '24 17:04 loic-sharma

Hey there, I'll go ahead and close this for now as it is stale.

I think the right short-term solution would be to add an API to post tasks to the platform thread (see https://github.com/flutter/flutter/issues/79213#issuecomment-2141021539).

The right long-term solution would be to make APIs exposed by the Windows embedder thread-safe, but this likely requires a design doc & design review from stakeholders.

Thanks for getting ball rolling on this. Feel free to ping me if you have any questions!

loic-sharma avatar Jun 04 '24 22:06 loic-sharma