Add isActive field on Timer.

BUG= http://dartbug.com/10010
R=floitsch@google.com

Review URL: https://codereview.chromium.org//18325006

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@24678 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
zarah@google.com
2013-07-02 12:01:11 +00:00
parent 1a5ccabf14
commit 01251efd5e
8 changed files with 155 additions and 47 deletions
+17 -3
View File
@@ -1360,6 +1360,16 @@ class TimerImpl implements Timer {
TimerImpl(int milliseconds, void callback())
: _once = true {
if (milliseconds == 0 && (!hasTimer() || _globalState.isWorker)) {
void internalCallback() {
_handle = null;
callback();
}
// Setting _handle to something different from null indicates that the
// callback has not been run. Hence, the choice of 1 is arbitrary.
_handle = 1;
// This makes a dependency between the async library and the
// event loop of the isolate library. The compiler makes sure
// that the event loop is compiled if [Timer] is used.
@@ -1367,15 +1377,17 @@ class TimerImpl implements Timer {
// loop instead of setTimeout, to make sure the futures get executed in
// order.
_globalState.topEventLoop.enqueue(
_globalState.currentContext, callback, 'timer');
_globalState.currentContext, internalCallback, 'timer');
_inEventLoop = true;
} else if (hasTimer()) {
_globalState.topEventLoop.activeTimerCount++;
void internalCallback() {
callback();
_handle = null;
_globalState.topEventLoop.activeTimerCount--;
callback();
}
_globalState.topEventLoop.activeTimerCount++;
_handle = JS('int', '#.setTimeout(#, #)',
globalThis,
convertDartClosureToJS(internalCallback, 0),
@@ -1416,6 +1428,8 @@ class TimerImpl implements Timer {
throw new UnsupportedError("Canceling a timer.");
}
}
bool get isActive => _handle != null;
}
bool hasTimer() => JS('', '#.setTimeout', globalThis) != null;
+10
View File
@@ -57,6 +57,16 @@ abstract class Timer {
* Cancels the timer.
*/
void cancel();
/**
* Returns whether the timer is still active.
*
* A non-periodic timer is active if the callback has not been executed,
* and the timer has not been canceled.
*
* A periodic timer is active if it has not been canceled.
*/
bool get isActive;
}
external Timer _createTimer(Duration duration, void callback());
+6 -7
View File
@@ -436,7 +436,6 @@ class _ZoneTimer implements Timer {
final _Zone _zone;
final _TimerCallback _callback;
Timer _timer;
bool _isDone = false;
_ZoneTimer(this._zone, Duration duration, this._callback) {
_zone.expectCallback();
@@ -444,15 +443,15 @@ class _ZoneTimer implements Timer {
}
void _run() {
_isDone = true;
_zone.executeCallbackGuarded(_callback);
}
void cancel() {
if (!_isDone) _zone.cancelCallbackExpectation();
_isDone = true;
if (_timer.isActive) _zone.cancelCallbackExpectation();
_timer.cancel();
}
bool get isActive => _timer.isActive;
}
typedef void _PeriodicTimerCallback(Timer timer);
@@ -464,7 +463,6 @@ class _PeriodicZoneTimer implements Timer {
final _Zone _zone;
final _PeriodicTimerCallback _callback;
Timer _timer;
bool _isDone = false;
_PeriodicZoneTimer(this._zone, Duration duration, this._callback) {
_zone.expectCallback();
@@ -477,10 +475,11 @@ class _PeriodicZoneTimer implements Timer {
}
void cancel() {
if (!_isDone) _zone.cancelCallbackExpectation();
_isDone = true;
if (_timer.isActive) _zone.cancelCallbackExpectation();
_timer.cancel();
}
bool get isActive => _timer.isActive;
}
/**
+35 -18
View File
@@ -31009,31 +31009,44 @@ final _pureIsolatePrintClosure = (s) {
final _forwardingPrintClosure = _Utils.forwardingPrint;
class _Timer implements Timer {
final canceller;
class _Timer implements Timer {
final _canceler;
_Timer(this.canceller);
_Timer(int milliSeconds, void callback(Timer timer), bool repeating) {
void cancel() { canceller(); }
if (repeating) {
int id = window._setInterval(() {
_canceler = null;
callback(this);
}, milliSeconds);)
_canceler = () => window._clearInterval(id);
} else {
int id = window._setTimeout(() {
_canceler = null;
callback(this);
}, milliSeconds); )
_canceler = window._clearTimeout(id);
}
}
void cancel() {
if (_canceler != null) {
_canceler();
}
_canceler = null;
}
bool get isActive => _canceler != null;
}
get _timerFactoryClosure => (int milliSeconds, void callback(Timer timer), bool repeating) {
var maker;
var canceller;
if (repeating) {
maker = window._setInterval;
canceller = window._clearInterval;
} else {
maker = window._setTimeout;
canceller = window._clearTimeout;
}
Timer timer;
final int id = maker(() { callback(timer); }, milliSeconds);
timer = new _Timer(() { canceller(id); });
return timer;
get _timerFactoryClosure =>
(int milliSeconds, void callback(Timer timer), bool repeating) {
return new _Timer(milliseconds, callback, repeating);
};
class _PureIsolateTimer implements Timer {
bool _isDone = false;
final ReceivePort _port = new ReceivePort();
SendPort _sendPort; // Effectively final.
@@ -31043,6 +31056,7 @@ class _PureIsolateTimer implements Timer {
_sendPort = _port.toSendPort();
_port.receive((msg, replyTo) {
assert(msg == _TIMER_PING);
_isDone = !repeating;
callback(this);
if (!repeating) _cancel();
});
@@ -31056,12 +31070,15 @@ class _PureIsolateTimer implements Timer {
}
void _cancel() {
_isDone = true;
_port.close();
}
_send(msg) {
_sendToHelperIsolate(msg, _sendPort);
}
bool get isActive => !_isDone;
}
get _pureIsolateTimerFactoryClosure =>
+7 -1
View File
@@ -50,6 +50,7 @@ class _Timer extends LinkedListEntry<_Timer> implements Timer {
bool get _repeating => _milliSeconds >= 0;
bool get isActive => _callback != null;
// Cancels a set timer. The timer is removed from the timer list and if
// the given timer is the earliest timer the native timer is reset.
@@ -143,7 +144,12 @@ class _Timer extends LinkedListEntry<_Timer> implements Timer {
// one of the later timers which will set the callback to
// null.
if (timer._callback != null) {
timer._callback(timer);
var callback = timer._callback;
if (!timer._repeating) {
//Mark timer as inactive.
timer._callback = null;
}
callback(timer);
// Re-insert repeating timer if not canceled.
if (timer._repeating && timer._callback != null) {
timer._advanceWakeupTime();
+45
View File
@@ -0,0 +1,45 @@
// Copyright (c) 2011, 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.
import 'dart:async';
import '../../../pkg/unittest/lib/unittest.dart';
main() {
test("timer isActive test", () {
Timer t;
t = new Timer(const Duration(seconds: 1),
expectAsync0(() => expect(t.isActive, equals(false))));
expect(t.isActive, equals(true));
});
test("periodic timer cancel test", () {
Timer t;
int i = 0;
void checkActive(Timer timer) {
expect(t.isActive, equals(true));
if (i == 2) {
t.cancel();
expect(t.isActive, equals(false));
}
i++;
}
t = new Timer.periodic(new Duration(milliseconds: 1),
expectAsync1(checkActive, count: 3));
expect(t.isActive, equals(true));
});
test("timer cancel test", () {
Timer timer = new Timer(const Duration(seconds: 1),
() => fail("Should not be reached."));
Timer.run(expectAsync0(() {
expect(timer.isActive, equals(true));
timer.cancel();
expect(timer.isActive, equals(false));
}));
});
}
+1
View File
@@ -59,6 +59,7 @@ async/stream_periodic4_test: Fail # Timer interface not supported; dartbug.com/7
async/stream_periodic5_test: Fail # Timer interface not supported; dartbug.com/7728.
async/run_zoned7_test: Fail # Timer interface not supported: dartbug.com/7728.
async/catch_errors22_test: Fail # Timer interface not supported: dartbug.com/7728.
async/timer_isActive_test: Fail # Timer interface not supported: dartbug.com/7728.
[ $compiler == dart2js && $browser ]
async/timer_not_available_test: Fail, OK # only meant to test when there is no way to
+34 -18
View File
@@ -198,31 +198,43 @@ final _pureIsolatePrintClosure = (s) {
final _forwardingPrintClosure = _Utils.forwardingPrint;
class _Timer implements Timer {
final canceller;
class _Timer implements Timer{
var _canceler;
_Timer(this.canceller);
_Timer(int milliSeconds, void callback(Timer timer), bool repeating) {
void cancel() { canceller(); }
if (repeating) {
int id = window._setInterval(() {
callback(this);
}, milliSeconds);)
_canceler = () => window._clearInterval(id);
} else {
int id = window._setTimeout(() {
_canceler = null;
callback(this);
}, milliSeconds);)
_canceler = () => window._clearTimeout(id);
}
}
void cancel() {
if (_canceler != null) {
_canceler();
}
_canceler = null;
}
bool get isActive => _canceler != null;
}
get _timerFactoryClosure => (int milliSeconds, void callback(Timer timer), bool repeating) {
var maker;
var canceller;
if (repeating) {
maker = window._setInterval;
canceller = window._clearInterval;
} else {
maker = window._setTimeout;
canceller = window._clearTimeout;
}
Timer timer;
final int id = maker(() { callback(timer); }, milliSeconds);
timer = new _Timer(() { canceller(id); });
return timer;
get _timerFactoryClosure =>
(int milliSeconds, void callback(Timer timer), bool repeating) {
return new _Timer(milliseconds, callback, repeating);
};
class _PureIsolateTimer implements Timer {
bool _isActive = true;
final ReceivePort _port = new ReceivePort();
SendPort _sendPort; // Effectively final.
@@ -232,6 +244,7 @@ class _PureIsolateTimer implements Timer {
_sendPort = _port.toSendPort();
_port.receive((msg, replyTo) {
assert(msg == _TIMER_PING);
_isActive = repeating;
callback(this);
if (!repeating) _cancel();
});
@@ -245,12 +258,15 @@ class _PureIsolateTimer implements Timer {
}
void _cancel() {
_isActive = false;
_port.close();
}
_send(msg) {
_sendToHelperIsolate(msg, _sendPort);
}
bool get isActive => _isActive;
}
get _pureIsolateTimerFactoryClosure =>