@@ -29,12 +29,10 @@ class VmTurnZone {
2929 // onTurnDone hook at the end of the current VM turn.
3030 Zone _innerZone;
3131
32- // Number of microtasks pending from _outerZone (& descendants)
32+ // Number of microtasks pending from _innerZone (& descendants)
3333 int _pendingMicrotasks = 0 ;
3434 // Whether some code has been executed in the _innerZone (& descendants) in the current turn
3535 bool _hasExecutedCodeInInnerZone = false ;
36- // Whether the onTurnStart hook is executing
37- bool _inTurnStart = false ;
3836 // _outerRun() call depth. 0 at the end of a macrotask
3937 // zone.run(() => { // top-level call
4038 // zone.run(() => {}); // nested call -> in-turn
@@ -44,36 +42,26 @@ class VmTurnZone {
4442 /**
4543 * Associates with this
4644 *
47- * - an "outer" [Zone] , which is a child of the one that created this.
45+ * - an "outer" [Zone] , which is a the one that created this.
4846 * - an "inner" [Zone] , which is a child of the outer [Zone] .
4947 *
5048 * @param {bool} enableLongStackTrace whether to enable long stack trace. They should only be
5149 * enabled in development mode as they significantly impact perf.
5250 */
5351 VmTurnZone ({bool enableLongStackTrace}) {
54- // The _outerZone captures microtask scheduling so that we can run onTurnDone when the queue
55- // is exhausted and code has been executed in the _innerZone.
52+ _outerZone = Zone .current;
53+
5654 if (enableLongStackTrace) {
57- _outerZone = Chain .capture (
58- () => _createOuterZone (Zone .current),
55+ _innerZone = Chain .capture (
56+ () => _createInnerZone (Zone .current),
5957 onError: _onErrorWithLongStackTrace);
6058 } else {
61- _outerZone = _createOuterZone (
59+ _innerZone = _createInnerZone (
6260 Zone .current,
6361 handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, error, StackTrace trace) =>
6462 _onErrorWithoutLongStackTrace (error, trace)
6563 );
6664 }
67-
68- // Instruments the inner [Zone] to detect when code is executed in this (or a descendant) zone.
69- // Also runs the onTurnStart hook the first time this zone executes some code in each turn.
70- _innerZone = _outerZone.fork (
71- specification: new ZoneSpecification (
72- run: _innerRun,
73- runUnary: _innerRunUnary,
74- runBinary: _innerRunBinary
75- ),
76- zoneValues: {'_name' : 'inner' });
7765 }
7866
7967 /**
@@ -136,47 +124,28 @@ class VmTurnZone {
136124 * ```
137125 */
138126 dynamic runOutsideAngular (fn ()) {
139- return _outerZone.runGuarded (fn);
140- }
141-
142- // Executes code in the [_innerZone] & trigger the onTurnStart hook when code is executed for the
143- // first time in a turn.
144- dynamic _innerRun (Zone self, ZoneDelegate parent, Zone zone, fn ()) {
145- _maybeStartVmTurn (parent, zone);
146- return parent.run (zone, fn);
147- }
148-
149- dynamic _innerRunUnary (Zone self, ZoneDelegate parent, Zone zone, fn (arg), arg) {
150- _maybeStartVmTurn (parent, zone);
151- return parent.runUnary (zone, fn, arg);
152- }
153-
154- dynamic _innerRunBinary (Zone self, ZoneDelegate parent, Zone zone, fn (arg1, arg2), arg1, arg2) {
155- _maybeStartVmTurn (parent, zone);
156- return parent.runBinary (zone, fn, arg1, arg2);
127+ return _outerZone.run (fn);
157128 }
158129
159- void _maybeStartVmTurn (ZoneDelegate parent, Zone zone ) {
130+ void _maybeStartVmTurn (ZoneDelegate parent) {
160131 if (! _hasExecutedCodeInInnerZone) {
161132 _hasExecutedCodeInInnerZone = true ;
162133 if (_onTurnStart != null ) {
163- _inTurnStart = true ;
164- parent.run (zone, _onTurnStart);
134+ parent.run (_innerZone, _onTurnStart);
165135 }
166136 }
167137 }
168138
169- dynamic _outerRun (Zone self, ZoneDelegate parent, Zone zone, fn ()) {
139+ dynamic _run (Zone self, ZoneDelegate parent, Zone zone, fn ()) {
170140 try {
171141 _nestedRun++ ;
142+ _maybeStartVmTurn (parent);
172143 return parent.run (zone, fn);
173144 } finally {
174145 _nestedRun-- ;
175- // If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
176- // _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
177- // to _outerRun()).
146+ // If there are no more pending microtasks and we are not in a recursive call, this is the end of a turn
178147 if (_pendingMicrotasks == 0 && _nestedRun == 0 ) {
179- if (_onTurnDone != null && ! _inTurnStart && _hasExecutedCodeInInnerZone) {
148+ if (_onTurnDone != null && _hasExecutedCodeInInnerZone) {
180149 // Trigger onTurnDone at the end of a turn if _innerZone has executed some code
181150 try {
182151 parent.run (_innerZone, _onTurnDone);
@@ -185,15 +154,14 @@ class VmTurnZone {
185154 }
186155 }
187156 }
188- _inTurnStart = false ;
189157 }
190158 }
191159
192- dynamic _outerRunUnary (Zone self, ZoneDelegate parent, Zone zone, fn (arg), arg) =>
193- _outerRun (self, parent, zone, () => fn (arg));
160+ dynamic _runUnary (Zone self, ZoneDelegate parent, Zone zone, fn (arg), arg) =>
161+ _run (self, parent, zone, () => fn (arg));
194162
195- dynamic _outerRunBinary (Zone self, ZoneDelegate parent, Zone zone, fn (arg1, arg2), arg1, arg2) =>
196- _outerRun (self, parent, zone, () => fn (arg1, arg2));
163+ dynamic _runBinary (Zone self, ZoneDelegate parent, Zone zone, fn (arg1, arg2), arg1, arg2) =>
164+ _run (self, parent, zone, () => fn (arg1, arg2));
197165
198166 void _scheduleMicrotask (Zone self, ZoneDelegate parent, Zone zone, fn) {
199167 _pendingMicrotasks++ ;
@@ -226,16 +194,16 @@ class VmTurnZone {
226194 }
227195 }
228196
229- Zone _createOuterZone (Zone zone, {handleUncaughtError}) {
197+ Zone _createInnerZone (Zone zone, {handleUncaughtError}) {
230198 return zone.fork (
231199 specification: new ZoneSpecification (
232200 scheduleMicrotask: _scheduleMicrotask,
233- run: _outerRun ,
234- runUnary: _outerRunUnary ,
235- runBinary: _outerRunBinary ,
201+ run: _run ,
202+ runUnary: _runUnary ,
203+ runBinary: _runBinary ,
236204 handleUncaughtError: handleUncaughtError
237205 ),
238- zoneValues: {'_name ' : 'outer' }
206+ zoneValues: {'_innerZone ' : true }
239207 );
240208 }
241209}
0 commit comments