Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
765300a
WIP prototype
liamappelbe Nov 19, 2023
642de7d
missed files
liamappelbe Nov 19, 2023
e193318
fix
liamappelbe Nov 20, 2023
eb2d782
Merge branch 'main' into platiso
liamappelbe Nov 22, 2023
e4b3c24
WIP
liamappelbe Nov 27, 2023
9894b98
Working prototype
liamappelbe Nov 30, 2023
a33ff74
Clean up a bit
liamappelbe Nov 30, 2023
97ca3fd
Ryan's comments
liamappelbe Dec 4, 2023
d88fdfd
Revert changes to tester_main
liamappelbe Dec 4, 2023
527eb03
Handle engine shutdown using PlatformIsolateManager
liamappelbe Dec 6, 2023
a441ddb
Move PlatformIsolateManager to RuntimeController and shutdown to Shell
liamappelbe Dec 7, 2023
fd31dbc
Move platiso shutdown to MessageEpilogue callback
liamappelbe Dec 7, 2023
c08bd8d
Merge branch 'main' into platiso2
liamappelbe Dec 7, 2023
675ba56
Merge branch 'main' into platiso2
liamappelbe Jan 3, 2024
d816957
Fix race between RegisterPlatformIsolate and ShutdownPlatformIsolates
liamappelbe Jan 4, 2024
3d2d5d8
Tests
liamappelbe Jan 11, 2024
81cfe52
More tests
liamappelbe Jan 14, 2024
27b4db3
More tests and error handling.
liamappelbe Jan 18, 2024
430d342
Support errorsAreFatal flag
liamappelbe Jan 23, 2024
dfffe7a
Clean up some TODOs
liamappelbe Jan 24, 2024
c279bfc
Format
liamappelbe Jan 24, 2024
6e384c3
Merge branch 'main' into platiso2
liamappelbe Jan 24, 2024
3e31187
API documentation
liamappelbe Jan 25, 2024
22af0cc
Fix typos
liamappelbe Jan 25, 2024
dfdf2c7
Fix licences and some build warnings
liamappelbe Jan 25, 2024
4d726f0
fmt
liamappelbe Jan 25, 2024
56df527
Fix clang-tidy
liamappelbe Jan 25, 2024
6e48192
Jason's comments
liamappelbe Jan 30, 2024
b196c55
Merge branch 'main' into platiso2
liamappelbe Jan 30, 2024
c7af637
Shutdown platform isolate if registration failed.
liamappelbe Jan 30, 2024
679abcd
Fix the seg fault and test microtask scheduling
liamappelbe Feb 2, 2024
b084018
format
liamappelbe Feb 2, 2024
c982a10
Merge branch 'main' into platiso2
liamappelbe Feb 2, 2024
75d4dde
clang tidy
liamappelbe Feb 2, 2024
4d2acfd
Pass null isolate_group_data to CreateDartIsolateGroup
liamappelbe Feb 4, 2024
167f015
fmt
liamappelbe Feb 4, 2024
699175c
Fix analysis
liamappelbe Feb 5, 2024
a4f4a61
Cache platform isolate, remove spawn method
liamappelbe Feb 7, 2024
b9a51f9
Dummy platform_isolate API for web
liamappelbe Feb 7, 2024
51bad14
Revert "Dummy platform_isolate API for web"
liamappelbe Feb 7, 2024
e823f32
Only expose runInPlatformThread in the API
liamappelbe Feb 7, 2024
4a343cb
Merge branch 'platiso3' into platiso2
liamappelbe Feb 7, 2024
f50f791
Fix license
liamappelbe Feb 7, 2024
185e248
Fix dummy web API
liamappelbe Feb 8, 2024
a45ca33
Fix analysis
liamappelbe Feb 8, 2024
8bc9944
Fix test
liamappelbe Feb 9, 2024
998aa5e
Fix test in release mode, and a flake
liamappelbe Feb 11, 2024
99dbdd8
fmt
liamappelbe Feb 11, 2024
400da57
fmt
liamappelbe Feb 11, 2024
cb9b845
Fix test
liamappelbe Feb 11, 2024
21f5141
Fix impeller build
liamappelbe Feb 13, 2024
3b5a2c4
Keep platform isolate alive for the lifetime of the app
liamappelbe Feb 13, 2024
c98528f
Merge branch 'platiso2' of github.com:liamappelbe/engine into platiso2
liamappelbe Feb 13, 2024
b9a87d9
Fix analysis
liamappelbe Feb 14, 2024
d53522d
Merge branch 'main' into platiso2
liamappelbe Feb 20, 2024
6de7797
Simplify platfor_isolate.dart and disable Isolate.exit
liamappelbe Feb 21, 2024
5dd4f9b
Simplify PlatformIsolateManager, and add more tests
liamappelbe Feb 21, 2024
b493f1d
format
liamappelbe Feb 22, 2024
2094637
Merge branch 'main' into platiso2
liamappelbe Feb 22, 2024
87c2060
Fix analysis and one test
liamappelbe Feb 22, 2024
9ee715c
Review comments
liamappelbe Feb 27, 2024
9d0ce6d
More review comments
liamappelbe Feb 27, 2024
45cd307
fmt
liamappelbe Feb 27, 2024
33f483b
Merge branch 'main' into platiso2
liamappelbe Feb 27, 2024
40d06ef
Fix merge cruft
liamappelbe Feb 28, 2024
de58637
Silence UnwindErrors
liamappelbe Feb 29, 2024
94c25cd
Review comments
liamappelbe Mar 4, 2024
de5d6b5
Merge branch 'main' into platiso2
liamappelbe Mar 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@
../../../flutter/runtime/dart_vm_unittests.cc
../../../flutter/runtime/fixtures
../../../flutter/runtime/no_dart_plugin_registrant_unittests.cc
../../../flutter/runtime/platform_isolate_manager_unittests.cc
../../../flutter/runtime/type_conversions_unittests.cc
../../../flutter/shell/common/animator_unittests.cc
../../../flutter/shell/common/base64_unittests.cc
Expand Down
12 changes: 12 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -35635,6 +35635,7 @@ ORIGIN: ../../../flutter/lib/ui/painting/single_frame_codec.h + ../../../flutter
ORIGIN: ../../../flutter/lib/ui/painting/vertices.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/painting/vertices.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/platform_dispatcher.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/platform_isolate.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/plugins.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/plugins/callback_cache.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/plugins/callback_cache.h + ../../../flutter/LICENSE
Expand Down Expand Up @@ -35675,6 +35676,8 @@ ORIGIN: ../../../flutter/lib/ui/window/key_data_packet.cc + ../../../flutter/LIC
ORIGIN: ../../../flutter/lib/ui/window/key_data_packet.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_configuration.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_configuration.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_isolate.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_isolate.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_message.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_message.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/ui/window/platform_message_response.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -35716,6 +35719,7 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/painting.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/path.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/path_metrics.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/platform_dispatcher.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/platform_isolate.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/pointer.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/semantics.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine.dart + ../../../flutter/LICENSE
Expand Down Expand Up @@ -36015,6 +36019,8 @@ ORIGIN: ../../../flutter/runtime/isolate_configuration.cc + ../../../flutter/LIC
ORIGIN: ../../../flutter/runtime/isolate_configuration.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/platform_data.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/platform_data.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/platform_isolate_manager.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/platform_isolate_manager.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/ptrace_check.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/ptrace_check.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/runtime/runtime_controller.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -38475,6 +38481,7 @@ FILE: ../../../flutter/lib/ui/painting/single_frame_codec.h
FILE: ../../../flutter/lib/ui/painting/vertices.cc
FILE: ../../../flutter/lib/ui/painting/vertices.h
FILE: ../../../flutter/lib/ui/platform_dispatcher.dart
FILE: ../../../flutter/lib/ui/platform_isolate.dart
FILE: ../../../flutter/lib/ui/plugins.dart
FILE: ../../../flutter/lib/ui/plugins/callback_cache.cc
FILE: ../../../flutter/lib/ui/plugins/callback_cache.h
Expand Down Expand Up @@ -38515,6 +38522,8 @@ FILE: ../../../flutter/lib/ui/window/key_data_packet.cc
FILE: ../../../flutter/lib/ui/window/key_data_packet.h
FILE: ../../../flutter/lib/ui/window/platform_configuration.cc
FILE: ../../../flutter/lib/ui/window/platform_configuration.h
FILE: ../../../flutter/lib/ui/window/platform_isolate.cc
FILE: ../../../flutter/lib/ui/window/platform_isolate.h
FILE: ../../../flutter/lib/ui/window/platform_message.cc
FILE: ../../../flutter/lib/ui/window/platform_message.h
FILE: ../../../flutter/lib/ui/window/platform_message_response.cc
Expand Down Expand Up @@ -38557,6 +38566,7 @@ FILE: ../../../flutter/lib/web_ui/lib/painting.dart
FILE: ../../../flutter/lib/web_ui/lib/path.dart
FILE: ../../../flutter/lib/web_ui/lib/path_metrics.dart
FILE: ../../../flutter/lib/web_ui/lib/platform_dispatcher.dart
FILE: ../../../flutter/lib/web_ui/lib/platform_isolate.dart
FILE: ../../../flutter/lib/web_ui/lib/pointer.dart
FILE: ../../../flutter/lib/web_ui/lib/semantics.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine.dart
Expand Down Expand Up @@ -38856,6 +38866,8 @@ FILE: ../../../flutter/runtime/isolate_configuration.cc
FILE: ../../../flutter/runtime/isolate_configuration.h
FILE: ../../../flutter/runtime/platform_data.cc
FILE: ../../../flutter/runtime/platform_data.h
FILE: ../../../flutter/runtime/platform_isolate_manager.cc
FILE: ../../../flutter/runtime/platform_isolate_manager.h
FILE: ../../../flutter/runtime/ptrace_check.cc
FILE: ../../../flutter/runtime/ptrace_check.h
FILE: ../../../flutter/runtime/runtime_controller.cc
Expand Down
1 change: 1 addition & 0 deletions common/exported_test_symbols.sym
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
Spawn;
LoadLibraryFromKernel;
LookupEntryPoint;
ForceShutdownIsolate;
};
1 change: 1 addition & 0 deletions common/exported_test_symbols_mac.sym
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ _kInternalFlutterGpu*
_Spawn
_LoadLibraryFromKernel
_LookupEntryPoint
_ForceShutdownIsolate
2 changes: 2 additions & 0 deletions lib/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ source_set("ui") {
"window/key_data_packet.h",
"window/platform_configuration.cc",
"window/platform_configuration.h",
"window/platform_isolate.cc",
"window/platform_isolate.h",
"window/platform_message.cc",
"window/platform_message.h",
"window/platform_message_response.cc",
Expand Down
3 changes: 3 additions & 0 deletions lib/ui/dart_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "flutter/lib/ui/text/paragraph.h"
#include "flutter/lib/ui/text/paragraph_builder.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/lib/ui/window/platform_isolate.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#include "third_party/tonic/logging/dart_error.h"
Expand Down Expand Up @@ -113,6 +114,8 @@ typedef CanvasPath Path;
V(PlatformConfigurationNativeApi::SendPortPlatformMessage) \
V(PlatformConfigurationNativeApi::SendChannelUpdate) \
V(PlatformConfigurationNativeApi::GetScaledFontSize) \
V(PlatformIsolateNativeApi::IsRunningOnPlatformThread) \
V(PlatformIsolateNativeApi::Spawn) \
V(DartRuntimeHooks::Logger_PrintDebugString) \
V(DartRuntimeHooks::Logger_PrintString) \
V(DartRuntimeHooks::ScheduleMicrotask) \
Expand Down
9 changes: 8 additions & 1 deletion lib/ui/experiments/ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate' show SendPort;
import 'dart:isolate'
show
Isolate,
IsolateSpawnException,
RawReceivePort,
RemoteError,
SendPort;
import 'dart:math' as math;
import 'dart:nativewrappers';
import 'dart:typed_data';
Expand All @@ -35,6 +41,7 @@ part '../math.dart';
part '../natives.dart';
part '../painting.dart';
part '../platform_dispatcher.dart';
part '../platform_isolate.dart';
part '../plugins.dart';
part '../pointer.dart';
part '../semantics.dart';
Expand Down
189 changes: 189 additions & 0 deletions lib/ui/platform_isolate.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

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

2024

Copy link
Member

Choose a reason for hiding this comment

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

Flutter uses 2013 throughout its codebase

Copy link
Member

Choose a reason for hiding this comment

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

Flutter uses 2013 throughout its codebase

That's not what go/copyright (external version https://opensource.google/documentation/reference/copyright) instructs us to do though. It should be the year when the file got first published.

Other coding styles (like Chromium1) seem to adhere to the go/copyright.

Footnotes

  1. https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/c++/c++.md#file-headers

// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of dart.ui;

/// Runs [computation] on the platform thread and returns the result.
///
Copy link
Member

Choose a reason for hiding this comment

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

If the platform doesn't support a platform thread (or it wasn't implemented) - e.g. like jason mentions linux desktop embedder - this function will throw.

