Chromium Code Reviews| Index: runtime/observatory/lib/src/service/object.dart |
| diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart |
| index fa73cf6266a6b429e6185147b7eab837fa8af9ef..b43a69903b32724af9e3fd66de208c4c89d636be 100644 |
| --- a/runtime/observatory/lib/src/service/object.dart |
| +++ b/runtime/observatory/lib/src/service/object.dart |
| @@ -1396,6 +1396,62 @@ class Isolate extends ServiceObjectOwner with Coverage { |
| return invokeRpc('resume', {'step': 'Out'}); |
| } |
| + /// result[0] completes after the inital resume. The UI should wait on this |
| + /// future because some other breakpoint may be hit before the async |
| + /// continuation. |
| + /// result[1] completes after the second resume. Tests should wait on this |
|
Cutch
2015/07/20 23:49:35
name these constants, e.g.:
result[0] -> result[kF
rmacnak
2015/07/21 17:35:36
Done.
|
| + /// future to avoid confusing the pause event at the state-machine switch |
| + /// with the pause event after the state-machine switch. |
| + List<Future> asyncStepOver() { |
| + Completer firstResume = new Completer(); |
| + Completer secondResume = new Completer(); |
| + var subscription; |
| + |
| + handleError(error) { |
| + if (subscription != null) { |
| + subscription.cancel(); |
| + subscription = null; |
| + } |
| + firstResume.completeError(error); |
| + secondResume.completeError(error); |
| + } |
| + |
| + if ((pauseEvent == null) || |
| + (pauseEvent.kind != ServiceEvent.kPauseBreakpoint) || |
| + (pauseEvent.asyncContinuation == null)) { |
| + handleError(new Exception("No async continuation available")); |
| + } else { |
| + Instance continuation = pauseEvent.asyncContinuation; |
| + assert(continuation.isClosure); |
| + addBreakOnActivation(continuation).then((Breakpoint continuationBpt) { |
| + isolate.vm.getEventStream(VM.kDebugStream).then((stream) { |
| + var onResume = firstResume; |
| + subscription = stream.listen((ServiceEvent event) { |
| + if ((event.kind == ServiceEvent.kPauseBreakpoint) && |
| + (event.breakpoint == continuationBpt)) { |
| + // We are stopped before state-machine dispatch; step-over to |
| + // reach user code. |
| + removeBreakpoint(continuationBpt).then((_) { |
| + onResume = secondResume; |
| + stepOver().catchError(handleError); |
| + }); |
| + } else if (event.kind == ServiceEvent.kResume) { |
| + if (onResume == secondResume) { |
| + subscription.cancel(); |
| + subscription = null; |
| + } |
|
Cutch
2015/07/20 23:49:35
else { assert(onResume == firstResume); } ?
rmacnak
2015/07/21 17:35:36
Switching to
if (onResume != null) {
|
| + onResume.complete(this); |
| + onResume = null; |
| + } |
| + }); |
| + this.resume().catchError(handleError); |
|
Cutch
2015/07/20 23:49:35
You use isolate. above, please be consistent with
rmacnak
2015/07/21 17:35:36
Done.
|
| + }).catchError(handleError); |
| + }).catchError(handleError); |
| + } |
| + |
| + return [firstResume.future, secondResume.future]; |
| + } |
| + |
| Future setName(String newName) { |
| return invokeRpc('setName', {'name': newName}); |
| } |