@@ -625,68 +625,12 @@ class HotRunner extends ResidentRunner {
625625 device.generator! .accept ();
626626 }
627627 }
628- // Check if the isolate is paused and resume it.
629628 final List <Future <void >> operations = < Future <void >> [];
630629 for (final FlutterDevice ? device in flutterDevices) {
631- final Set <String ?> uiIsolatesIds = < String ? > {};
632- final List <FlutterView > views = await device! .vmService! .getFlutterViews ();
633- for (final FlutterView view in views) {
634- if (view.uiIsolate == null ) {
635- continue ;
636- }
637- uiIsolatesIds.add (view.uiIsolate! .id);
638- // Reload the isolate.
639- final Future <vm_service.Isolate ?> reloadIsolate = device.vmService! .getIsolateOrNull (
640- view.uiIsolate! .id! ,
641- );
642- operations.add (
643- reloadIsolate.then ((vm_service.Isolate ? isolate) async {
644- if (isolate != null ) {
645- // The embedder requires that the isolate is unpaused, because the
646- // runInView method requires interaction with dart engine APIs that
647- // are not thread-safe, and thus must be run on the same thread that
648- // would be blocked by the pause. Simply un-pausing is not sufficient,
649- // because this does not prevent the isolate from immediately hitting
650- // a breakpoint (for example if the breakpoint was placed in a loop
651- // or in a frequently called method) or an exception. Instead, all
652- // breakpoints are first disabled and exception pause mode set to
653- // None, and then the isolate resumed.
654- // These settings do not need restoring as Hot Restart results in
655- // new isolates, which will be configured by the editor as they are
656- // started.
657- final List <Future <void >> breakpointAndExceptionRemoval = < Future <void >> [
658- device.vmService! .service.setIsolatePauseMode (
659- isolate.id! ,
660- exceptionPauseMode: vm_service.ExceptionPauseMode .kNone,
661- ),
662- for (final vm_service.Breakpoint breakpoint in isolate.breakpoints! )
663- device.vmService! .service.removeBreakpoint (isolate.id! , breakpoint.id! ),
664- ];
665- await Future .wait (breakpointAndExceptionRemoval);
666- if (isPauseEvent (isolate.pauseEvent! .kind! )) {
667- await device.vmService! .service.resume (view.uiIsolate! .id! );
668- }
669- }
670- }),
671- );
672- }
673-
674- // Wait for the UI isolates to have their breakpoints removed and exception pause mode
675- // cleared while also ensuring the isolate's are no longer paused. If we don't clear
676- // the exception pause mode before we start killing child isolates, it's possible that
677- // any UI isolate waiting on a result from a child isolate could throw an unhandled
678- // exception and re-pause the isolate, causing hot restart to hang.
679- await Future .wait (operations);
680- operations.clear ();
681-
682- // The engine handles killing and recreating isolates that it has spawned
683- // ("uiIsolates"). The isolates that were spawned from these uiIsolates
684- // will not be restarted, and so they must be manually killed.
685- final vm_service.VM vm = await device.vmService! .service.getVM ();
630+ // Explicitly kill all the isolates in the application, otherwise we need to account for
631+ // special cases that the engine can't handle (e.g., paused isolates, infinite loops, etc.).
632+ final vm_service.VM vm = await device! .vmService! .service.getVM ();
686633 for (final vm_service.IsolateRef isolateRef in vm.isolates! ) {
687- if (uiIsolatesIds.contains (isolateRef.id)) {
688- continue ;
689- }
690634 operations.add (
691635 device.vmService! .service
692636 .kill (isolateRef.id! )
0 commit comments