/// This may run the computation on a separate isolate. That isolate will be
/// reused for subsequent [runOnPlatformThread] calls. This means that global
/// state is maintained in that isolate between calls.
///
/// The [computation] and any state it captures may be sent to that isolate.
/// See [SendPort.send] for information about what types can be sent.
///
/// If [computation] is asynchronous (returns a `Future<R>`) then
/// that future is awaited in the new isolate, completing the entire
/// asynchronous computation, before returning the result.
///
/// If [computation] throws, the `Future` returned by this function completes
/// with that error.
///
/// The [computation] function and its result (or error) must be
/// sendable between isolates. Objects that cannot be sent include open
/// files and sockets (see [SendPort.send] for details).
///
/// This method can only be invoked from the main isolate.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should mark this temporarily as

///
/// Experimental for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

///
/// This API is currently experimental.
Future<R> runOnPlatformThread<R>(FutureOr<R> Function() computation) {
if (isRunningOnPlatformThread) {
return Future<R>(computation);
}
final SendPort? sendPort = _platformRunnerSendPort;
if (sendPort != null) {
return _sendComputation(sendPort, computation);
} else {
return (_platformRunnerSendPortFuture ??= _spawnPlatformIsolate())
.then((SendPort port) => _sendComputation(port, computation));
}
}

