Skip to content

Commit

Permalink
fix coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe committed Nov 7, 2024
1 parent 0867e0f commit 7f57739
Showing 1 changed file with 12 additions and 47 deletions.
59 changes: 12 additions & 47 deletions pkgs/coverage/lib/src/isolate_paused_listener.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ typedef SyncErrorLogger = void Function(String message);
/// Calls onIsolatePaused whenever an isolate reaches the pause-on-exit state,
/// and passes a flag stating whether that isolate is the last one in the group.
class IsolatePausedListener {
IsolatePausedListener(this._service, this._onIsolatePaused, this._log) {
_service.onDone.then((_) => _log("\n###################\nservice done\n###################\n"));
}
IsolatePausedListener(this._service, this._onIsolatePaused, this._log);

final VmService _service;
final AsyncIsolatePausedCallback _onIsolatePaused;
Expand All @@ -40,25 +38,19 @@ class IsolatePausedListener {
/// Starts listening and returns a future that completes when all isolates
/// have exited.
Future<void> waitUntilAllExited() async {
_log("\n\nIsolatePausedListener listenToIsolateLifecycleEvents");
await listenToIsolateLifecycleEvents(_service, _onStart, _onPause, _onExit);

_log("\n\nIsolatePausedListener _allNonMainIsolatesExited");
await _allNonMainIsolatesExited.future;

// Resume the main isolate.
_log("\n\nIsolatePausedListener waiting done");
try {
_log("\n\nIsolatePausedListener resume main? $_mainIsolate");
if (_mainIsolate != null) {
_log("\n\nIsolatePausedListener waiting for main to pause");
if (await _mainIsolatePaused.future) {
_log("\n\nIsolatePausedListener collect and resume main");
await _runCallbackAndResume(_mainIsolate!, true);
await _runCallbackAndResume(
_mainIsolate!, !_getGroup(_mainIsolate!).collected);
}
}
} finally {
_log("\n\nIsolatePausedListener _finished = true");
_finished = true;
}
}
Expand All @@ -67,98 +59,71 @@ class IsolatePausedListener {
_isolateGroups[isolateRef.isolateGroupId!] ??= IsolateGroupState();

void _onStart(IsolateRef isolateRef) {
_log("IsolatePausedListener _onStart $isolateRef");
if (_finished) {
_log("IsolatePausedListener _onStart $isolateRef already finished");
return;
}
if (_finished) return;
final group = _getGroup(isolateRef);
group.start(isolateRef.id!);
if (_mainIsolate == null && _isMainIsolate(isolateRef)) {
_log("IsolatePausedListener _onStart $isolateRef is main");
_mainIsolate = isolateRef;
} else {
++_numNonMainIsolates;
_log("IsolatePausedListener _onStart $isolateRef is not main: $_numNonMainIsolates");
}
_log("IsolatePausedListener _onStart $isolateRef done");
}

Future<void> _onPause(IsolateRef isolateRef) async {
_log("IsolatePausedListener _onPause $isolateRef");
if (_finished) {
_log("IsolatePausedListener _onPause $isolateRef already finished");
return;
}
if (_finished) return;
final group = _getGroup(isolateRef);
group.pause(isolateRef.id!);
if (isolateRef.id! == _mainIsolate?.id) {
_log("IsolatePausedListener _onPause $isolateRef is main");
_mainIsolatePaused.complete(true);

// If the main isolate is the only isolate, then _allNonMainIsolatesExited
// will never be completed. So check that case here.
_checkCompleted();
} else {
_log("IsolatePausedListener _onPause $isolateRef collect and resume");
await _runCallbackAndResume(isolateRef, group.noRunningIsolates);
}
_log("IsolatePausedListener _onPause $isolateRef done");
}

Future<void> _runCallbackAndResume(
IsolateRef isolateRef, bool isLastIsolateInGroup) async {
_log("IsolatePausedListener _runCallbackAndResume $isolateRef $isLastIsolateInGroup");
if (isLastIsolateInGroup) {
_log("IsolatePausedListener _runCallbackAndResume $isolateRef group.collected");
_getGroup(isolateRef).collected = true;
}
try {
_log("IsolatePausedListener _runCallbackAndResume $isolateRef running callback");
await _onIsolatePaused(isolateRef, isLastIsolateInGroup);
} finally {
_log("IsolatePausedListener _runCallbackAndResume $isolateRef resuming isolate");
await _service.resume(isolateRef.id!);
}
_log("IsolatePausedListener _runCallbackAndResume $isolateRef done");
}

void _onExit(IsolateRef isolateRef) {
_log("IsolatePausedListener _onExit $isolateRef");
if (_finished) {
_log("IsolatePausedListener _onExit $isolateRef already finished");
return;
}
if (_finished) return;
final group = _getGroup(isolateRef);
group.exit(isolateRef.id!);
_log("IsolatePausedListener _onExit $isolateRef ${group.noLiveIsolates} ${group.collected}");
if (group.noLiveIsolates && !group.collected) {
_log('ERROR: An isolate exited without pausing, causing '
'coverage data to be lost for group ${isolateRef.isolateGroupId!}.');
}
_log("IsolatePausedListener _onExit $isolateRef ${isolateRef.id} ${_mainIsolate?.id}");
if (isolateRef.id! == _mainIsolate?.id) {
_log("IsolatePausedListener _onExit $isolateRef is main");
if (!_mainIsolatePaused.isCompleted) {
_log("IsolatePausedListener _onExit $isolateRef Main isolate exited without pausing");
// Main isolate exited without pausing.
_mainIsolatePaused.complete(false);
}
} else {
--_numNonMainIsolates;
_log("IsolatePausedListener _onExit $isolateRef is not main $_numNonMainIsolates");
_checkCompleted();
}
_log("IsolatePausedListener _onExit $isolateRef done");
}

bool get _mainRunning =>
_mainIsolate != null && !_mainIsolatePaused.isCompleted;

void _checkCompleted() {
_log("IsolatePausedListener _checkCompleted $_numNonMainIsolates ${_mainIsolatePaused.isCompleted} ${_allNonMainIsolatesExited.isCompleted}");
if (_numNonMainIsolates == 0 && _mainIsolatePaused.isCompleted && !_allNonMainIsolatesExited.isCompleted) {
_log("IsolatePausedListener _checkCompleted _allNonMainIsolatesExited.complete()");
if (_numNonMainIsolates == 0 &&
!_mainRunning &&
!_allNonMainIsolatesExited.isCompleted) {
_allNonMainIsolatesExited.complete();
}
_log("IsolatePausedListener _checkCompleted done");
}

static bool _isMainIsolate(IsolateRef isolateRef) {
Expand Down

0 comments on commit 7f57739

Please sign in to comment.