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

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') | no next file with comments »
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) && !cancellationCompleter.isCompleted) {
98 // If the stream has been cancelled, complete the cancellation future
99 // with the error.
100 cancellationCompleter.completeError(error, stackTrace);
101 return;
102 }
96 // If stream is cancelled, tell caller to exit the async generator. 103 // If stream is cancelled, tell caller to exit the async generator.
97 if (!controller.hasListener) return; 104 if (!controller.hasListener) return;
98 controller.addError(error, stackTrace); 105 controller.addError(error, stackTrace);
99 // No need to schedule the generator body here. This code is only 106 // No need to schedule the generator body here. This code is only
100 // called from the catch clause of the implicit try-catch-finally 107 // 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 108 // 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. 109 // of the generator and do not need to run the generator again.
103 } 110 }
104 111
105 close() { 112 close() {
113 if ((cancellationCompleter != null) && !cancellationCompleter.isCompleted) {
114 // If the stream has been cancelled, complete the cancellation future
115 // with the error.
116 cancellationCompleter.complete();
117 }
106 controller.close(); 118 controller.close();
107 } 119 }
108 120
109 _AsyncStarStreamController(this.asyncStarBody) { 121 _AsyncStarStreamController(this.asyncStarBody) {
110 controller = new StreamController(onListen: this.onListen, 122 controller = new StreamController(onListen: this.onListen,
111 onResume: this.onResume, 123 onResume: this.onResume,
112 onCancel: this.onCancel); 124 onCancel: this.onCancel);
113 } 125 }
114 126
115 onListen() { 127 onListen() {
116 assert(!onListenReceived); 128 assert(!onListenReceived);
117 onListenReceived = true; 129 onListenReceived = true;
118 scheduleGenerator(); 130 scheduleGenerator();
119 } 131 }
120 132
121 onResume() { 133 onResume() {
122 scheduleGenerator(); 134 scheduleGenerator();
123 } 135 }
124 136
125 onCancel() { 137 onCancel() {
126 scheduleGenerator(); 138 if (controller.isClosed) {
139 return null;
140 }
141 if (cancellationCompleter == null) {
142 cancellationCompleter = new Completer();
143 scheduleGenerator();
144 }
145 return cancellationCompleter.future;
127 } 146 }
128 } 147 }
129 148
130 149
131 // _SyncIterable and _syncIterator are used by the compiler to 150 // _SyncIterable and _syncIterator are used by the compiler to
132 // implement sync* generator functions. A sync* generator allocates 151 // implement sync* generator functions. A sync* generator allocates
133 // and returns a new _SyncIterable object. 152 // and returns a new _SyncIterable object.
134 153
135 typedef bool SyncGeneratorCallback(Iterator iterator); 154 typedef bool SyncGeneratorCallback(Iterator iterator);
136 155
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 if (isYieldEach) { 193 if (isYieldEach) {
175 // Spec mandates: it is a dynamic error if the class of [the object 194 // Spec mandates: it is a dynamic error if the class of [the object
176 // returned by yield*] does not implement Iterable. 195 // returned by yield*] does not implement Iterable.
177 yieldEachIterator = (current as Iterable).iterator; 196 yieldEachIterator = (current as Iterable).iterator;
178 continue; 197 continue;
179 } 198 }
180 return true; 199 return true;
181 } 200 }
182 } 201 }
183 } 202 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698