blob: 416a3a6e3e874e43425b70a56d4641bce2fe4fe3 [file] [log] [blame] [edit]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Root-zone and its implementation of zone features.
part of 'dart:async';
const _Zone _rootZone = _RootZone();
void _rootHandleUncaughtError(
Zone? self,
ZoneDelegate? parent,
Zone zone,
Object error,
StackTrace stackTrace,
) {
_rootHandleError(error, stackTrace);
}
void _rootHandleError(Object error, StackTrace stackTrace) {
_schedulePriorityAsyncCallback(() {
Error.throwWithStackTrace(error, stackTrace);
});
}
R _rootRun<R>(Zone? self, ZoneDelegate? parent, Zone zone, R f()) {
if (identical(Zone._current, zone)) return f();
if (zone is! _Zone) {
throw ArgumentError.value(zone, "zone", "Can only run in platform zones");
}
_Zone old = Zone._enter(zone);
try {
return f();
} finally {
Zone._leave(old);
}
}
R _rootRunUnary<R, T>(
Zone? self,
ZoneDelegate? parent,
Zone zone,
R f(T arg),
T arg,
) {
if (identical(Zone._current, zone)) return f(arg);
if (zone is! _Zone) {
throw ArgumentError.value(zone, "zone", "Can only run in platform zones");
}
_Zone old = Zone._enter(zone);
try {
return f(arg);
} finally {
Zone._leave(old);
}
}
R _rootRunBinary<R, T1, T2>(
Zone? self,
ZoneDelegate? parent,
Zone zone,
R f(T1 arg1, T2 arg2),
T1 arg1,
T2 arg2,
) {
if (identical(Zone._current, zone)) return f(arg1, arg2);
if (zone is! _Zone) {
throw ArgumentError.value(zone, "zone", "Can only run in platform zones");
}
_Zone old = Zone._enter(zone);
try {
return f(arg1, arg2);
} finally {
Zone._leave(old);
}
}
ZoneCallback<R> _rootRegisterCallback<R>(
Zone self,
ZoneDelegate parent,
Zone zone,
R f(),
) {
return f;
}
ZoneUnaryCallback<R, T> _rootRegisterUnaryCallback<R, T>(
Zone self,
ZoneDelegate parent,
Zone zone,
R f(T arg),
) {
return f;
}
ZoneBinaryCallback<R, T1, T2> _rootRegisterBinaryCallback<R, T1, T2>(
Zone self,
ZoneDelegate parent,
Zone zone,
R f(T1 arg1, T2 arg2),
) {
return f;
}
AsyncError? _rootErrorCallback(
Zone self,
ZoneDelegate parent,
Zone zone,
Object error,
StackTrace? stackTrace,
) => null;
void _rootScheduleMicrotask(
Zone? self,
ZoneDelegate? parent,
Zone zone,
void f(),
) {
if (!identical(_rootZone, zone)) {
bool hasErrorHandler = !_rootZone.inSameErrorZone(zone);
if (hasErrorHandler) {
f = zone.bindCallbackGuarded(f);
} else {
f = zone.bindCallback(f);
}
}
_scheduleAsyncCallback(f);
}
Timer _rootCreateTimer(
Zone self,
ZoneDelegate parent,
Zone zone,
Duration duration,
void Function() callback,
) {
if (!identical(_rootZone, zone)) {
callback = zone.bindCallback(callback);
}
return Timer._createTimer(duration, callback);
}
Timer _rootCreatePeriodicTimer(
Zone self,
ZoneDelegate parent,
Zone zone,
Duration duration,
void callback(Timer timer),
) {
if (!identical(_rootZone, zone)) {
callback = zone.bindUnaryCallback<void, Timer>(callback);
}
return Timer._createPeriodicTimer(duration, callback);
}
void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) {
printToConsole(line);
}
void _printToZone(String line) {
Zone.current.print(line);
}
Zone _rootFork(
Zone? self,
ZoneDelegate? parent,
Zone zone,
ZoneSpecification? specification,
Map<Object?, Object?>? zoneValues,
) {
if (zone is! _Zone) {
throw ArgumentError.value(zone, "zone", "Can only fork a platform zone");
}
// TODO(floitsch): it would be nice if we could get rid of this hack.
// Change the static zoneOrDirectPrint function to go through zones
// from now on.
printToZone = _printToZone;
if (specification == null) {
specification = const ZoneSpecification();
} else if (specification is! _ZoneSpecification) {
specification = ZoneSpecification.from(specification);
}
Map<Object?, Object?> valueMap;
if (zoneValues == null) {
valueMap = zone._map;
} else {
valueMap = HashMap<Object?, Object?>.from(zoneValues);
}
if (specification == null)
throw "unreachable"; // TODO(lrn): Remove when type promotion works.
return _CustomZone(zone, specification, valueMap);
}