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

Side by Side Diff: sdk/lib/async/stream_impl.dart

Issue 15864007: Add zone support to streams. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Upload Created 7 years, 6 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 | « sdk/lib/async/stream_controller.dart ('k') | sdk/lib/async/zone.dart » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of dart.async; 5 part of dart.async;
6 6
7 /** Throws the given error in the next cycle. */
8 _throwDelayed(var error, [Object stackTrace]) {
9 // We are going to reach the top-level here, but there might be a global
10 // exception handler. This means that we shouldn't print the stack trace.
11 // TODO(floitsch): Find better solution that doesn't print the stack trace
12 // if there is a global exception handler.
13 runAsync(() {
14 if (stackTrace != null) print(stackTrace);
15 var trace = getAttachedStackTrace(error);
16 if (trace != null && trace != stackTrace) print(trace);
17 throw error;
18 });
19 }
20
21 /** Abstract and private interface for a place to put events. */ 7 /** Abstract and private interface for a place to put events. */
22 abstract class _EventSink<T> { 8 abstract class _EventSink<T> {
23 void _add(T data); 9 void _add(T data);
24 void _addError(Object error); 10 void _addError(Object error);
25 void _close(); 11 void _close();
26 } 12 }
27 13
28 /** 14 /**
29 * Abstract and private interface for a place to send events. 15 * Abstract and private interface for a place to send events.
30 * 16 *
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 static const int _STATE_HAS_PENDING = 32; 75 static const int _STATE_HAS_PENDING = 32;
90 static const int _STATE_PAUSE_COUNT = 64; 76 static const int _STATE_PAUSE_COUNT = 64;
91 static const int _STATE_PAUSE_COUNT_SHIFT = 6; 77 static const int _STATE_PAUSE_COUNT_SHIFT = 6;
92 78
93 /* Event handlers provided in constructor. */ 79 /* Event handlers provided in constructor. */
94 /* TODO(7733): Fix Function->_DataHandler<T> when dart2js understands 80 /* TODO(7733): Fix Function->_DataHandler<T> when dart2js understands
95 * parameterized function types. */ 81 * parameterized function types. */
96 Function _onData; 82 Function _onData;
97 _ErrorHandler _onError; 83 _ErrorHandler _onError;
98 _DoneHandler _onDone; 84 _DoneHandler _onDone;
85 final _Zone _zone = _Zone.current;
99 86
100 /** Bit vector based on state-constants above. */ 87 /** Bit vector based on state-constants above. */
101 int _state; 88 int _state;
102 89
103 /** 90 /**
104 * Queue of pending events. 91 * Queue of pending events.
105 * 92 *
106 * Is created when necessary, or set in constructor for preconfigured events. 93 * Is created when necessary, or set in constructor for preconfigured events.
107 */ 94 */
108 _PendingEvents _pending; 95 _PendingEvents _pending;
109 96
110 _BufferingStreamSubscription(this._onData, 97 _BufferingStreamSubscription(this._onData,
111 this._onError, 98 this._onError,
112 this._onDone, 99 this._onDone,
113 bool cancelOnError) 100 bool cancelOnError)
114 : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) { 101 : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) {
115 assert(_onData != null); 102 assert(_onData != null);
116 assert(_onError != null); 103 assert(_onError != null);
117 assert(_onDone != null); 104 assert(_onDone != null);
105 _zone.expectCallback();
118 } 106 }
119 107
120 /** 108 /**
121 * Sets the subscription's pending events object. 109 * Sets the subscription's pending events object.
122 * 110 *
123 * This can only be done once. The pending events object is used for the 111 * This can only be done once. The pending events object is used for the
124 * rest of the subscription's life cycle. 112 * rest of the subscription's life cycle.
125 */ 113 */
126 void _setPendingEvents(_PendingEvents pendingEvents) { 114 void _setPendingEvents(_PendingEvents pendingEvents) {
127 assert(_pending == null); 115 assert(_pending == null);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 bool get _isPaused => _state >= _STATE_PAUSE_COUNT; 214 bool get _isPaused => _state >= _STATE_PAUSE_COUNT;
227 bool get _canFire => _state < _STATE_IN_CALLBACK; 215 bool get _canFire => _state < _STATE_IN_CALLBACK;
228 bool get _mayResumeInput => 216 bool get _mayResumeInput =>
229 !_isPaused && (_pending == null || _pending.isEmpty); 217 !_isPaused && (_pending == null || _pending.isEmpty);
230 bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0; 218 bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0;
231 219
232 bool get isPaused => _isPaused; 220 bool get isPaused => _isPaused;
233 221
234 void _cancel() { 222 void _cancel() {
235 _state |= _STATE_CANCELED; 223 _state |= _STATE_CANCELED;
224 _zone.cancelCallbackExpectation();
236 if (_hasPending) { 225 if (_hasPending) {
237 _pending.cancelSchedule(); 226 _pending.cancelSchedule();
238 } 227 }
239 } 228 }
240 229
241 /** 230 /**
242 * Increment the pause count. 231 * Increment the pause count.
243 * 232 *
244 * Also marks input as paused. 233 * Also marks input as paused.
245 */ 234 */
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 _state |= _STATE_CLOSED; 275 _state |= _STATE_CLOSED;
287 if (_canFire) { 276 if (_canFire) {
288 _sendDone(); 277 _sendDone();
289 } else { 278 } else {
290 _addPending(const _DelayedDone()); 279 _addPending(const _DelayedDone());
291 } 280 }
292 } 281 }
293 282
294 // Hooks called when the input is paused, unpaused or canceled. 283 // Hooks called when the input is paused, unpaused or canceled.
295 // These must not throw. If overwritten to call user code, include suitable 284 // These must not throw. If overwritten to call user code, include suitable
296 // try/catch wrapping and send any errors to [_throwDelayed]. 285 // try/catch wrapping and send any errors to
286 // [_Zone.current.handleUncaughtError].
297 void _onPause() { 287 void _onPause() {
298 assert(_isInputPaused); 288 assert(_isInputPaused);
299 } 289 }
300 290
301 void _onResume() { 291 void _onResume() {
302 assert(!_isInputPaused); 292 assert(!_isInputPaused);
303 } 293 }
304 294
305 void _onCancel() { 295 void _onCancel() {
306 assert(_isCanceled); 296 assert(_isCanceled);
(...skipping 20 matching lines...) Expand all
327 } 317 }
328 318
329 /* _EventDispatch interface. */ 319 /* _EventDispatch interface. */
330 320
331 void _sendData(T data) { 321 void _sendData(T data) {
332 assert(!_isCanceled); 322 assert(!_isCanceled);
333 assert(!_isPaused); 323 assert(!_isPaused);
334 assert(!_inCallback); 324 assert(!_inCallback);
335 bool wasInputPaused = _isInputPaused; 325 bool wasInputPaused = _isInputPaused;
336 _state |= _STATE_IN_CALLBACK; 326 _state |= _STATE_IN_CALLBACK;
337 try { 327 _zone.executePeriodicCallbackGuarded(() => _onData(data));
338 _onData(data);
339 } catch (e, s) {
340 _throwDelayed(e, s);
341 }
342 _state &= ~_STATE_IN_CALLBACK; 328 _state &= ~_STATE_IN_CALLBACK;
343 _checkState(wasInputPaused); 329 _checkState(wasInputPaused);
344 } 330 }
345 331
346 void _sendError(var error) { 332 void _sendError(var error) {
347 assert(!_isCanceled); 333 assert(!_isCanceled);
348 assert(!_isPaused); 334 assert(!_isPaused);
349 assert(!_inCallback); 335 assert(!_inCallback);
350 bool wasInputPaused = _isInputPaused; 336 bool wasInputPaused = _isInputPaused;
351 _state |= _STATE_IN_CALLBACK; 337 _state |= _STATE_IN_CALLBACK;
352 try { 338 if (!_zone.inSameErrorZone(_Zone.current)) {
353 _onError(error); 339 // Errors are not allowed to traverse zone boundaries.
354 } catch (e, s) { 340 _Zone.current.handleUncaughtError(error);
355 _throwDelayed(e, s); 341 } else {
342 _zone.executePeriodicCallbackGuarded(() => _onError(error));
356 } 343 }
357 _state &= ~_STATE_IN_CALLBACK; 344 _state &= ~_STATE_IN_CALLBACK;
358 if (_cancelOnError) { 345 if (_cancelOnError) {
359 _cancel(); 346 _cancel();
360 } 347 }
361 _checkState(wasInputPaused); 348 _checkState(wasInputPaused);
362 } 349 }
363 350
364 void _sendDone() { 351 void _sendDone() {
365 assert(!_isCanceled); 352 assert(!_isCanceled);
366 assert(!_isPaused); 353 assert(!_isPaused);
367 assert(!_inCallback); 354 assert(!_inCallback);
368 _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK); 355 _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK);
369 try { 356 _zone.executeCallbackGuarded(_onDone);
370 _onDone();
371 } catch (e, s) {
372 _throwDelayed(e, s);
373 }
374 _onCancel(); // No checkState after cancel, it is always the last event. 357 _onCancel(); // No checkState after cancel, it is always the last event.
375 _state &= ~_STATE_IN_CALLBACK; 358 _state &= ~_STATE_IN_CALLBACK;
376 } 359 }
377 360
378 /** 361 /**
379 * Call a hook function. 362 * Call a hook function.
380 * 363 *
381 * The call is properly wrapped in code to avoid other callbacks 364 * The call is properly wrapped in code to avoid other callbacks
382 * during the call, and it checks for state changes after the call 365 * during the call, and it checks for state changes after the call
383 * that should cause further callbacks. 366 * that should cause further callbacks.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 typedef void _DataHandler<T>(T value); 527 typedef void _DataHandler<T>(T value);
545 typedef void _ErrorHandler(error); 528 typedef void _ErrorHandler(error);
546 typedef void _DoneHandler(); 529 typedef void _DoneHandler();
547 530
548 531
549 /** Default data handler, does nothing. */ 532 /** Default data handler, does nothing. */
550 void _nullDataHandler(var value) {} 533 void _nullDataHandler(var value) {}
551 534
552 /** Default error handler, reports the error to the global handler. */ 535 /** Default error handler, reports the error to the global handler. */
553 void _nullErrorHandler(error) { 536 void _nullErrorHandler(error) {
554 _throwDelayed(error); 537 _Zone.current.handleUncaughtError(error);
555 } 538 }
556 539
557 /** Default done handler, does nothing. */ 540 /** Default done handler, does nothing. */
558 void _nullDoneHandler() {} 541 void _nullDoneHandler() {}
559 542
560 543
561 /** A delayed event on a buffering stream subscription. */ 544 /** A delayed event on a buffering stream subscription. */
562 abstract class _DelayedEvent { 545 abstract class _DelayedEvent {
563 /** Added as a linked list on the [StreamController]. */ 546 /** Added as a linked list on the [StreamController]. */
564 _DelayedEvent next; 547 _DelayedEvent next;
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 _FutureImpl<bool> hasNext = _futureOrPrefetch; 875 _FutureImpl<bool> hasNext = _futureOrPrefetch;
893 _clear(); 876 _clear();
894 hasNext._setValue(false); 877 hasNext._setValue(false);
895 return; 878 return;
896 } 879 }
897 _subscription.pause(); 880 _subscription.pause();
898 _futureOrPrefetch = null; 881 _futureOrPrefetch = null;
899 _state = _STATE_EXTRA_DONE; 882 _state = _STATE_EXTRA_DONE;
900 } 883 }
901 } 884 }
OLDNEW
« no previous file with comments | « sdk/lib/async/stream_controller.dart ('k') | sdk/lib/async/zone.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698