SendPort? _platformRunnerSendPort;
Future<SendPort>? _platformRunnerSendPortFuture;
final Map<int, Completer<Object?>> _pending = <int, Completer<Object?>>{};
int _nextId = 0;

Future<SendPort> _spawnPlatformIsolate() {
final Completer<SendPort> sendPortCompleter = Completer<SendPort>();
final RawReceivePort receiver = RawReceivePort()..keepIsolateAlive = false;
Copy link
Member

Choose a reason for hiding this comment

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

When we later allow calling this from a helper isolates, we may want to

  // When scheduling a computation
  if (_pending.isEmpty) {
    receiver.keepIsolateAlive = true;
  }
  _pending[nextId++] = ...

  // When getting result
  ... = _pending.removeAt(id);
  if (_pending.isEmpty) receiver.keepIsolateAlive = false;

Consider leaving a comment

(the keepIsolateAlive getter/setter can be optimized to not go to runtime)

receiver.handler = (Object? message) {
if (message == null) {
// This is the platform isolate's onExit handler.
Copy link
Member

Choose a reason for hiding this comment

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

Are we actually registering an exit handler (don't see where)?

Either we should throw an error if we think this cannot happen or we should just complete all pending RPCs with an error - but not silently ignore it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Jason's comment mentions how to make a private test-only API, so I can now implement and test this logic.

// This shouldn't really happen, since Isolate.exit is disabled, the
// pause and terminate capabilities aren't provided to the parent
// isolate, and errors are fatal is false. But if the isolate does
// shutdown unexpectedly, clear the singleton so we can create another.
for (final Completer<Object?> completer in _pending.values) {
completer.completeError(RemoteError(
'PlatformIsolate shutdown unexpectedly',
StackTrace.empty.toString()));
}
_pending.clear();
_platformRunnerSendPort = null;
_platformRunnerSendPortFuture = null;
} else if (message is _PlatformIsolateReadyMessage) {
_platformRunnerSendPort = message.computationPort;
sendPortCompleter.complete(message.computationPort);
} else if (message is _ComputationResult) {
final Completer<Object?> resultCompleter = _pending.remove(message.id)!;
final Object? remoteStack = message.remoteStack;
final Object? remoteError = message.remoteError;
if (remoteStack != null) {
if (remoteStack is StackTrace) {
// Typed error.
resultCompleter.completeError(remoteError!, remoteStack);
} else {
// onError handler message, uncaught async error.
// Both values are strings, so calling `toString` is efficient.
final RemoteError error =
RemoteError(remoteError!.toString(), remoteStack.toString());
resultCompleter.completeError(error, error.stackTrace);
}
} else {
resultCompleter.complete(message.result);
}
} else {
// We encountered an error while starting the new isolate.
Copy link
Member

Choose a reason for hiding this comment

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

If that's true, shouldn't it be

  sendPortCompleter.completeError(...);

maybe make it

  if (!sendPortCompleter.isCompleted) {
    sendPortCompleter.completeError(...);
    return;
  }
  throw ...("unexpected message: $message");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

if (!sendPortCompleter.isCompleted) {
sendPortCompleter.completeError(
IsolateSpawnException('Unable to spawn isolate: $message'));
return;
}
// This shouldn't happen.
throw IsolateSpawnException(
Copy link
Member

Choose a reason for hiding this comment

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

Not really related to spawning, is it? Maybe UnsupportedError

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed, per your other comment

"Internal error: unexpected message: '$message'");
}
};
final Isolate parentIsolate = Isolate.current;
final SendPort sendPort = receiver.sendPort;
try {
_nativeSpawn(() => _platformIsolateMain(parentIsolate, sendPort));
} on Object {
receiver.close();
rethrow;
}
return sendPortCompleter.future;
}

Future<R> _sendComputation<R>(
SendPort port, FutureOr<R> Function() computation) {
final int id = ++_nextId;
final Completer<R> resultCompleter = Completer<R>();
_pending[id] = resultCompleter;
port.send(_ComputationRequest(id, computation));
return resultCompleter.future;
}

void _safeSend(SendPort sendPort, int id, Object? result, Object? error,
Object? stackTrace) {
try {
sendPort.send(_ComputationResult(id, result, error, stackTrace));
} catch (sendError, sendStack) {
sendPort.send(_ComputationResult(id, null, sendError, sendStack));
}
}

void _platformIsolateMain(Isolate parentIsolate, SendPort sendPort) {
final RawReceivePort computationPort = RawReceivePort();
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to avoid repeated port creations (it's expensive, has to go to runtime, ...) - see comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

computationPort.handler = (_ComputationRequest? message) {
if (message == null) {
// The parent isolate has shutdown. Allow this isolate to shutdown.
computationPort.keepIsolateAlive = false;
return;
}

late final FutureOr<Object?> potentiallyAsyncResult;
try {
potentiallyAsyncResult = message.computation();
} catch (e, s) {
_safeSend(sendPort, message.id, null, e, s);
return;
}

if (potentiallyAsyncResult is Future<Object?>) {
potentiallyAsyncResult.then((Object? result) {
_safeSend(sendPort, message.id, result, null, null);
}, onError: (Object? e, Object? s) {
_safeSend(sendPort, message.id, null, e, s ?? StackTrace.empty);
});
} else {
_safeSend(sendPort, message.id, potentiallyAsyncResult, null, null);
}
};
Isolate.current.addOnExitListener(sendPort);
parentIsolate.addOnExitListener(computationPort.sendPort);
sendPort.send(_PlatformIsolateReadyMessage(computationPort.sendPort));
}

@Native<Void Function(Handle)>(symbol: 'PlatformIsolateNativeApi::Spawn')
external void _nativeSpawn(Function entryPoint);

/// Whether the current isolate is running on the platform thread.
final bool isRunningOnPlatformThread = _isRunningOnPlatformThread();

@Native<Bool Function()>(
symbol: 'PlatformIsolateNativeApi::IsRunningOnPlatformThread', isLeaf: true)
external bool _isRunningOnPlatformThread();

class _PlatformIsolateReadyMessage {
_PlatformIsolateReadyMessage(this.computationPort);

final SendPort computationPort;
}

class _ComputationRequest {
_ComputationRequest(this.id, this.computation);

final int id;
final FutureOr<Object?> Function() computation;
}

class _ComputationResult {
_ComputationResult(this.id, this.result, this.remoteError, this.remoteStack);

final int id;
final Object? result;
final Object? remoteError;
final Object? remoteStack;
}
9 changes: 8 additions & 1 deletion lib/ui/ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate' show SendPort;
import 'dart:isolate'
show
Isolate,
IsolateSpawnException,
RawReceivePort,
RemoteError,
SendPort;
import 'dart:math' as math;
import 'dart:nativewrappers';
import 'dart:typed_data';
Expand All @@ -35,6 +41,7 @@ part 'math.dart';
part 'natives.dart';
part 'painting.dart';
part 'platform_dispatcher.dart';
part 'platform_isolate.dart';
part 'plugins.dart';
part 'pointer.dart';
part 'semantics.dart';
Expand Down
6 changes: 6 additions & 0 deletions lib/ui/ui_dart_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,10 @@ int64_t UIDartState::GetRootIsolateToken() const {
return IsRootIsolate() ? reinterpret_cast<int64_t>(this) : 0;
}

Dart_Isolate UIDartState::CreatePlatformIsolate(Dart_Handle entry_point,
char** error) {
FML_UNREACHABLE();
return nullptr;
}

} // namespace flutter
3 changes: 3 additions & 0 deletions lib/ui/ui_dart_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ class UIDartState : public tonic::DartState {
/// The expected type for runtime stage shaders.
impeller::RuntimeStageBackend GetRuntimeStageBackend() const;

virtual Dart_Isolate CreatePlatformIsolate(Dart_Handle entry_point,
char** error);

protected:
UIDartState(TaskObserverAdd add_callback,
TaskObserverRemove remove_callback,
Expand Down
4 changes: 4 additions & 0 deletions lib/ui/window/platform_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace flutter {
class FontCollection;
class PlatformMessage;
class PlatformMessageHandler;
class PlatformIsolateManager;
class Scene;

//--------------------------------------------------------------------------
Expand Down Expand Up @@ -247,6 +248,9 @@ class PlatformConfigurationClient {
virtual double GetScaledFontSize(double unscaled_font_size,
int configuration_id) const = 0;

virtual std::shared_ptr<PlatformIsolateManager>
GetPlatformIsolateManager() = 0;

protected:
virtual ~PlatformConfigurationClient();
};
Expand Down
Loading