|
11 | 11 | #include <cxxreact/ErrorUtils.h>
|
12 | 12 | #include <react/featureflags/ReactNativeFeatureFlags.h>
|
13 | 13 | #include <react/renderer/debug/SystraceSection.h>
|
| 14 | +#include <react/utils/SetForScope.h> |
14 | 15 | #include <utility>
|
15 | 16 | #include "ErrorUtils.h"
|
16 | 17 |
|
17 | 18 | namespace facebook::react {
|
18 | 19 |
|
19 |
| -namespace { |
20 |
| -/** |
21 |
| - * This is partially equivalent to the "Perform a microtask checkpoint" step in |
22 |
| - * the Web event loop. See |
23 |
| - * https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint. |
24 |
| - * |
25 |
| - * Iterates on \c drainMicrotasks until it completes or hits the retries bound. |
26 |
| - */ |
27 |
| -void executeMicrotasks(jsi::Runtime& runtime) { |
28 |
| - SystraceSection s("RuntimeScheduler::executeMicrotasks"); |
29 |
| - |
30 |
| - uint8_t retries = 0; |
31 |
| - // A heuristic number to guard infinite or absurd numbers of retries. |
32 |
| - const static unsigned int kRetriesBound = 255; |
33 |
| - |
34 |
| - while (retries < kRetriesBound) { |
35 |
| - try { |
36 |
| - // The default behavior of \c drainMicrotasks is unbounded execution. |
37 |
| - // We may want to make it bounded in the future. |
38 |
| - if (runtime.drainMicrotasks()) { |
39 |
| - break; |
40 |
| - } |
41 |
| - } catch (jsi::JSError& error) { |
42 |
| - handleJSError(runtime, error, true); |
43 |
| - } |
44 |
| - retries++; |
45 |
| - } |
46 |
| - |
47 |
| - if (retries == kRetriesBound) { |
48 |
| - throw std::runtime_error("Hits microtasks retries bound."); |
49 |
| - } |
50 |
| -} |
51 |
| -} // namespace |
52 |
| - |
53 | 20 | #pragma mark - Public
|
54 | 21 |
|
55 | 22 | RuntimeScheduler_Modern::RuntimeScheduler_Modern(
|
@@ -298,7 +265,7 @@ void RuntimeScheduler_Modern::executeTask(
|
298 | 265 |
|
299 | 266 | if (ReactNativeFeatureFlags::enableMicrotasks()) {
|
300 | 267 | // "Perform a microtask checkpoint" step.
|
301 |
| - executeMicrotasks(runtime); |
| 268 | + performMicrotaskCheckpoint(runtime); |
302 | 269 | }
|
303 | 270 |
|
304 | 271 | if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) {
|
@@ -339,4 +306,43 @@ void RuntimeScheduler_Modern::executeMacrotask(
|
339 | 306 | }
|
340 | 307 | }
|
341 | 308 |
|
| 309 | +/** |
| 310 | + * This is partially equivalent to the "Perform a microtask checkpoint" step in |
| 311 | + * the Web event loop. See |
| 312 | + * https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint. |
| 313 | + * |
| 314 | + * Iterates on \c drainMicrotasks until it completes or hits the retries bound. |
| 315 | + */ |
| 316 | +void RuntimeScheduler_Modern::performMicrotaskCheckpoint( |
| 317 | + jsi::Runtime& runtime) { |
| 318 | + SystraceSection s("RuntimeScheduler::performMicrotaskCheckpoint"); |
| 319 | + |
| 320 | + if (performingMicrotaskCheckpoint_) { |
| 321 | + return; |
| 322 | + } |
| 323 | + |
| 324 | + SetForScope change(performingMicrotaskCheckpoint_, true); |
| 325 | + |
| 326 | + uint8_t retries = 0; |
| 327 | + // A heuristic number to guard infinite or absurd numbers of retries. |
| 328 | + const static unsigned int kRetriesBound = 255; |
| 329 | + |
| 330 | + while (retries < kRetriesBound) { |
| 331 | + try { |
| 332 | + // The default behavior of \c drainMicrotasks is unbounded execution. |
| 333 | + // We may want to make it bounded in the future. |
| 334 | + if (runtime.drainMicrotasks()) { |
| 335 | + break; |
| 336 | + } |
| 337 | + } catch (jsi::JSError& error) { |
| 338 | + handleJSError(runtime, error, true); |
| 339 | + } |
| 340 | + retries++; |
| 341 | + } |
| 342 | + |
| 343 | + if (retries == kRetriesBound) { |
| 344 | + throw std::runtime_error("Hits microtasks retries bound."); |
| 345 | + } |
| 346 | +} |
| 347 | + |
342 | 348 | } // namespace facebook::react
|
0 commit comments