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

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

Issue 23875032: Expose Zones. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 7 years, 2 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/timer.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 /** Abstract and private interface for a place to put events. */ 7 /** Abstract and private interface for a place to put events. */
8 abstract class _EventSink<T> { 8 abstract class _EventSink<T> {
9 void _add(T data); 9 void _add(T data);
10 void _addError(Object error); 10 void _addError(Object error);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 static const int _STATE_CANCELED = 8; 73 static const int _STATE_CANCELED = 8;
74 static const int _STATE_IN_CALLBACK = 16; 74 static const int _STATE_IN_CALLBACK = 16;
75 static const int _STATE_HAS_PENDING = 32; 75 static const int _STATE_HAS_PENDING = 32;
76 static const int _STATE_PAUSE_COUNT = 64; 76 static const int _STATE_PAUSE_COUNT = 64;
77 static const int _STATE_PAUSE_COUNT_SHIFT = 6; 77 static const int _STATE_PAUSE_COUNT_SHIFT = 6;
78 78
79 /* Event handlers provided in constructor. */ 79 /* Event handlers provided in constructor. */
80 _DataHandler<T> _onData; 80 _DataHandler<T> _onData;
81 _ErrorHandler _onError; 81 _ErrorHandler _onError;
82 _DoneHandler _onDone; 82 _DoneHandler _onDone;
83 final _Zone _zone = _Zone.current; 83 final Zone _zone = Zone.current;
84 84
85 /** Bit vector based on state-constants above. */ 85 /** Bit vector based on state-constants above. */
86 int _state; 86 int _state;
87 87
88 /** 88 /**
89 * Queue of pending events. 89 * Queue of pending events.
90 * 90 *
91 * Is created when necessary, or set in constructor for preconfigured events. 91 * Is created when necessary, or set in constructor for preconfigured events.
92 */ 92 */
93 _PendingEvents _pending; 93 _PendingEvents _pending;
94 94
95 _BufferingStreamSubscription(this._onData, 95 _BufferingStreamSubscription(void onData(T data),
96 this._onError, 96 void onError(error),
97 this._onDone, 97 void onDone(),
98 bool cancelOnError) 98 bool cancelOnError)
99 : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) { 99 : _onData = Zone.current.registerUnaryCallback(onData),
100 _onError = Zone.current.registerUnaryCallback(onError),
101 _onDone = Zone.current.registerCallback(onDone),
102 _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) {
100 assert(_onData != null); 103 assert(_onData != null);
101 assert(_onError != null); 104 assert(_onError != null);
102 assert(_onDone != null); 105 assert(_onDone != null);
103 _zone.expectCallback();
104 } 106 }
105 107
106 /** 108 /**
107 * Sets the subscription's pending events object. 109 * Sets the subscription's pending events object.
108 * 110 *
109 * 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
110 * rest of the subscription's life cycle. 112 * rest of the subscription's life cycle.
111 */ 113 */
112 void _setPendingEvents(_PendingEvents pendingEvents) { 114 void _setPendingEvents(_PendingEvents pendingEvents) {
113 assert(_pending == null); 115 assert(_pending == null);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 bool get _isPaused => _state >= _STATE_PAUSE_COUNT; 214 bool get _isPaused => _state >= _STATE_PAUSE_COUNT;
213 bool get _canFire => _state < _STATE_IN_CALLBACK; 215 bool get _canFire => _state < _STATE_IN_CALLBACK;
214 bool get _mayResumeInput => 216 bool get _mayResumeInput =>
215 !_isPaused && (_pending == null || _pending.isEmpty); 217 !_isPaused && (_pending == null || _pending.isEmpty);
216 bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0; 218 bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0;
217 219
218 bool get isPaused => _isPaused; 220 bool get isPaused => _isPaused;
219 221
220 void _cancel() { 222 void _cancel() {
221 _state |= _STATE_CANCELED; 223 _state |= _STATE_CANCELED;
222 _zone.cancelCallbackExpectation();
223 if (_hasPending) { 224 if (_hasPending) {
224 _pending.cancelSchedule(); 225 _pending.cancelSchedule();
225 } 226 }
226 } 227 }
227 228
228 /** 229 /**
229 * Increment the pause count. 230 * Increment the pause count.
230 * 231 *
231 * Also marks input as paused. 232 * Also marks input as paused.
232 */ 233 */
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 } 316 }
316 317
317 /* _EventDispatch interface. */ 318 /* _EventDispatch interface. */
318 319
319 void _sendData(T data) { 320 void _sendData(T data) {
320 assert(!_isCanceled); 321 assert(!_isCanceled);
321 assert(!_isPaused); 322 assert(!_isPaused);
322 assert(!_inCallback); 323 assert(!_inCallback);
323 bool wasInputPaused = _isInputPaused; 324 bool wasInputPaused = _isInputPaused;
324 _state |= _STATE_IN_CALLBACK; 325 _state |= _STATE_IN_CALLBACK;
325 _zone.executePeriodicCallbackGuarded(() => _onData(data)); 326 _zone.runUnaryGuarded(_onData, data);
326 _state &= ~_STATE_IN_CALLBACK; 327 _state &= ~_STATE_IN_CALLBACK;
327 _checkState(wasInputPaused); 328 _checkState(wasInputPaused);
328 } 329 }
329 330
330 void _sendError(var error) { 331 void _sendError(var error) {
331 assert(!_isCanceled); 332 assert(!_isCanceled);
332 assert(!_isPaused); 333 assert(!_isPaused);
333 assert(!_inCallback); 334 assert(!_inCallback);
334 bool wasInputPaused = _isInputPaused; 335 bool wasInputPaused = _isInputPaused;
335 _state |= _STATE_IN_CALLBACK; 336 _state |= _STATE_IN_CALLBACK;
336 if (!_zone.inSameErrorZone(_Zone.current)) { 337 if (!_zone.inSameErrorZone(Zone.current)) {
337 // Errors are not allowed to traverse zone boundaries. 338 // Errors are not allowed to traverse zone boundaries.
338 _Zone.current.handleUncaughtError(error); 339 Zone.current.handleUncaughtError(error);
339 } else { 340 } else {
340 _zone.executePeriodicCallbackGuarded(() => _onError(error)); 341 _zone.runUnaryGuarded(_onError, error);
341 } 342 }
342 _state &= ~_STATE_IN_CALLBACK; 343 _state &= ~_STATE_IN_CALLBACK;
343 if (_cancelOnError) { 344 if (_cancelOnError) {
344 _cancel(); 345 _cancel();
345 } 346 }
346 _checkState(wasInputPaused); 347 _checkState(wasInputPaused);
347 } 348 }
348 349
349 void _sendDone() { 350 void _sendDone() {
350 assert(!_isCanceled); 351 assert(!_isCanceled);
351 assert(!_isPaused); 352 assert(!_isPaused);
352 assert(!_inCallback); 353 assert(!_inCallback);
353 _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK); 354 _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK);
354 _zone.executeCallbackGuarded(_onDone); 355 _zone.runGuarded(_onDone);
355 _onCancel(); // No checkState after cancel, it is always the last event. 356 _onCancel(); // No checkState after cancel, it is always the last event.
356 _state &= ~_STATE_IN_CALLBACK; 357 _state &= ~_STATE_IN_CALLBACK;
357 } 358 }
358 359
359 /** 360 /**
360 * Call a hook function. 361 * Call a hook function.
361 * 362 *
362 * The call is properly wrapped in code to avoid other callbacks 363 * The call is properly wrapped in code to avoid other callbacks
363 * during the call, and it checks for state changes after the call 364 * during the call, and it checks for state changes after the call
364 * that should cause further callbacks. 365 * that should cause further callbacks.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 typedef void _DataHandler<T>(T value); 526 typedef void _DataHandler<T>(T value);
526 typedef void _ErrorHandler(error); 527 typedef void _ErrorHandler(error);
527 typedef void _DoneHandler(); 528 typedef void _DoneHandler();
528 529
529 530
530 /** Default data handler, does nothing. */ 531 /** Default data handler, does nothing. */
531 void _nullDataHandler(var value) {} 532 void _nullDataHandler(var value) {}
532 533
533 /** Default error handler, reports the error to the global handler. */ 534 /** Default error handler, reports the error to the global handler. */
534 void _nullErrorHandler(error) { 535 void _nullErrorHandler(error) {
535 _Zone.current.handleUncaughtError(error); 536 Zone.current.handleUncaughtError(error);
536 } 537 }
537 538
538 /** Default done handler, does nothing. */ 539 /** Default done handler, does nothing. */
539 void _nullDoneHandler() {} 540 void _nullDoneHandler() {}
540 541
541 542
542 /** A delayed event on a buffering stream subscription. */ 543 /** A delayed event on a buffering stream subscription. */
543 abstract class _DelayedEvent { 544 abstract class _DelayedEvent {
544 /** Added as a linked list on the [StreamController]. */ 545 /** Added as a linked list on the [StreamController]. */
545 _DelayedEvent next; 546 _DelayedEvent next;
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 void cancel() {} 717 void cancel() {}
717 bool get isPaused => _pauseCounter > 0; 718 bool get isPaused => _pauseCounter > 0;
718 719
719 Future asFuture([futureValue]) => new _Future(); 720 Future asFuture([futureValue]) => new _Future();
720 } 721 }
721 722
722 class _AsBroadcastStream<T> extends Stream<T> { 723 class _AsBroadcastStream<T> extends Stream<T> {
723 final Stream<T> _source; 724 final Stream<T> _source;
724 final _broadcastCallback _onListenHandler; 725 final _broadcastCallback _onListenHandler;
725 final _broadcastCallback _onCancelHandler; 726 final _broadcastCallback _onCancelHandler;
726 final _Zone _zone; 727 final Zone _zone;
727 728
728 _AsBroadcastStreamController<T> _controller; 729 _AsBroadcastStreamController<T> _controller;
729 StreamSubscription<T> _subscription; 730 StreamSubscription<T> _subscription;
730 731
731 _AsBroadcastStream(this._source, 732 _AsBroadcastStream(this._source,
732 this._onListenHandler, 733 void onListenHandler(StreamSubscription subscription),
733 this._onCancelHandler) 734 void onCancelHandler(StreamSubscription subscription))
734 : _zone = _Zone.current { 735 : _onListenHandler = Zone.current.registerUnaryCallback(onListenHandler),
736 _onCancelHandler = Zone.current.registerUnaryCallback(onCancelHandler),
737 _zone = Zone.current {
735 _controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel); 738 _controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel);
736 // Keep zone alive until we are done doing callbacks.
737 _zone.expectCallback();
738 } 739 }
739 740
740 bool get isBroadcast => true; 741 bool get isBroadcast => true;
741 742
742 StreamSubscription<T> listen(void onData(T data), 743 StreamSubscription<T> listen(void onData(T data),
743 { void onError(Object error), 744 { void onError(Object error),
744 void onDone(), 745 void onDone(),
745 bool cancelOnError}) { 746 bool cancelOnError}) {
746 if (_controller == null) { 747 if (_controller == null) {
747 // Return a dummy subscription backed by nothing, since 748 // Return a dummy subscription backed by nothing, since
748 // it won't ever receive any events. 749 // it won't ever receive any events.
749 return new _DummyStreamSubscription<T>(); 750 return new _DummyStreamSubscription<T>();
750 } 751 }
751 if (_subscription == null) { 752 if (_subscription == null) {
752 _subscription = _source.listen(_controller.add, 753 _subscription = _source.listen(_controller.add,
753 onError: _controller.addError, 754 onError: _controller.addError,
754 onDone: _controller.close); 755 onDone: _controller.close);
755 } 756 }
756 if (onData == null) onData = _nullDataHandler; 757 if (onData == null) onData = _nullDataHandler;
757 if (onError == null) onError = _nullErrorHandler; 758 if (onError == null) onError = _nullErrorHandler;
758 if (onDone == null) onDone = _nullDoneHandler; 759 if (onDone == null) onDone = _nullDoneHandler;
759 cancelOnError = identical(true, cancelOnError); 760 cancelOnError = identical(true, cancelOnError);
760 return _controller._subscribe(onData, onError, onDone, cancelOnError); 761 return _controller._subscribe(onData, onError, onDone, cancelOnError);
761 } 762 }
762 763
763 void _onCancel() { 764 void _onCancel() {
764 bool shutdown = (_controller == null) || _controller.isClosed; 765 bool shutdown = (_controller == null) || _controller.isClosed;
765 if (_onCancelHandler != null) { 766 if (_onCancelHandler != null) {
766 _zone.executePeriodicCallbackGuarded( 767 _zone.runUnary(_onCancelHandler, new _BroadcastSubscriptionWrapper(this));
767 () => _onCancelHandler(new _BroadcastSubscriptionWrapper(this)));
768 } 768 }
769 if (shutdown) { 769 if (shutdown) {
770 if (_subscription != null) { 770 if (_subscription != null) {
771 _subscription.cancel(); 771 _subscription.cancel();
772 _subscription = null; 772 _subscription = null;
773 } 773 }
774 _zone.cancelCallbackExpectation();
775 } 774 }
776 } 775 }
777 776
778 void _onListen() { 777 void _onListen() {
779 if (_onListenHandler != null) { 778 if (_onListenHandler != null) {
780 _zone.executePeriodicCallbackGuarded( 779 _zone.runUnary(_onListenHandler, new _BroadcastSubscriptionWrapper(this));
781 () => _onListenHandler(new _BroadcastSubscriptionWrapper(this)));
782 } 780 }
783 } 781 }
784 782
785 // Methods called from _BroadcastSubscriptionWrapper. 783 // Methods called from _BroadcastSubscriptionWrapper.
786 void _cancelSubscription() { 784 void _cancelSubscription() {
787 if (_subscription == null) return; 785 if (_subscription == null) return;
788 // Called by [_controller] when it has no subscribers left. 786 // Called by [_controller] when it has no subscribers left.
789 StreamSubscription subscription = _subscription; 787 StreamSubscription subscription = _subscription;
790 _subscription = null; 788 _subscription = null;
791 if (_controller._isEmpty) {
792 _zone.cancelCallbackExpectation();
793 }
794 _controller = null; // Marks the stream as no longer listenable. 789 _controller = null; // Marks the stream as no longer listenable.
795 subscription.cancel(); 790 subscription.cancel();
796 } 791 }
797 792
798 void _pauseSubscription(Future resumeSignal) { 793 void _pauseSubscription(Future resumeSignal) {
799 if (_subscription == null) return; 794 if (_subscription == null) return;
800 _subscription.pause(resumeSignal); 795 _subscription.pause(resumeSignal);
801 } 796 }
802 797
803 void _resumeSubscription() { 798 void _resumeSubscription() {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 _Future<bool> hasNext = _futureOrPrefetch; 995 _Future<bool> hasNext = _futureOrPrefetch;
1001 _clear(); 996 _clear();
1002 hasNext._complete(false); 997 hasNext._complete(false);
1003 return; 998 return;
1004 } 999 }
1005 _subscription.pause(); 1000 _subscription.pause();
1006 _futureOrPrefetch = null; 1001 _futureOrPrefetch = null;
1007 _state = _STATE_EXTRA_DONE; 1002 _state = _STATE_EXTRA_DONE;
1008 } 1003 }
1009 } 1004 }
OLDNEW
« no previous file with comments | « sdk/lib/async/stream_controller.dart ('k') | sdk/lib/async/timer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698