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

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

Issue 891293003: Store zone in microtask entry. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix type assertion. Don't store zone if using zone.bind. Created 5 years, 8 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 | 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) 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 part of dart.async; 5 part of dart.async;
6 6
7 typedef void _AsyncCallback(); 7 typedef void _AsyncCallback();
8 8
9 class _AsyncCallbackEntry { 9 class _AsyncCallbackEntry {
10 final _AsyncCallback callback; 10 final _AsyncCallback callback;
11 final Zone zone;
11 _AsyncCallbackEntry next; 12 _AsyncCallbackEntry next;
12 _AsyncCallbackEntry(this.callback); 13 _AsyncCallbackEntry(this.callback, this.zone);
13 } 14 }
14 15
15 /** Head of single linked list of pending callbacks. */ 16 /** Head of single linked list of pending callbacks. */
16 _AsyncCallbackEntry _nextCallback; 17 _AsyncCallbackEntry _nextCallback;
17 /** Tail of single linked list of pending callbacks. */ 18 /** Tail of single linked list of pending callbacks. */
18 _AsyncCallbackEntry _lastCallback; 19 _AsyncCallbackEntry _lastCallback;
19 /** 20 /**
20 * Tail of priority callbacks added by the currently executing callback. 21 * Tail of priority callbacks added by the currently executing callback.
21 * 22 *
22 * Priority callbacks are put at the beginning of the 23 * Priority callbacks are put at the beginning of the
23 * callback queue, so that if one callback schedules more than one 24 * callback queue, so that if one callback schedules more than one
24 * priority callback, they are still enqueued in scheduling order. 25 * priority callback, they are still enqueued in scheduling order.
25 */ 26 */
26 _AsyncCallbackEntry _lastPriorityCallback; 27 _AsyncCallbackEntry _lastPriorityCallback;
27 /** 28 /**
28 * Whether we are currently inside the callback loop. 29 * Whether we are currently inside the callback loop.
29 * 30 *
30 * If we are inside the loop, we never need to schedule the loop, 31 * If we are inside the loop, we never need to schedule the loop,
31 * even if adding a first element. 32 * even if adding a first element.
32 */ 33 */
33 bool _isInCallbackLoop = false; 34 bool _isInCallbackLoop = false;
34 35
35 void _asyncRunCallbackLoop() { 36 void _microtaskLoop() {
36 while (_nextCallback != null) { 37 while (_nextCallback != null) {
37 _lastPriorityCallback = null; 38 _lastPriorityCallback = null;
38 _AsyncCallbackEntry entry = _nextCallback; 39 _AsyncCallbackEntry entry = _nextCallback;
39 _nextCallback = entry.next; 40 _nextCallback = entry.next;
40 if (_nextCallback == null) _lastCallback = null; 41 if (_nextCallback == null) _lastCallback = null;
42 Zone._current = entry.zone;
41 entry.callback(); 43 entry.callback();
42 } 44 }
43 } 45 }
44 46
45 void _asyncRunCallback() { 47 void _microtaskLoopEntry() {
46 _isInCallbackLoop = true; 48 _isInCallbackLoop = true;
47 try { 49 try {
48 _asyncRunCallbackLoop(); 50 // Moved to separate function because try-finally prevents
51 // good optimization.
52 _microtaskLoop();
49 } finally { 53 } finally {
54 Zone._current = _ROOT_ZONE;
50 _lastPriorityCallback = null; 55 _lastPriorityCallback = null;
51 _isInCallbackLoop = false; 56 _isInCallbackLoop = false;
52 if (_nextCallback != null) _AsyncRun._scheduleImmediate(_asyncRunCallback); 57 if (_nextCallback != null) {
58 _AsyncRun._scheduleImmediate(_microtaskLoopEntry);
59 }
53 } 60 }
54 } 61 }
55 62
56 /** 63 /**
57 * Schedules a callback to be called as a microtask. 64 * Schedules a callback to be called as a microtask.
58 * 65 *
59 * The microtask is called after all other currently scheduled 66 * The microtask is called after all other currently scheduled
60 * microtasks, but as part of the current system event. 67 * microtasks, but as part of the current system event.
61 */ 68 */
62 void _scheduleAsyncCallback(callback) { 69 void _scheduleAsyncCallback(_AsyncCallbackEntry newEntry) {
63 // Optimizing a group of Timer.run callbacks to be executed in the
64 // same Timer callback.
65 if (_nextCallback == null) { 70 if (_nextCallback == null) {
66 _nextCallback = _lastCallback = new _AsyncCallbackEntry(callback); 71 _nextCallback = _lastCallback = newEntry;
67 if (!_isInCallbackLoop) { 72 if (!_isInCallbackLoop) {
68 _AsyncRun._scheduleImmediate(_asyncRunCallback); 73 _AsyncRun._scheduleImmediate(_microtaskLoopEntry);
69 } 74 }
70 } else { 75 } else {
71 _AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback);
72 _lastCallback.next = newEntry; 76 _lastCallback.next = newEntry;
73 _lastCallback = newEntry; 77 _lastCallback = newEntry;
74 } 78 }
75 } 79 }
76 80
77 /** 81 /**
78 * Schedules a callback to be called before all other currently scheduled ones. 82 * Schedules a callback to be called before all other currently scheduled ones.
79 * 83 *
80 * This callback takes priority over existing scheduled callbacks. 84 * This callback takes priority over existing scheduled callbacks.
81 * It is only used internally to give higher priority to error reporting. 85 * It is only used internally to give higher priority to error reporting.
86 *
87 * Is always run in the root zone.
82 */ 88 */
83 void _schedulePriorityAsyncCallback(callback) { 89 void _schedulePriorityAsyncCallback(callback) {
84 _AsyncCallbackEntry entry = new _AsyncCallbackEntry(callback); 90 _AsyncCallbackEntry entry =
91 new _AsyncCallbackEntry(callback, _ROOT_ZONE);
85 if (_nextCallback == null) { 92 if (_nextCallback == null) {
86 _scheduleAsyncCallback(callback); 93 _scheduleAsyncCallback(entry);
87 _lastPriorityCallback = _lastCallback; 94 _lastPriorityCallback = _lastCallback;
88 } else if (_lastPriorityCallback == null) { 95 } else if (_lastPriorityCallback == null) {
89 entry.next = _nextCallback; 96 entry.next = _nextCallback;
90 _nextCallback = _lastPriorityCallback = entry; 97 _nextCallback = _lastPriorityCallback = entry;
91 } else { 98 } else {
92 entry.next = _lastPriorityCallback.next; 99 entry.next = _lastPriorityCallback.next;
93 _lastPriorityCallback.next = entry; 100 _lastPriorityCallback.next = entry;
94 _lastPriorityCallback = entry; 101 _lastPriorityCallback = entry;
95 if (entry.next == null) { 102 if (entry.next == null) {
96 _lastCallback = entry; 103 _lastCallback = entry;
(...skipping 20 matching lines...) Expand all
117 * foo(); 124 * foo();
118 * } 125 * }
119 * 126 *
120 * ## Other resources 127 * ## Other resources
121 * 128 *
122 * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/): 129 * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
123 * Learn how Dart handles the event queue and microtask queue, so you can write 130 * Learn how Dart handles the event queue and microtask queue, so you can write
124 * better asynchronous code with fewer surprises. 131 * better asynchronous code with fewer surprises.
125 */ 132 */
126 void scheduleMicrotask(void callback()) { 133 void scheduleMicrotask(void callback()) {
127 if (identical(_ROOT_ZONE, Zone.current)) { 134 _Zone currentZone = Zone.current;
135 if (identical(_ROOT_ZONE, currentZone)) {
128 // No need to bind the callback. We know that the root's scheduleMicrotask 136 // No need to bind the callback. We know that the root's scheduleMicrotask
129 // will be invoked in the root zone. 137 // will be invoked in the root zone.
130 _rootScheduleMicrotask(null, null, _ROOT_ZONE, callback); 138 _rootScheduleMicrotask(null, null, _ROOT_ZONE, callback);
131 return; 139 return;
132 } 140 }
141 _ZoneFunction implementation = currentZone._scheduleMicrotask;
142 if (identical(_ROOT_ZONE, implementation.zone) &&
143 _ROOT_ZONE.inSameErrorZone(currentZone)) {
144 _rootScheduleMicrotask(null, null, currentZone,
145 currentZone.registerCallback(callback));
146 return;
147 }
133 Zone.current.scheduleMicrotask( 148 Zone.current.scheduleMicrotask(
134 Zone.current.bindCallback(callback, runGuarded: true)); 149 Zone.current.bindCallback(callback, runGuarded: true));
135 } 150 }
136 151
137 class _AsyncRun { 152 class _AsyncRun {
138 /** Schedule the given callback before any other event in the event-loop. */ 153 /** Schedule the given callback before any other event in the event-loop. */
139 external static void _scheduleImmediate(void callback()); 154 external static void _scheduleImmediate(void callback());
140 } 155 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/async/zone.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698