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

Side by Side Diff: pkg/scheduled_test/lib/scheduled_stream.dart

Issue 139363002: Reapply r31820 with a 'slow' status file marker. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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 | « pkg/pkgbuild.status ('k') | no next file » | 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 library scheduled_test.scheduled_stream; 5 library scheduled_test.scheduled_stream;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:stack_trace/stack_trace.dart'; 10 import 'package:stack_trace/stack_trace.dart';
(...skipping 22 matching lines...) Expand all
33 /// 33 ///
34 /// If this is non-null, [_pendingValues] will always be empty, since any 34 /// If this is non-null, [_pendingValues] will always be empty, since any
35 /// value coming in will be passed to this completer. 35 /// value coming in will be passed to this completer.
36 Completer<T> _nextCompleter; 36 Completer<T> _nextCompleter;
37 37
38 /// The completer for emitting a value requested by [hasNext]. 38 /// The completer for emitting a value requested by [hasNext].
39 Completer<bool> _hasNextCompleter; 39 Completer<bool> _hasNextCompleter;
40 40
41 /// The set of all streams forked from this one. 41 /// The set of all streams forked from this one.
42 final _forks = new Set<ScheduledStream<T>>(); 42 final _forks = new Set<ScheduledStream<T>>();
43 final _forkControllers = new Set<StreamController<T>>();
43 44
44 /// The queue of values emitted by [_stream] but not yet emitted through 45 /// The queue of values emitted by [_stream] but not yet emitted through
45 /// [next]. 46 /// [next].
46 final _pendingValues = new Queue<Fallible<T>>(); 47 final _pendingValues = new Queue<Fallible<T>>();
47 48
48 /// All values emitted by this stream so far. 49 /// All values emitted by this stream so far.
49 /// 50 ///
50 /// This does not include values emitted by the underlying stream but not yet 51 /// This does not include values emitted by the underlying stream but not yet
51 /// emitted through [next]. 52 /// emitted through [next].
52 List<T> get emittedValues => new UnmodifiableListView(_emittedValues); 53 List<T> get emittedValues => new UnmodifiableListView(_emittedValues);
(...skipping 12 matching lines...) Expand all
65 /// Whether the wrapped stream has been closed. 66 /// Whether the wrapped stream has been closed.
66 bool _isDone = false; 67 bool _isDone = false;
67 68
68 /// Whether [next] has been called but has not yet returned. 69 /// Whether [next] has been called but has not yet returned.
69 /// 70 ///
70 /// This is distinct from `_nextCompleter != null` when [next] is called while 71 /// This is distinct from `_nextCompleter != null` when [next] is called while
71 /// there are pending values available, until the future it returns completes. 72 /// there are pending values available, until the future it returns completes.
72 bool _isNextPending = false; 73 bool _isNextPending = false;
73 74
74 /// Creates a new scheduled stream wrapping [stream]. 75 /// Creates a new scheduled stream wrapping [stream].
75 ScheduledStream(Stream<T> stream) 76 ScheduledStream(this._stream) {
76 : _stream = stream.asBroadcastStream() {
77 _subscription = _stream.listen((value) { 77 _subscription = _stream.listen((value) {
78 for (var c in _forkControllers) {
79 c.add(value);
80 }
78 if (_hasNextCompleter != null) { 81 if (_hasNextCompleter != null) {
79 _hasNextCompleter.complete(true); 82 _hasNextCompleter.complete(true);
80 _hasNextCompleter = null; 83 _hasNextCompleter = null;
81 } 84 }
82 85
83 if (_nextCompleter != null) { 86 if (_nextCompleter != null) {
84 _nextCompleter.complete(value); 87 _nextCompleter.complete(value);
85 _emittedValues.add(value); 88 _emittedValues.add(value);
86 _nextCompleter = null; 89 _nextCompleter = null;
87 _isNextPending = false; 90 _isNextPending = false;
88 } else { 91 } else {
89 _pendingValues.add(new Fallible.withValue(value)); 92 _pendingValues.add(new Fallible.withValue(value));
90 } 93 }
91 }, onError: (error, stackTrace) { 94 }, onError: (error, stackTrace) {
95 for (var c in _forkControllers) {
96 c.addError(error, stackTrace);
97 }
92 if (_hasNextCompleter != null) { 98 if (_hasNextCompleter != null) {
93 _hasNextCompleter.completeError(error, stackTrace); 99 _hasNextCompleter.completeError(error, stackTrace);
94 _hasNextCompleter = null; 100 _hasNextCompleter = null;
95 } 101 }
96 102
97 if (_nextCompleter != null) { 103 if (_nextCompleter != null) {
98 _nextCompleter.completeError(error, stackTrace); 104 _nextCompleter.completeError(error, stackTrace);
99 _nextCompleter = null; 105 _nextCompleter = null;
100 } else { 106 } else {
101 _pendingValues.add(new Fallible.withError(error, stackTrace)); 107 _pendingValues.add(new Fallible.withError(error, stackTrace));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 /// closed at whatever point it's currently at. 204 /// closed at whatever point it's currently at.
199 ScheduledStream<T> fork() { 205 ScheduledStream<T> fork() {
200 var controller = new StreamController<T>(); 206 var controller = new StreamController<T>();
201 for (var valueOrError in _pendingValues) { 207 for (var valueOrError in _pendingValues) {
202 if (valueOrError.hasValue) { 208 if (valueOrError.hasValue) {
203 controller.add(valueOrError.value); 209 controller.add(valueOrError.value);
204 } else { 210 } else {
205 controller.addError(valueOrError.error, valueOrError.stackTrace); 211 controller.addError(valueOrError.error, valueOrError.stackTrace);
206 } 212 }
207 } 213 }
208
209 if (_isDone) { 214 if (_isDone) {
210 controller.close(); 215 controller.close();
211 } else { 216 } else {
212 _stream.pipe(controller); 217 _forkControllers.add(controller);
213 } 218 }
214 219
215 var fork = new ScheduledStream<T>(controller.stream); 220 var fork = new ScheduledStream<T>(controller.stream);
216 _forks.add(fork); 221 _forks.add(fork);
217 return fork; 222 return fork;
218 } 223 }
219 224
220 /// Closes this stream. 225 /// Closes this stream.
221 /// 226 ///
222 /// This cancels the subscription to the underlying stream and acts as though 227 /// This cancels the subscription to the underlying stream and acts as though
223 /// [this] was closed immediately after the current position, regardless of 228 /// [this] was closed immediately after the current position, regardless of
224 /// whether the underlying stream has emitted additional events. 229 /// whether the underlying stream has emitted additional events.
225 void close() { 230 void close() {
226 _subscription.cancel(); 231 _subscription.cancel();
227 _pendingValues.clear(); 232 _pendingValues.clear();
228 233
229 for (var fork in _forks) { 234 for (var fork in _forks) {
230 fork.close(); 235 fork.close();
231 } 236 }
232 _forks.clear(); 237 _forks.clear();
233 238
234 if (!_isDone) _onDone(); 239 if (!_isDone) _onDone();
235 } 240 }
236 241
237 /// Handles a "done" event from the underlying stream, as well as [this] being 242 /// Handles a "done" event from the underlying stream, as well as [this] being
238 /// closed. 243 /// closed.
239 void _onDone() { 244 void _onDone() {
245 for (var c in _forkControllers) {
246 c.close();
247 }
248 _forkControllers.clear();
249
240 if (_hasNextCompleter != null) { 250 if (_hasNextCompleter != null) {
241 _hasNextCompleter.complete(false); 251 _hasNextCompleter.complete(false);
242 _hasNextCompleter = null; 252 _hasNextCompleter = null;
243 } 253 }
244 254
245 if (_nextCompleter != null) { 255 if (_nextCompleter != null) {
246 _nextCompleter.completeError( 256 _nextCompleter.completeError(
247 new StateError("ScheduledStream has no more elements."), 257 new StateError("ScheduledStream has no more elements."),
248 new Chain.current()); 258 new Chain.current());
249 _nextCompleter = null; 259 _nextCompleter = null;
250 _isNextPending = false; 260 _isNextPending = false;
251 } 261 }
252 262
253 _isDone = true; 263 _isDone = true;
254 } 264 }
255 } 265 }
OLDNEW
« no previous file with comments | « pkg/pkgbuild.status ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698