compute<Q, R> function
The dart:io implementation of isolate.compute
.
Implementation
Future<R> compute<Q, R>(ComputeCallback<Q, R> callback, Q message,
{String? debugLabel}) async {
debugLabel ??=
bool.fromEnvironment('dart.vm.product') ? 'compute' : callback.toString();
final Flow flow = Flow.begin();
Timeline.startSync('$debugLabel: start', flow: flow);
final RawReceivePort port = RawReceivePort();
Timeline.finishSync();
void timeEndAndCleanup() {
Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id));
port.close();
Timeline.finishSync();
}
final Completer<dynamic> completer = Completer<dynamic>();
port.handler = (dynamic msg) {
timeEndAndCleanup();
completer.complete(msg);
};
try {
await Isolate.spawn<_IsolateConfiguration<Q, R>>(
_spawn,
_IsolateConfiguration<Q, R>(
callback,
message,
port.sendPort,
debugLabel,
flow.id,
),
onExit: port.sendPort,
onError: port.sendPort,
debugName: debugLabel,
);
} on Object {
timeEndAndCleanup();
rethrow;
}
final dynamic response = await completer.future;
if (response == null) {
throw RemoteError('Isolate exited without result or error.', '');
}
assert(response is List<dynamic>);
response as List<dynamic>;
final int type = response.length;
assert(1 <= type && type <= 3);
switch (type) {
// success; see _buildSuccessResponse
case 1:
return response[0] as R;
// native error; see Isolate.addErrorListener
case 2:
await Future<Never>.error(RemoteError(
response[0] as String,
response[1] as String,
));
// caught error; see _buildErrorResponse
case 3:
default:
assert(type == 3 && response[2] == null);
await Future<Never>.error(
response[0] as Object,
response[1] as StackTrace,
);
}
}