Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/js_helper.dart

Issue 1026743002: Fix cancel behaviour of async* in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rename test, update status file Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library _js_helper; 5 library _js_helper;
6 6
7 import 'dart:_async_await_error_codes' as async_error_codes; 7 import 'dart:_async_await_error_codes' as async_error_codes;
8 8
9 import 'dart:_js_embedded_names' show 9 import 'dart:_js_embedded_names' show
10 DEFERRED_LIBRARY_URIS, 10 DEFERRED_LIBRARY_URIS,
(...skipping 3667 matching lines...) Expand 10 before | Expand all | Expand 10 after
3678 /// If the async* function wants to do an await it calls this function with 3678 /// If the async* function wants to do an await it calls this function with
3679 /// [object] not and [IterationMarker]. 3679 /// [object] not and [IterationMarker].
3680 /// 3680 ///
3681 /// If [object] is not a [Future], it is wrapped in a `Future.value`. 3681 /// If [object] is not a [Future], it is wrapped in a `Future.value`.
3682 /// The [asyncBody] is called on completion of the future (see [asyncHelper]. 3682 /// The [asyncBody] is called on completion of the future (see [asyncHelper].
3683 void asyncStarHelper(dynamic object, 3683 void asyncStarHelper(dynamic object,
3684 dynamic /* int | js function */ bodyFunctionOrErrorCode, 3684 dynamic /* int | js function */ bodyFunctionOrErrorCode,
3685 AsyncStarStreamController controller) { 3685 AsyncStarStreamController controller) {
3686 if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) { 3686 if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) {
3687 // This happens on return from the async* function. 3687 // This happens on return from the async* function.
3688 controller.close(); 3688 if (controller.cancelationCompleter != null) {
3689 controller.cancelationCompleter.complete();
3690 } else {
3691 controller.close();
3692 }
3689 return; 3693 return;
3690 } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { 3694 } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
3691 // The error is a js-error. 3695 // The error is a js-error.
3692 controller.addError(unwrapException(object), 3696 if (controller.cancelationCompleter != null) {
3693 getTraceFromException(object)); 3697 controller.cancelationCompleter.completeError(
3694 controller.close(); 3698 unwrapException(object),
3699 getTraceFromException(object));
3700 } else {
3701 controller.addError(unwrapException(object),
3702 getTraceFromException(object));
3703 controller.close();
3704 }
3695 return; 3705 return;
3696 } 3706 }
3697 3707
3698 if (object is IterationMarker) { 3708 if (object is IterationMarker) {
3699 if (controller.stopRunning) { 3709 if (controller.cancelationCompleter != null) {
3700 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3710 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3701 async_error_codes.STREAM_WAS_CANCELED)(null); 3711 async_error_codes.STREAM_WAS_CANCELED)(null);
3702 return; 3712 return;
3703 } 3713 }
3704 if (object.state == IterationMarker.YIELD_SINGLE) { 3714 if (object.state == IterationMarker.YIELD_SINGLE) {
3705 controller.add(object.value); 3715 controller.add(object.value);
3706 // If the controller is paused we stop producing more values. 3716 // If the controller is paused we stop producing more values.
3707 if (controller.isPaused) { 3717 if (controller.isPaused) {
3708 return; 3718 return;
3709 } 3719 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3746 } 3756 }
3747 3757
3748 /// A wrapper around a [StreamController] that remembers if that controller 3758 /// A wrapper around a [StreamController] that remembers if that controller
3749 /// got a cancel. 3759 /// got a cancel.
3750 /// 3760 ///
3751 /// Also has a subSubscription that when not null will provide events for the 3761 /// Also has a subSubscription that when not null will provide events for the
3752 /// stream, and will be paused and resumed along with this controller. 3762 /// stream, and will be paused and resumed along with this controller.
3753 class AsyncStarStreamController { 3763 class AsyncStarStreamController {
3754 StreamController controller; 3764 StreamController controller;
3755 Stream get stream => controller.stream; 3765 Stream get stream => controller.stream;
3756 bool stopRunning = false; 3766 Completer cancelationCompleter = null;
3767 bool get isCanceled => cancelationCompleter != null;
3757 bool isAdding = false; 3768 bool isAdding = false;
3758 bool isPaused = false; 3769 bool isPaused = false;
3759 add(event) => controller.add(event); 3770 add(event) => controller.add(event);
3760 addStream(Stream stream) { 3771 addStream(Stream stream) {
3761 return controller.addStream(stream, cancelOnError: false); 3772 return controller.addStream(stream, cancelOnError: false);
3762 } 3773 }
3763 addError(error, stackTrace) => controller.addError(error, stackTrace); 3774 addError(error, stackTrace) => controller.addError(error, stackTrace);
3764 close() => controller.close(); 3775 close() => controller.close();
3765 3776
3766 AsyncStarStreamController(body) { 3777 AsyncStarStreamController(body) {
3767 controller = new StreamController( 3778 controller = new StreamController(
3768 onListen: () { 3779 onListen: () {
3769 scheduleMicrotask(() { 3780 scheduleMicrotask(() {
3770 Function wrapped = _wrapJsFunctionForAsync(body, 3781 Function wrapped = _wrapJsFunctionForAsync(body,
3771 async_error_codes.SUCCESS); 3782 async_error_codes.SUCCESS);
3772 wrapped(null); 3783 wrapped(null);
3773 }); 3784 });
3774 }, 3785 },
3775 onPause: () { 3786 onPause: () {
3776 isPaused = true; 3787 isPaused = true;
3777 }, onResume: () { 3788 }, onResume: () {
3778 isPaused = false; 3789 isPaused = false;
3779 if (!isAdding) { 3790 if (!isAdding) {
3780 asyncStarHelper(null, body, this); 3791 asyncStarHelper(null, body, this);
3781 } 3792 }
3782 }, onCancel: () { 3793 }, onCancel: () {
3783 stopRunning = true; 3794 if (!controller.isClosed) {
3784 if (isPaused) asyncStarHelper(null, body, this); 3795 cancelationCompleter = new Completer();
3796 if (isPaused) asyncStarHelper(null, body, this);
3797
3798 return cancelationCompleter.future;
3799 }
3785 }); 3800 });
3786 } 3801 }
3787 } 3802 }
3788 3803
3789 makeAsyncStarController(body) { 3804 makeAsyncStarController(body) {
3790 return new AsyncStarStreamController(body); 3805 return new AsyncStarStreamController(body);
3791 } 3806 }
3792 3807
3793 class IterationMarker { 3808 class IterationMarker {
3794 static const YIELD_SINGLE = 0; 3809 static const YIELD_SINGLE = 0;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3888 // This is a function that will return a helper function that does the 3903 // This is a function that will return a helper function that does the
3889 // iteration of the sync*. 3904 // iteration of the sync*.
3890 // 3905 //
3891 // Each invocation should give a body with fresh state. 3906 // Each invocation should give a body with fresh state.
3892 final dynamic /* js function */ _outerHelper; 3907 final dynamic /* js function */ _outerHelper;
3893 3908
3894 SyncStarIterable(this._outerHelper); 3909 SyncStarIterable(this._outerHelper);
3895 3910
3896 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); 3911 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper));
3897 } 3912 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698