Chromium Code Reviews| Index: sdk/lib/async/event_loop.dart |
| diff --git a/sdk/lib/async/event_loop.dart b/sdk/lib/async/event_loop.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..54e05f0e3d27a91d0d49b0bdcb3f7c4d391cee07 |
| --- /dev/null |
| +++ b/sdk/lib/async/event_loop.dart |
| @@ -0,0 +1,73 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +part of dart.async; |
| + |
| +typedef void _AsyncCallback(); |
| + |
| +bool _callbacksAreEnqueued = false; |
| +List<_AsyncCallback> _asyncCallbacks = <_AsyncCallback>[]; |
| + |
| +void _asyncRunCallback() { |
| + // As long as we are iterating over the registered callbacks we don't |
| + // unset the [_callbacksAreEnqueued] boolean. |
| + while (!_asyncCallbacks.isEmpty) { |
| + List callbacks = _asyncCallbacks; |
| + // Create a new list, to avoid that the we grow too much if the callbacks |
|
siva
2013/03/07 02:39:17
This comment does not read well.
floitsch
2013/03/08 20:04:41
done.
|
| + // add new callbacks themselves. |
| + _asyncCallbacks = <_AsyncCallback>[]; |
| + for (int i = 0; i < callbacks.length; i++) { |
| + Function callback = callbacks[i]; |
| + callbacks[i] = null; |
| + try { |
| + callback(); |
| + } catch (e) { |
| + List remainingCallbacks = |
| + _asyncCallbacks.getRange(i + 1, _asyncCallbacks.length - i + 1); |
|
siva
2013/03/07 02:39:17
shouldn't this be:
List remainingCallbacks = callb
floitsch
2013/03/08 20:04:41
Done.
|
| + List newCallbacks = _asyncCallbacks; |
| + _asyncCallbacks = <_AsyncCallback>[]; |
| + _asyncCallbacks.addAll(remainingCallbacks); |
| + _asyncCallbacks.addAll(newCallbacks); |
| + _AsyncRun._enqueueImmediate(_asyncRunCallback); |
| + throw; |
| + } |
| + } |
| + } |
| + // Any new callback must register a callback function now. |
| + _callbacksAreEnqueued = false; |
| +} |
| + |
| +/** |
| + * Runs the given [callback] asynchronously. |
| + * |
| + * Callbacks register through this function are always executed in order and |
|
siva
2013/03/07 02:39:17
registered
floitsch
2013/03/08 20:04:41
Done.
|
| + * are guaranteed to run before other asynchronous events (like [Timer] events, |
| + * or DOM events). |
| + * |
| + * Warning: it is possible to starve the DOM by registering asynchronous |
| + * callbacks through this method. For example the following program will |
| + * run the callbacks without ever giving the Timer callback a chance to execute: |
| + * |
| + * Timer.run(() { print("executed"); }); // Will never be executed; |
| + * foo() { |
| + * asyncRun(foo); // Schedules [foo] in front of other events. |
| + * } |
| + * main() { |
| + * foo(); |
| + * } |
| + */ |
| +void runAsync(void callback()) { |
| + // Optimizing a group of Timer.run callbacks to be executed in the |
| + // same Timer callback. |
| + _asyncCallbacks.add(callback); |
| + if (!_callbacksAreEnqueued) { |
| + _AsyncRun._enqueueImmediate(_asyncRunCallback); |
| + _callbacksAreEnqueued = true; |
| + } |
| +} |
| + |
| +class _AsyncRun { |
| + /** Enqueues the given callback before any other event in the event-loop. */ |
| + external static void _enqueueImmediate(void callback()); |
| +} |