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

Side by Side Diff: runtime/lib/core_patch.dart

Issue 1014273003: Make await for cancel the stream when breaking out of the loop (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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
« no previous file with comments | « no previous file | runtime/vm/ast.h » ('j') | runtime/vm/parser.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 import "dart:math"; 5 import "dart:math";
6 import "dart:typed_data"; 6 import "dart:typed_data";
7 7
8 // Equivalent of calling FATAL from C++ code. 8 // Equivalent of calling FATAL from C++ code.
9 _fatal(msg) native "DartCore_fatal"; 9 _fatal(msg) native "DartCore_fatal";
10 10
(...skipping 18 matching lines...) Expand all
29 29
30 30
31 // _AsyncStarStreamController is used by the compiler to implement 31 // _AsyncStarStreamController is used by the compiler to implement
32 // async* generator functions. 32 // async* generator functions.
33 class _AsyncStarStreamController { 33 class _AsyncStarStreamController {
34 StreamController controller; 34 StreamController controller;
35 Function asyncStarBody; 35 Function asyncStarBody;
36 bool isAdding = false; 36 bool isAdding = false;
37 bool onListenReceived = false; 37 bool onListenReceived = false;
38 bool isScheduled = false; 38 bool isScheduled = false;
39 Completer cancellationCompleter = null;
39 40
40 Stream get stream => controller.stream; 41 Stream get stream => controller.stream;
41 42
42 void runBody() { 43 void runBody() {
43 isScheduled = false; 44 isScheduled = false;
44 asyncStarBody(); 45 asyncStarBody();
45 } 46 }
46 47
47 void scheduleGenerator() { 48 void scheduleGenerator() {
48 if (isScheduled || controller.isPaused || isAdding) { 49 if (isScheduled || controller.isPaused || isAdding) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 var whenDoneAdding = 87 var whenDoneAdding =
87 controller.addStream(stream as Stream, cancelOnError: false); 88 controller.addStream(stream as Stream, cancelOnError: false);
88 whenDoneAdding.then((_) { 89 whenDoneAdding.then((_) {
89 isAdding = false; 90 isAdding = false;
90 scheduleGenerator(); 91 scheduleGenerator();
91 }); 92 });
92 return false; 93 return false;
93 } 94 }
94 95
95 void addError(error, stackTrace) { 96 void addError(error, stackTrace) {
97 if ((cancellationCompleter != null &&
regis 2015/03/24 23:46:27 Redundant pair of parenthesis
hausner 2015/03/24 23:57:29 Done.
98 !cancellationCompleter.isCompleted)) {
99 // If the stream has been cancelled, complete the cancellation future
100 // with the error.
101 cancellationCompleter.completeError(error, stackTrace);
102 return;
103 }
96 // If stream is cancelled, tell caller to exit the async generator. 104 // If stream is cancelled, tell caller to exit the async generator.
97 if (!controller.hasListener) return; 105 if (!controller.hasListener) return;
98 controller.addError(error, stackTrace); 106 controller.addError(error, stackTrace);
99 // No need to schedule the generator body here. This code is only 107 // No need to schedule the generator body here. This code is only
100 // called from the catch clause of the implicit try-catch-finally 108 // called from the catch clause of the implicit try-catch-finally
101 // around the generator body. That is, we are on the error path out 109 // around the generator body. That is, we are on the error path out
102 // of the generator and do not need to run the generator again. 110 // of the generator and do not need to run the generator again.
103 } 111 }
104 112
105 close() { 113 close() {
114 if ((cancellationCompleter != null) &&
regis 2015/03/24 23:46:27 ditto
hausner 2015/03/24 23:57:29 This one actually had the closing paren in the rig
115 !cancellationCompleter.isCompleted) {
116 // If the stream has been cancelled, complete the cancellation future
117 // with the error.
118 cancellationCompleter.complete();
119 }
106 controller.close(); 120 controller.close();
107 } 121 }
108 122
109 _AsyncStarStreamController(this.asyncStarBody) { 123 _AsyncStarStreamController(this.asyncStarBody) {
110 controller = new StreamController(onListen: this.onListen, 124 controller = new StreamController(onListen: this.onListen,
111 onResume: this.onResume, 125 onResume: this.onResume,
112 onCancel: this.onCancel); 126 onCancel: this.onCancel);
113 } 127 }
114 128
115 onListen() { 129 onListen() {
116 assert(!onListenReceived); 130 assert(!onListenReceived);
117 onListenReceived = true; 131 onListenReceived = true;
118 scheduleGenerator(); 132 scheduleGenerator();
119 } 133 }
120 134
121 onResume() { 135 onResume() {
122 scheduleGenerator(); 136 scheduleGenerator();
123 } 137 }
124 138
125 onCancel() { 139 onCancel() {
126 scheduleGenerator(); 140 if (controller.isClosed) {
141 return null;
142 }
143 if (cancellationCompleter == null) {
144 cancellationCompleter = new Completer();
145 scheduleGenerator();
146 }
147 return cancellationCompleter.future;
127 } 148 }
128 } 149 }
129 150
130 151
131 // _SyncIterable and _syncIterator are used by the compiler to 152 // _SyncIterable and _syncIterator are used by the compiler to
132 // implement sync* generator functions. A sync* generator allocates 153 // implement sync* generator functions. A sync* generator allocates
133 // and returns a new _SyncIterable object. 154 // and returns a new _SyncIterable object.
134 155
135 typedef bool SyncGeneratorCallback(Iterator iterator); 156 typedef bool SyncGeneratorCallback(Iterator iterator);
136 157
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 if (isYieldEach) { 195 if (isYieldEach) {
175 // Spec mandates: it is a dynamic error if the class of [the object 196 // Spec mandates: it is a dynamic error if the class of [the object
176 // returned by yield*] does not implement Iterable. 197 // returned by yield*] does not implement Iterable.
177 yieldEachIterator = (current as Iterable).iterator; 198 yieldEachIterator = (current as Iterable).iterator;
178 continue; 199 continue;
179 } 200 }
180 return true; 201 return true;
181 } 202 }
182 } 203 }
183 } 204 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/ast.h » ('j') | runtime/vm/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698