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

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

Issue 17064008: Revert "Zone support for Futures." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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/event_loop.dart ('k') | sdk/lib/async/stream_controller.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 deprecatedFutureValue(_FutureImpl future) => 7 deprecatedFutureValue(_FutureImpl future) =>
8 future._isComplete ? future._resultOrListeners : null; 8 future._isComplete ? future._resultOrListeners : null;
9 9
10 abstract class _Completer<T> implements Completer<T> { 10 abstract class _Completer<T> implements Completer<T> {
11 final Future<T> future; 11 final Future<T> future;
12 bool _isComplete = false; 12 bool _isComplete = false;
13 13
14 _Completer() : future = new _FutureImpl<T>() { 14 _Completer() : future = new _FutureImpl<T>();
15 _FutureImpl futureImpl = future;
16 futureImpl._zone.expectCallback();
17 }
18 15
19 void _setFutureValue(T value); 16 void _setFutureValue(T value);
20 void _setFutureError(error); 17 void _setFutureError(error);
21 18
22 void complete([T value]) { 19 void complete([T value]) {
23 if (_isComplete) throw new StateError("Future already completed"); 20 if (_isComplete) throw new StateError("Future already completed");
24 _isComplete = true; 21 _isComplete = true;
25 _FutureImpl futureImpl = future;
26 futureImpl._zone.cancelCallbackExpectation();
27 _setFutureValue(value); 22 _setFutureValue(value);
28 } 23 }
29 24
30 void completeError(Object error, [Object stackTrace = null]) { 25 void completeError(Object error, [Object stackTrace = null]) {
31 if (_isComplete) throw new StateError("Future already completed"); 26 if (_isComplete) throw new StateError("Future already completed");
32 _isComplete = true; 27 _isComplete = true;
33 if (stackTrace != null) { 28 if (stackTrace != null) {
34 // Force the stack trace onto the error, even if it already had one. 29 // Force the stack trace onto the error, even if it already had one.
35 _attachStackTrace(error, stackTrace); 30 _attachStackTrace(error, stackTrace);
36 } 31 }
37 _FutureImpl futureImpl = future; 32 _setFutureError(error);
38 if (futureImpl._inSameErrorZone(_Zone.current)) {
39 futureImpl._zone.cancelCallbackExpectation();
40 _setFutureError(error);
41 } else {
42 _Zone.current.handleUncaughtError(error);
43 }
44 } 33 }
45 34
46 bool get isCompleted => _isComplete; 35 bool get isCompleted => _isComplete;
47 } 36 }
48 37
49 class _AsyncCompleter<T> extends _Completer<T> { 38 class _AsyncCompleter<T> extends _Completer<T> {
50 void _setFutureValue(T value) { 39 void _setFutureValue(T value) {
51 _FutureImpl future = this.future; 40 _FutureImpl future = this.future;
52 runAsync(() { future._setValue(value); }); 41 runAsync(() { future._setValue(value); });
53 } 42 }
(...skipping 24 matching lines...) Expand all
78 * 67 *
79 * Listeners are kept in a linked list. 68 * Listeners are kept in a linked list.
80 */ 69 */
81 abstract class _FutureListener<T> { 70 abstract class _FutureListener<T> {
82 _FutureListener _nextListener; 71 _FutureListener _nextListener;
83 factory _FutureListener.wrap(_FutureImpl future) { 72 factory _FutureListener.wrap(_FutureImpl future) {
84 return new _FutureListenerWrapper(future); 73 return new _FutureListenerWrapper(future);
85 } 74 }
86 void _sendValue(T value); 75 void _sendValue(T value);
87 void _sendError(error); 76 void _sendError(error);
88
89 bool _inSameErrorZone(_Zone otherZone);
90 } 77 }
91 78
92 /** Adapter for a [_FutureImpl] to be a future result listener. */ 79 /** Adapter for a [_FutureImpl] to be a future result listener. */
93 class _FutureListenerWrapper<T> implements _FutureListener<T> { 80 class _FutureListenerWrapper<T> implements _FutureListener<T> {
94 _FutureImpl future; 81 _FutureImpl future;
95 _FutureListener _nextListener; 82 _FutureListener _nextListener;
96 _FutureListenerWrapper(this.future); 83 _FutureListenerWrapper(this.future);
97 _sendValue(T value) { future._setValue(value); } 84 _sendValue(T value) { future._setValue(value); }
98 _sendError(error) { future._setError(error); } 85 _sendError(error) { future._setError(error); }
99 bool _inSameErrorZone(_Zone otherZone) => future._inSameErrorZone(otherZone);
100 }
101
102 /**
103 * This listener is installed at error-zone boundaries. It signals an
104 * uncaught error in the zone of origin when an error is sent from one error
105 * zone to another.
106 *
107 * When a Future is listening to another Future and they have not been
108 * instantiated in the same error-zone then Futures put an instance of this
109 * class between them (see [_FutureImpl._addListener]).
110 *
111 * For example:
112 *
113 * var completer = new Completer();
114 * var future = completer.future.then((x) => x);
115 * catchErrors(() {
116 * var future2 = future.catchError(print);
117 * });
118 * completer.completeError(499);
119 *
120 * In this example `future` and `future2` are in different error-zones. The
121 * error (499) that originates outside `catchErrors` must not reach the
122 * `catchError` future (`future2`) inside `catchErrors`.
123 *
124 * When invoking `catchError` on `future` the Future installs an
125 * [_ErrorZoneBoundaryListener] between itself and the result, `future2`.
126 *
127 * Conceptually _ErrorZoneBoundaryListeners could be implemented as
128 * `catchError`s on the origin future as well.
129 */
130 class _ErrorZoneBoundaryListener implements _FutureListener {
131 _FutureListener _nextListener;
132 final _FutureListener _listener;
133
134 _ErrorZoneBoundaryListener(this._listener);
135
136 bool _inSameErrorZone(_Zone otherZone) {
137 // Should never be called. We use [_inSameErrorZone] to know if we have
138 // to insert an instance of [_ErrorZoneBoundaryListener] (and in the
139 // controller). Once we have inserted one we should never need to use it
140 // anymore.
141 throw new UnsupportedError(
142 "A Zone boundary doesn't support the inSameErrorZone test.");
143 }
144
145 void _sendValue(value) {
146 _listener._sendValue(value);
147 }
148
149 void _sendError(error) {
150 // We are not allowed to send an error from one error-zone to another.
151 // This is the whole purpose of this class.
152 _Zone.current.handleUncaughtError(error);
153 }
154 } 86 }
155 87
156 class _FutureImpl<T> implements Future<T> { 88 class _FutureImpl<T> implements Future<T> {
157 // State of the future. The state determines the interpretation of the 89 // State of the future. The state determines the interpretation of the
158 // [resultOrListeners] field. 90 // [resultOrListeners] field.
159 // TODO(lrn): rename field since it can also contain a chained future. 91 // TODO(lrn): rename field since it can also contain a chained future.
160 92
161 /// Initial state, waiting for a result. In this state, the 93 /// Initial state, waiting for a result. In this state, the
162 /// [resultOrListeners] field holds a single-linked list of 94 /// [resultOrListeners] field holds a single-linked list of
163 /// [FutureListener] listeners. 95 /// [FutureListener] listeners.
(...skipping 15 matching lines...) Expand all
179 /// Extra bit set when the future has been completed with an error result. 111 /// Extra bit set when the future has been completed with an error result.
180 /// but no listener has been scheduled to receive the error. 112 /// but no listener has been scheduled to receive the error.
181 /// If the bit is still set when a [runAsync] call triggers, the error will 113 /// If the bit is still set when a [runAsync] call triggers, the error will
182 /// be reported to the top-level handler. 114 /// be reported to the top-level handler.
183 /// Assigning a listener before that time will clear the bit. 115 /// Assigning a listener before that time will clear the bit.
184 static const int _UNHANDLED_ERROR = 8; 116 static const int _UNHANDLED_ERROR = 8;
185 117
186 /** Whether the future is complete, and as what. */ 118 /** Whether the future is complete, and as what. */
187 int _state = _INCOMPLETE; 119 int _state = _INCOMPLETE;
188 120
189 final _Zone _zone = _Zone.current.fork();
190
191 bool get _isChained => (_state & _CHAINED) != 0; 121 bool get _isChained => (_state & _CHAINED) != 0;
192 bool get _hasChainedListener => _state == _CHAINED; 122 bool get _hasChainedListener => _state == _CHAINED;
193 bool get _isComplete => _state >= _VALUE; 123 bool get _isComplete => _state >= _VALUE;
194 bool get _hasValue => _state == _VALUE; 124 bool get _hasValue => _state == _VALUE;
195 bool get _hasError => _state >= _ERROR; 125 bool get _hasError => _state >= _ERROR;
196 bool get _hasUnhandledError => _state >= _UNHANDLED_ERROR; 126 bool get _hasUnhandledError => _state >= _UNHANDLED_ERROR;
197 127
198 void _clearUnhandledError() { 128 void _clearUnhandledError() {
199 _state &= ~_UNHANDLED_ERROR; 129 _state &= ~_UNHANDLED_ERROR;
200 } 130 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 Future catchError(f(error), { bool test(error) }) { 208 Future catchError(f(error), { bool test(error) }) {
279 return new _CatchErrorFuture(f, test).._subscribeTo(this); 209 return new _CatchErrorFuture(f, test).._subscribeTo(this);
280 } 210 }
281 211
282 Future<T> whenComplete(action()) { 212 Future<T> whenComplete(action()) {
283 return new _WhenFuture<T>(action).._subscribeTo(this); 213 return new _WhenFuture<T>(action).._subscribeTo(this);
284 } 214 }
285 215
286 Stream<T> asStream() => new Stream.fromFuture(this); 216 Stream<T> asStream() => new Stream.fromFuture(this);
287 217
288 bool _inSameErrorZone(_Zone otherZone) {
289 return _zone.inSameErrorZone(otherZone);
290 }
291
292 void _setValue(T value) { 218 void _setValue(T value) {
293 if (_isComplete) throw new StateError("Future already completed"); 219 if (_isComplete) throw new StateError("Future already completed");
294 _FutureListener listeners = _isChained ? null : _removeListeners(); 220 _FutureListener listeners = _isChained ? null : _removeListeners();
295 _state = _VALUE; 221 _state = _VALUE;
296 _resultOrListeners = value; 222 _resultOrListeners = value;
297 while (listeners != null) { 223 while (listeners != null) {
298 _FutureListener listener = listeners; 224 _FutureListener listener = listeners;
299 listeners = listener._nextListener; 225 listeners = listener._nextListener;
300 listener._nextListener = null; 226 listener._nextListener = null;
301 listener._sendValue(value); 227 listener._sendValue(value);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 assert(_state == _ERROR); 260 assert(_state == _ERROR);
335 _state = _ERROR | _UNHANDLED_ERROR; 261 _state = _ERROR | _UNHANDLED_ERROR;
336 // Wait for the rest of the current event's duration to see 262 // Wait for the rest of the current event's duration to see
337 // if a subscriber is added to handle the error. 263 // if a subscriber is added to handle the error.
338 runAsync(() { 264 runAsync(() {
339 if (_hasUnhandledError) { 265 if (_hasUnhandledError) {
340 // No error handler has been added since the error was set. 266 // No error handler has been added since the error was set.
341 _clearUnhandledError(); 267 _clearUnhandledError();
342 // TODO(floitsch): Hook this into unhandled error handling. 268 // TODO(floitsch): Hook this into unhandled error handling.
343 var error = _resultOrListeners; 269 var error = _resultOrListeners;
344 _zone.handleUncaughtError(error); 270 print("Uncaught Error: ${error}");
271 var trace = getAttachedStackTrace(error);
272 if (trace != null) {
273 print("Stack Trace:\n$trace\n");
274 }
275 throw error;
345 } 276 }
346 }); 277 });
347 } 278 }
348 279
349 void _addListener(_FutureListener listener) { 280 void _addListener(_FutureListener listener) {
350 assert(listener._nextListener == null);
351 if (!listener._inSameErrorZone(_zone)) {
352 listener = new _ErrorZoneBoundaryListener(listener);
353 }
354 if (_isChained) { 281 if (_isChained) {
355 _state = _CHAINED; // In case it was _CHAINED_UNLISTENED. 282 _state = _CHAINED; // In case it was _CHAINED_UNLISTENED.
356 _FutureImpl resultSource = _chainSource; 283 _FutureImpl resultSource = _chainSource;
357 resultSource._addListener(listener); 284 resultSource._addListener(listener);
358 return; 285 return;
359 } 286 }
360 if (_isComplete) { 287 if (_isComplete) {
361 _clearUnhandledError(); 288 _clearUnhandledError();
362 // Handle late listeners asynchronously. 289 // Handle late listeners asynchronously.
363 runAsync(() { 290 runAsync(() {
364 if (_hasValue) { 291 if (_hasValue) {
365 T value = _resultOrListeners; 292 T value = _resultOrListeners;
366 listener._sendValue(value); 293 listener._sendValue(value);
367 } else { 294 } else {
368 assert(_hasError); 295 assert(_hasError);
369 listener._sendError(_resultOrListeners); 296 listener._sendError(_resultOrListeners);
370 } 297 }
371 }); 298 });
372 } else { 299 } else {
373 assert(!_isComplete); 300 assert(!_isComplete);
301 assert(listener._nextListener == null);
374 listener._nextListener = _resultOrListeners; 302 listener._nextListener = _resultOrListeners;
375 _resultOrListeners = listener; 303 _resultOrListeners = listener;
376 } 304 }
377 } 305 }
378 306
379 _FutureListener _removeListeners() { 307 _FutureListener _removeListeners() {
380 // Reverse listeners before returning them, so the resulting list is in 308 // Reverse listeners before returning them, so the resulting list is in
381 // subscription order. 309 // subscription order.
382 assert(!_isComplete); 310 assert(!_isComplete);
383 _FutureListener current = _resultOrListeners; 311 _FutureListener current = _resultOrListeners;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 * 427 *
500 * A transforming future is itself a future and a future listener. 428 * A transforming future is itself a future and a future listener.
501 * Subclasses override [_sendValue]/[_sendError] to intercept 429 * Subclasses override [_sendValue]/[_sendError] to intercept
502 * the results of a previous future. 430 * the results of a previous future.
503 */ 431 */
504 abstract class _TransformFuture<S, T> extends _FutureImpl<T> 432 abstract class _TransformFuture<S, T> extends _FutureImpl<T>
505 implements _FutureListener<S> { 433 implements _FutureListener<S> {
506 // _FutureListener implementation. 434 // _FutureListener implementation.
507 _FutureListener _nextListener; 435 _FutureListener _nextListener;
508 436
509 _TransformFuture() { 437 void _sendValue(S value);
510 _zone.expectCallback();
511 }
512 438
513 void _sendValue(S value) { 439 void _sendError(error);
514 _zone.executeCallback(() => _zonedSendValue(value));
515 }
516
517 void _sendError(error) {
518 _zone.executeCallback(() => _zonedSendError(error));
519 }
520 440
521 void _subscribeTo(_FutureImpl future) { 441 void _subscribeTo(_FutureImpl future) {
522 future._addListener(this); 442 future._addListener(this);
523 } 443 }
524
525 void _zonedSendValue(S value);
526 void _zonedSendError(error);
527 } 444 }
528 445
529 /** The onValue and onError handlers return either a value or a future */ 446 /** The onValue and onError handlers return either a value or a future */
530 typedef dynamic _FutureOnValue<T>(T value); 447 typedef dynamic _FutureOnValue<T>(T value);
531 typedef dynamic _FutureOnError(error); 448 typedef dynamic _FutureOnError(error);
532 /** Test used by [Future.catchError] to handle skip some errors. */ 449 /** Test used by [Future.catchError] to handle skip some errors. */
533 typedef bool _FutureErrorTest(var error); 450 typedef bool _FutureErrorTest(var error);
534 /** Used by [WhenFuture]. */ 451 /** Used by [WhenFuture]. */
535 typedef _FutureAction(); 452 typedef _FutureAction();
536 453
537 /** Future returned by [Future.then] with no [:onError:] parameter. */ 454 /** Future returned by [Future.then] with no [:onError:] parameter. */
538 class _ThenFuture<S, T> extends _TransformFuture<S, T> { 455 class _ThenFuture<S, T> extends _TransformFuture<S, T> {
539 // TODO(ahe): Restore type when feature is implemented in dart2js 456 // TODO(ahe): Restore type when feature is implemented in dart2js
540 // checked mode. 457 // checked mode.
541 final /* _FutureOnValue<S> */ _onValue; 458 final /* _FutureOnValue<S> */ _onValue;
542 459
543 _ThenFuture(this._onValue); 460 _ThenFuture(this._onValue);
544 461
545 _zonedSendValue(S value) { 462 _sendValue(S value) {
546 assert(_onValue != null); 463 assert(_onValue != null);
547 var result; 464 var result;
548 try { 465 try {
549 result = _onValue(value); 466 result = _onValue(value);
550 } catch (e, s) { 467 } catch (e, s) {
551 _setError(_asyncError(e, s)); 468 _setError(_asyncError(e, s));
552 return; 469 return;
553 } 470 }
554 _setOrChainValue(result); 471 _setOrChainValue(result);
555 } 472 }
556 473
557 void _zonedSendError(error) { 474 void _sendError(error) {
558 _setError(error); 475 _setError(error);
559 } 476 }
560 } 477 }
561 478
562 /** Future returned by [Future.catchError]. */ 479 /** Future returned by [Future.catchError]. */
563 class _CatchErrorFuture<T> extends _TransformFuture<T,T> { 480 class _CatchErrorFuture<T> extends _TransformFuture<T,T> {
564 final _FutureErrorTest _test; 481 final _FutureErrorTest _test;
565 final _FutureOnError _onError; 482 final _FutureOnError _onError;
566 483
567 _CatchErrorFuture(this._onError, this._test); 484 _CatchErrorFuture(this._onError, this._test);
568 485
569 _zonedSendValue(T value) { 486 _sendValue(T value) {
570 _setValue(value); 487 _setValue(value);
571 } 488 }
572 489
573 _zonedSendError(error) { 490 _sendError(error) {
574 assert(_onError != null); 491 assert(_onError != null);
575 // if _test is supplied, check if it returns true, otherwise just 492 // if _test is supplied, check if it returns true, otherwise just
576 // forward the error unmodified. 493 // forward the error unmodified.
577 if (_test != null) { 494 if (_test != null) {
578 bool matchesTest; 495 bool matchesTest;
579 try { 496 try {
580 matchesTest = _test(error); 497 matchesTest = _test(error);
581 } catch (e, s) { 498 } catch (e, s) {
582 _setError(_asyncError(e, s)); 499 _setError(_asyncError(e, s));
583 return; 500 return;
(...skipping 16 matching lines...) Expand all
600 } 517 }
601 518
602 /** Future returned by [Future.then] with an [:onError:] parameter. */ 519 /** Future returned by [Future.then] with an [:onError:] parameter. */
603 class _SubscribeFuture<S, T> extends _ThenFuture<S, T> { 520 class _SubscribeFuture<S, T> extends _ThenFuture<S, T> {
604 final _FutureOnError _onError; 521 final _FutureOnError _onError;
605 522
606 _SubscribeFuture(onValue(S value), this._onError) : super(onValue); 523 _SubscribeFuture(onValue(S value), this._onError) : super(onValue);
607 524
608 // The _sendValue method is inherited from ThenFuture. 525 // The _sendValue method is inherited from ThenFuture.
609 526
610 void _zonedSendError(error) { 527 void _sendError(error) {
611 assert(_onError != null); 528 assert(_onError != null);
612 var result; 529 var result;
613 try { 530 try {
614 result = _onError(error); 531 result = _onError(error);
615 } catch (e, s) { 532 } catch (e, s) {
616 _setError(_asyncError(e, s)); 533 _setError(_asyncError(e, s));
617 return; 534 return;
618 } 535 }
619 _setOrChainValue(result); 536 _setOrChainValue(result);
620 } 537 }
621 } 538 }
622 539
623 /** Future returned by [Future.whenComplete]. */ 540 /** Future returned by [Future.whenComplete]. */
624 class _WhenFuture<T> extends _TransformFuture<T, T> { 541 class _WhenFuture<T> extends _TransformFuture<T, T> {
625 final _FutureAction _action; 542 final _FutureAction _action;
626 543
627 _WhenFuture(this._action); 544 _WhenFuture(this._action);
628 545
629 void _zonedSendValue(T value) { 546 void _sendValue(T value) {
630 try { 547 try {
631 var result = _action(); 548 var result = _action();
632 if (result is Future) { 549 if (result is Future) {
633 Future resultFuture = result; 550 Future resultFuture = result;
634 resultFuture.then((_) { 551 resultFuture.then((_) {
635 _setValue(value); 552 _setValue(value);
636 }, onError: _setError); 553 }, onError: _setError);
637 return; 554 return;
638 } 555 }
639 } catch (e, s) { 556 } catch (e, s) {
640 _setError(_asyncError(e, s)); 557 _setError(_asyncError(e, s));
641 return; 558 return;
642 } 559 }
643 _setValue(value); 560 _setValue(value);
644 } 561 }
645 562
646 void _zonedSendError(error) { 563 void _sendError(error) {
647 try { 564 try {
648 var result = _action(); 565 var result = _action();
649 if (result is Future) { 566 if (result is Future) {
650 Future resultFuture = result; 567 Future resultFuture = result;
651 // TODO(lrn): Find a way to combine [error] into [e]. 568 // TODO(lrn): Find a way to combine [error] into [e].
652 resultFuture.then((_) { 569 resultFuture.then((_) {
653 _setError(error); 570 _setError(error);
654 }, onError: _setError); 571 }, onError: _setError);
655 return; 572 return;
656 } 573 }
657 } catch (e, s) { 574 } catch (e, s) {
658 error = _asyncError(e, s); 575 error = _asyncError(e, s);
659 } 576 }
660 _setError(error); 577 _setError(error);
661 } 578 }
662 } 579 }
OLDNEW
« no previous file with comments | « sdk/lib/async/event_loop.dart ('k') | sdk/lib/async/stream_controller.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698