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

Side by Side Diff: bin/timer_impl.dart

Issue 8973005: Fix bug 846: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 9 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class _Timer implements Timer { 5 class _Timer implements Timer {
6 6
7 /* 7 /*
8 * Set jitter to wake up timer events that would happen in _TIMER_JITTER ms. 8 * Set jitter to wake up timer events that would happen in _TIMER_JITTER ms.
9 */ 9 */
10 static final int _TIMER_JITTER = 0; 10 static final int _TIMER_JITTER = 0;
11 11
12 /* 12 /*
13 * Disables the timer. 13 * Disables the timer.
14 */ 14 */
15 static final int _NO_TIMER = -1; 15 static final int _NO_TIMER = -1;
16 16
17 factory _Timer(void callback(Timer timer), 17 factory _Timer(void callback(Timer timer),
18 int milliSeconds, 18 int milliSeconds,
19 bool repeating) { 19 bool repeating) {
20 EventHandler._start(); 20 EventHandler._start();
21 if (_timers === null) { 21 if (_timers === null) {
22 _timers = new DoubleLinkedQueue<_Timer>(); 22 _timers = new DoubleLinkedQueue<_Timer>();
23 } 23 }
24 Timer timer = new _Timer._internal(); 24 Timer timer = new _Timer._internal();
25 timer._callback = callback; 25 timer._callback = callback;
26 timer._milliSeconds = milliSeconds; 26 timer._milliSeconds = milliSeconds;
27 timer._wakeupTime = (new Date.now()).value + milliSeconds; 27 timer._wakeupTime = (new Date.now()).value + milliSeconds;
28 timer._repeating = repeating; 28 timer._repeating = repeating;
29 timer._addTimerToList(); 29 timer._addTimerToList();
30 timer._notifyEventHandler(); 30 timer._notifyEventHandler();
siva 2011/12/16 01:42:02 We need to call notifyEventHandler only if addTime
31 return timer; 31 return timer;
32 } 32 }
33 33
34 _Timer._internal() {} 34 _Timer._internal() {}
35 35
36 void _clear() { 36 void _clear() {
37 _callback = null; 37 _callback = null;
38 _milliSeconds = 0; 38 _milliSeconds = 0;
39 _wakeupTime = 0; 39 _wakeupTime = 0;
40 _repeating = false; 40 _repeating = false;
(...skipping 27 matching lines...) Expand all
68 68
69 /* 69 /*
70 * Adds a timer to the timer list and resets the native timer if it is the 70 * Adds a timer to the timer list and resets the native timer if it is the
71 * earliest timer in the list. Timers with the same wakeup time are enqueued 71 * earliest timer in the list. Timers with the same wakeup time are enqueued
72 * in order and notified in FIFO order. 72 * in order and notified in FIFO order.
73 */ 73 */
74 void _addTimerToList() { 74 void _addTimerToList() {
75 if (_callback !== null) { 75 if (_callback !== null) {
76 76
77 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry(); 77 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
78 if (entry === null) {
79 _createTimerHandler();
80 }
81
82 while (entry !== null) { 78 while (entry !== null) {
83 if (_wakeupTime < entry.element._wakeupTime) { 79 if (_wakeupTime < entry.element._wakeupTime) {
84 entry.prepend(this); 80 entry.prepend(this);
85 return; 81 return;
86 } 82 }
87 entry = entry.nextEntry(); 83 entry = entry.nextEntry();
88 } 84 }
89 _timers.addLast(this); 85 _timers.addLast(this);
90 } 86 }
91 } 87 }
92 88
93 89
94 void _notifyEventHandler() { 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
95 if (_timers.firstEntry() === null) { 98 if (_timers.firstEntry() === null) {
99 // No pending timers: Close the receive port and let the event handler
100 // know.
96 if (_receivePort !== null) { 101 if (_receivePort !== null) {
97 EventHandler._sendData(-1, _receivePort, _NO_TIMER); 102 EventHandler._sendData(-1, _receivePort, _NO_TIMER);
98 _shutdownTimerHandler(); 103 _shutdownTimerHandler();
99 } 104 }
100 } else { 105 } else {
106 if (_receivePort === null) {
107 // Create a receive port and register a message handler for the timer
108 // events.
109 _createTimerHandler();
110 }
101 EventHandler._sendData(-1, 111 EventHandler._sendData(-1,
102 _receivePort, 112 _receivePort,
103 _timers.firstEntry().element._wakeupTime); 113 _timers.firstEntry().element._wakeupTime);
104 } 114 }
105 } 115 }
106 116
107 117
108 /* 118 /*
109 * Creates a receive port and registers the timer handler on that receive 119 * Creates a receive port and registers the timer handler on that receive
110 * port. 120 * port.
111 */ 121 */
112 void _createTimerHandler() { 122 void _createTimerHandler() {
113 123
114 void _handleTimeout() { 124 void _handleTimeout() {
115 int currentTime = (new Date.now()).value + _TIMER_JITTER; 125 int currentTime = (new Date.now()).value + _TIMER_JITTER;
116 126
127 // Collect all pending timers.
117 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry(); 128 DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
129 var pending_timers = new List();
118 while (entry !== null) { 130 while (entry !== null) {
119 _Timer timer = entry.element; 131 _Timer timer = entry.element;
120 if (timer._wakeupTime <= currentTime) { 132 if (timer._wakeupTime <= currentTime) {
121 entry.remove(); 133 entry.remove();
122 timer._callback(timer); 134 pending_timers.addLast(timer);
123 // Always process the event with the earliest wakeupTime first.
124 entry = _timers.firstEntry(); 135 entry = _timers.firstEntry();
125 if (timer._repeating) {
126 timer._advanceWakeupTime();
127 timer._addTimerToList();
128 _notifyEventHandler();
129 }
130 } else { 136 } else {
131 break; 137 break;
132 } 138 }
133 } 139 }
140
141 // Trigger all of the pending timers. New timers added as part of the
142 // callbacks will be enqueued now and notified in the next spin at the
143 // earliest.
144 _handling_callbacks = true;
145 try {
146 for (var timer in pending_timers) {
147 timer._callback(timer);
148 if (timer._repeating) {
149 timer._advanceWakeupTime();
150 timer._addTimerToList();
151 }
152 }
153 } finally {
154 _handling_callbacks = false;
155 }
134 _notifyEventHandler(); 156 _notifyEventHandler();
135 } 157 }
136 158
137 if(_receivePort === null) { 159 if(_receivePort === null) {
138 _receivePort = new ReceivePort(); 160 _receivePort = new ReceivePort();
139 _receivePort.receive((var message, ignored) { 161 _receivePort.receive((var message, ignored) {
140 _handleTimeout(); 162 _handleTimeout();
141 }); 163 });
142 } 164 }
143 } 165 }
144 166
145 void _shutdownTimerHandler() { 167 void _shutdownTimerHandler() {
146 _receivePort.close(); 168 _receivePort.close();
147 _receivePort = null; 169 _receivePort = null;
148 } 170 }
149 171
150 172
151 /* 173 /*
152 * Timers are ordered by wakeup time. 174 * Timers are ordered by wakeup time.
153 */ 175 */
154 static DoubleLinkedQueue<_Timer> _timers; 176 static DoubleLinkedQueue<_Timer> _timers;
155 177
156 static ReceivePort _receivePort; 178 static ReceivePort _receivePort;
179 static bool _handling_callbacks = false;
157 180
158 var _callback; 181 var _callback;
159 int _milliSeconds; 182 int _milliSeconds;
160 int _wakeupTime; 183 int _wakeupTime;
161 bool _repeating; 184 bool _repeating;
162 } 185 }
163 186
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698