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

Unified Diff: lib/async/async_patch.dart

Issue 1375373004: Use the event-handler for timers. (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/shared/natives.h » ('j') | src/vm/event_handler_linux.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/async/async_patch.dart
diff --git a/lib/async/async_patch.dart b/lib/async/async_patch.dart
index 73e17c591831abde21912a15a47d1f40b6cb5b30..63f4e2fee86354073142772ab12025cfe57486f9 100644
--- a/lib/async/async_patch.dart
+++ b/lib/async/async_patch.dart
@@ -10,7 +10,6 @@ import 'dart:math';
const patch = "patch";
Channel _eventQueue;
-_FletchTimer _timers;
int _numberOfEvents = 0;
void _handleEvents() {
@@ -37,116 +36,69 @@ Channel _ensureEventQueue() {
}
}
-final int _maxWaitTimeInMilliseconds = 1000;
-
-final int _baseTime = new DateTime.now().millisecondsSinceEpoch;
-
int get _currentTimestamp {
- return new DateTime.now().millisecondsSinceEpoch - _baseTime;
+ return new DateTime.now().millisecondsSinceEpoch;
}
-// TODO(ager): This is a pretty horrible implementation. We should get
-// this integrated with the event loop. For now this is enough to show
-// that we can implement async on top of our current primitives.
+// TODO(ajohnsen): We should create a heap-like structure in Dart, so we only
+// have one active port/channel per process.
class _FletchTimer implements Timer {
final int _milliseconds;
var _callback;
int _timestamp = 0;
_FletchTimer _next;
bool _isActive = true;
- bool _hasActiveWaitFiber = false;
+ Channel _channel;
+ Port _port;
bool get _isPeriodic => _milliseconds >= 0;
_FletchTimer(this._timestamp, this._callback)
: _milliseconds = -1 {
+ _channel = new Channel();
+ _port = new Port(_channel);
_schedule();
- _forkWaitFiber();
}
_FletchTimer.periodic(this._timestamp,
void callback(Timer timer),
this._milliseconds) {
_callback = () { callback(this); };
+ _channel = new Channel();
+ _port = new Port(_channel);
_schedule();
- _forkWaitFiber();
}
- void _forkWaitFiber() {
- if (_timers != this) return;
- assert(!_hasActiveWaitFiber);
- _hasActiveWaitFiber = true;
+ void _schedule() {
Fiber.fork(() {
- var milliseconds = _timestamp - _currentTimestamp;
- if (milliseconds < 0) milliseconds = 0;
- // Cap the sleep time so that a timer that is set way in the
- // future will not cause the system to keep running if it is
- // cancelled.
- if (milliseconds > _maxWaitTimeInMilliseconds) {
- milliseconds = _maxWaitTimeInMilliseconds;
+ int value = _channel.receive();
+ if (value == 0 && _isActive) {
+ _callback();
+ if (_isPeriodic) {
+ _reschedule();
+ } else {
+ _isActive = false;
+ }
}
-
- Channel channel = new Channel();
- Port port = new Port(channel);
- Process.spawn((int milliseconds) {
- os.sleep(milliseconds);
- port.send(null);
- }, milliseconds);
- channel.receive();
-
- _hasActiveWaitFiber = false;
- _fireExpiredTimers();
});
- }
-
- void _fireExpiredTimers() {
- // Skip cancelled timers.
- while (_timers != null && !_timers._isActive) _timers = _timers._next;
- if (_timers != null) {
- // If first timer is expired, fire it and reschedule if it is
- // periodic.
- if (_currentTimestamp >= _timers._timestamp) {
- _AsyncRun._scheduleImmediate(_timers._callback);
- var current = _timers;
- _timers = _timers._next;
- if (current._isPeriodic) current._reschedule();
- }
- // Spin up a timer fiber if there isn't already one for
- // the next timer to fire.
- if (_timers != null && !_timers._hasActiveWaitFiber) {
- _timers._forkWaitFiber();
- }
- }
- }
-
- void _schedule() {
- var lastWithSmallerTimestamp = null;
- for (_FletchTimer current = _timers;
- current != null;
- current = current._next) {
- if (current._timestamp > _timestamp) break;
- lastWithSmallerTimestamp = current;
- }
- if (lastWithSmallerTimestamp == null) {
- _next = _timers;
- _timers = this;
- } else {
- _next = lastWithSmallerTimestamp._next;
- lastWithSmallerTimestamp._next = this;
- }
+ _scheduleTimeout(_timestamp, _port);
}
void _reschedule() {
assert(_isPeriodic);
- _timestamp = _currentTimestamp + _milliseconds;
+ _timestamp += _milliseconds;
_schedule();
}
void cancel() {
+ _scheduleTimeout(-1, _port);
+ _port.send(-1);
_isActive = false;
}
bool get isActive => _isActive;
+
+ @fletch.native external static void _scheduleTimeout(int timeout, Port port);
}
@patch class Timer {
« no previous file with comments | « no previous file | src/shared/natives.h » ('j') | src/vm/event_handler_linux.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698