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

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: Created 5 years, 10 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 70 // Optimizing a group of Timer.run callbacks to be executed in the
64 // same Timer callback. 71 // same Timer callback.
Ivan Posva 2015/02/02 16:06:47 I am not clear what this comment is trying to tell
Lasse Reichstein Nielsen 2015/02/23 08:01:39 I think the timer is long, long gone. This comment
65 if (_nextCallback == null) { 72 if (_nextCallback == null) {
66 _nextCallback = _lastCallback = new _AsyncCallbackEntry(callback); 73 _nextCallback = _lastCallback = newEntry;
67 if (!_isInCallbackLoop) { 74 if (!_isInCallbackLoop) {
68 _AsyncRun._scheduleImmediate(_asyncRunCallback); 75 _AsyncRun._scheduleImmediate(_microtaskLoopEntry);
69 } 76 }
70 } else { 77 } else {
71 _AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback);
72 _lastCallback.next = newEntry; 78 _lastCallback.next = newEntry;
73 _lastCallback = newEntry; 79 _lastCallback = newEntry;
74 } 80 }
75 } 81 }
76 82
77 /** 83 /**
78 * Schedules a callback to be called before all other currently scheduled ones. 84 * Schedules a callback to be called before all other currently scheduled ones.
79 * 85 *
80 * This callback takes priority over existing scheduled callbacks. 86 * This callback takes priority over existing scheduled callbacks.
81 * It is only used internally to give higher priority to error reporting. 87 * It is only used internally to give higher priority to error reporting.
88 *
89 * Is always run in the root zone.
82 */ 90 */
83 void _schedulePriorityAsyncCallback(callback) { 91 void _schedulePriorityAsyncCallback(callback) {
84 _AsyncCallbackEntry entry = new _AsyncCallbackEntry(callback); 92 _AsyncCallbackEntry entry =
93 new _AsyncCallbackEntry(callback, _ROOT_ZONE);
85 if (_nextCallback == null) { 94 if (_nextCallback == null) {
86 _scheduleAsyncCallback(callback); 95 _scheduleAsyncCallback(entry);
87 _lastPriorityCallback = _lastCallback; 96 _lastPriorityCallback = _lastCallback;
88 } else if (_lastPriorityCallback == null) { 97 } else if (_lastPriorityCallback == null) {
89 entry.next = _nextCallback; 98 entry.next = _nextCallback;
90 _nextCallback = _lastPriorityCallback = entry; 99 _nextCallback = _lastPriorityCallback = entry;
91 } else { 100 } else {
92 entry.next = _lastPriorityCallback.next; 101 entry.next = _lastPriorityCallback.next;
93 _lastPriorityCallback.next = entry; 102 _lastPriorityCallback.next = entry;
94 _lastPriorityCallback = entry; 103 _lastPriorityCallback = entry;
95 if (entry.next == null) { 104 if (entry.next == null) {
96 _lastCallback = entry; 105 _lastCallback = entry;
(...skipping 20 matching lines...) Expand all
117 * foo(); 126 * foo();
118 * } 127 * }
119 * 128 *
120 * ## Other resources 129 * ## Other resources
121 * 130 *
122 * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/): 131 * * [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 132 * Learn how Dart handles the event queue and microtask queue, so you can write
124 * better asynchronous code with fewer surprises. 133 * better asynchronous code with fewer surprises.
125 */ 134 */
126 void scheduleMicrotask(void callback()) { 135 void scheduleMicrotask(void callback()) {
127 if (identical(_ROOT_ZONE, Zone.current)) { 136 Zone currentZone = Zone.current;
137 if (identical(_ROOT_ZONE, currentZone)) {
128 // No need to bind the callback. We know that the root's scheduleMicrotask 138 // No need to bind the callback. We know that the root's scheduleMicrotask
129 // will be invoked in the root zone. 139 // will be invoked in the root zone.
130 _rootScheduleMicrotask(null, null, _ROOT_ZONE, callback); 140 _rootScheduleMicrotask(null, null, _ROOT_ZONE, callback);
131 return; 141 return;
132 } 142 }
143 _ZoneFunction implementation = currentZone._scheduleMicrotask;
144 if (identical(_ROOT_ZONE, implementation.zone) &&
145 _ROOT_ZONE.inSameErrorZone(currentZone)) {
146 _rootScheduleMicrotask(null, null, currentZone,
147 currentZone.registerCallback(callback));
148 return;
149 }
133 Zone.current.scheduleMicrotask( 150 Zone.current.scheduleMicrotask(
134 Zone.current.bindCallback(callback, runGuarded: true)); 151 Zone.current.bindCallback(callback, runGuarded: true));
135 } 152 }
136 153
137 class _AsyncRun { 154 class _AsyncRun {
138 /** Schedule the given callback before any other event in the event-loop. */ 155 /** Schedule the given callback before any other event in the event-loop. */
139 external static void _scheduleImmediate(void callback()); 156 external static void _scheduleImmediate(void callback());
140 } 157 }
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