summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbokuweb <bokuweb@users.noreply.github.com>2019-01-27 06:10:38 +0900
committerBert Belder <bertbelder@gmail.com>2019-01-26 22:10:38 +0100
commitaaaa35548e146348a7f0c417e7ae64889fe744fb (patch)
treee2105792dba1b59594b0e5341782f31c93b889de
parent19b2d4a62a7c4a0d323ea9307410e5afe00a4871 (diff)
timers: use int instead of double for timeout type (#1469)
-rw-r--r--js/timers.ts13
-rw-r--r--js/timers_test.ts9
-rw-r--r--src/msg.fbs2
-rw-r--r--src/ops.rs3
4 files changed, 24 insertions, 3 deletions
diff --git a/js/timers.ts b/js/timers.ts
index 96bfc8c0f..9e9c312ee 100644
--- a/js/timers.ts
+++ b/js/timers.ts
@@ -25,6 +25,9 @@ interface Timer {
const EPOCH = Date.now();
const APOCALYPSE = 2 ** 32 - 2;
+// Timeout values > TIMEOUT_MAX are set to 1.
+const TIMEOUT_MAX = 2 ** 31 - 1;
+
let globalTimeoutDue: number | null = null;
let nextTimerId = 1;
@@ -50,6 +53,7 @@ function setGlobalTimeout(due: number | null, now: number) {
timeout = due - now;
assert(timeout >= 0);
}
+
// Send message to the backend.
const builder = flatbuffers.createBuilder();
msg.SetTimeout.startSetTimeout(builder);
@@ -181,7 +185,16 @@ function setTimer(
// and INT32_MAX. Any other value will cause the timer to fire immediately.
// We emulate this behavior.
const now = getTime();
+ if (delay > TIMEOUT_MAX) {
+ console.warn(
+ `${delay} does not fit into` +
+ " a 32-bit signed integer." +
+ "\nTimeout duration was set to 1."
+ );
+ delay = 1;
+ }
delay = Math.max(0, delay | 0);
+
// Create a new, unscheduled timer object.
const timer = {
id: nextTimerId++,
diff --git a/js/timers_test.ts b/js/timers_test.ts
index 1ea566c43..fe2ff64df 100644
--- a/js/timers_test.ts
+++ b/js/timers_test.ts
@@ -155,3 +155,12 @@ test(async function intervalCancelInvalidSilentFail() {
// Should silently fail (no panic)
clearInterval(2147483647);
});
+
+test(async function fireCallbackImmediatelyWhenDelayOverMaxValue() {
+ let count = 0;
+ setTimeout(() => {
+ count++;
+ }, 2 ** 31);
+ await waitForMs(1);
+ assertEqual(count, 1);
+});
diff --git a/src/msg.fbs b/src/msg.fbs
index 4b303535f..e13b15daa 100644
--- a/src/msg.fbs
+++ b/src/msg.fbs
@@ -202,7 +202,7 @@ table Chdir {
}
table SetTimeout {
- timeout: double;
+ timeout: int;
}
table Exit {
diff --git a/src/ops.rs b/src/ops.rs
index f3c80e1ac..85a731c6a 100644
--- a/src/ops.rs
+++ b/src/ops.rs
@@ -338,8 +338,7 @@ fn op_set_timeout(
) -> Box<Op> {
assert_eq!(data.len(), 0);
let inner = base.inner_as_set_timeout().unwrap();
- // FIXME why is timeout a double if it's cast immediately to i64/u64??
- let val = inner.timeout() as i64;
+ let val = inner.timeout();
let timeout_due = if val >= 0 {
Some(Instant::now() + Duration::from_millis(val as u64))
} else {