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

Side by Side Diff: runtime/bin/timer_impl.dart

Issue 11337019: Use patching for dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 class _Timer implements Timer {
6 // Set jitter to wake up timer events that would happen in _TIMER_JITTER ms.
7 static const int _TIMER_JITTER = 0;
8
9 // Disables the timer.
10 static const int _NO_TIMER = -1;
11
12 static Timer _createTimer(void callback(Timer timer),
13 int milliSeconds,
14 bool repeating) {
15 _EventHandler._start();
16 if (_timers === null) {
17 _timers = new DoubleLinkedQueue<_Timer>();
18 }
19 Timer timer = new _Timer._internal();
20 timer._callback = callback;
21 timer._milliSeconds = milliSeconds;
22 timer._wakeupTime = (new Date.now()).millisecondsSinceEpoch + milliSeconds;
23 timer._repeating = repeating;
24 timer._addTimerToList();
25 timer._notifyEventHandler();
26 return timer;
27 }
28
29 factory _Timer(int milliSeconds, void callback(Timer timer)) {
30 return _createTimer(callback, milliSeconds, false);
31 }
32
33 factory _Timer.repeating(int milliSeconds, void callback(Timer timer)) {
34 return _createTimer(callback, milliSeconds, true);
35 }
36
37 _Timer._internal() {}
38
39 void _clear() {
40 _callback = null;
41 _milliSeconds = 0;
42 _wakeupTime = 0;
43 _repeating = false;
44 }
45
46
47 // Cancels a set timer. The timer is removed from the timer list and if
48 // the given timer is the earliest timer the native timer is reset.
49 void cancel() {
50 _clear();
51 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
52 DoubleLinkedQueueEntry<_Timer> first = _timers.firstEntry();
53
54 while (entry !== null) {
55 if (entry.element === this) {
56 entry.remove();
57 if (first.element == this) {
58 entry = _timers.firstEntry();
59 _notifyEventHandler();
60 }
61 return;
62 }
63 entry = entry.nextEntry();
64 }
65 }
66
67 void _advanceWakeupTime() {
68 _wakeupTime += _milliSeconds;
69 }
70
71 // Adds a timer to the timer list and resets the native timer if it is the
72 // earliest timer in the list. Timers with the same wakeup time are enqueued
73 // in order and notified in FIFO order.
74 void _addTimerToList() {
75 if (_callback !== null) {
76
77 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
78 while (entry !== null) {
79 if (_wakeupTime < entry.element._wakeupTime) {
80 entry.prepend(this);
81 return;
82 }
83 entry = entry.nextEntry();
84 }
85 _timers.addLast(this);
86 }
87 }
88
89
90 void _notifyEventHandler() {
91 if (_handling_callbacks) {
92 // While we are already handling callbacks we will not notify the event
93 // handler. _handleTimeout will call _notifyEventHandler once all pending
94 // timers are processed.
95 return;
96 }
97
98 if (_timers.firstEntry() === null) {
99 // No pending timers: Close the receive port and let the event handler
100 // know.
101 if (_receivePort !== null) {
102 _EventHandler._sendData(null, _receivePort, _NO_TIMER);
103 _shutdownTimerHandler();
104 }
105 } else {
106 if (_receivePort === null) {
107 // Create a receive port and register a message handler for the timer
108 // events.
109 _createTimerHandler();
110 }
111 _EventHandler._sendData(null,
112 _receivePort,
113 _timers.firstEntry().element._wakeupTime);
114 }
115 }
116
117
118 // Creates a receive port and registers the timer handler on that
119 // receive port.
120 void _createTimerHandler() {
121
122 void _handleTimeout() {
123 int currentTime =
124 (new Date.now()).millisecondsSinceEpoch + _TIMER_JITTER;
125
126 // Collect all pending timers.
127 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
128 var pending_timers = new List();
129 while (entry !== null) {
130 _Timer timer = entry.element;
131 if (timer._wakeupTime <= currentTime) {
132 entry.remove();
133 pending_timers.addLast(timer);
134 entry = _timers.firstEntry();
135 } else {
136 break;
137 }
138 }
139
140 // Trigger all of the pending timers. New timers added as part of the
141 // callbacks will be enqueued now and notified in the next spin at the
142 // earliest.
143 _handling_callbacks = true;
144 try {
145 for (var timer in pending_timers) {
146 // One of the timers in the pending_timers list can cancel
147 // one of the later timers which will set the callback to
148 // null.
149 if (timer._callback != null) {
150 timer._callback(timer);
151 if (timer._repeating) {
152 timer._advanceWakeupTime();
153 timer._addTimerToList();
154 }
155 }
156 }
157 } finally {
158 _handling_callbacks = false;
159 }
160 _notifyEventHandler();
161 }
162
163 if(_receivePort === null) {
164 _receivePort = new ReceivePort();
165 _receivePort.receive((var message, ignored) {
166 _handleTimeout();
167 });
168 }
169 }
170
171 void _shutdownTimerHandler() {
172 _receivePort.close();
173 _receivePort = null;
174 }
175
176
177 // Timers are ordered by wakeup time.
178 static DoubleLinkedQueue<_Timer> _timers;
179
180 static ReceivePort _receivePort;
181 static bool _handling_callbacks = false;
182
183 var _callback;
184 int _milliSeconds;
185 int _wakeupTime;
186 bool _repeating;
187 }
188
189 // Provide a closure which will allocate a Timer object to be able to hook
190 // up the Timer interface in dart:isolate with the implementation here.
191 _getTimerFactoryClosure() {
192 return (int milliSeconds, void callback(Timer timer), bool repeating) {
193 if (repeating) {
194 return new _Timer.repeating(milliSeconds, callback);
195 }
196 return new _Timer(milliSeconds, callback);
197 };
198 }
199
200
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698