aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorAleksandr Likhanov <vegayours@gmail.com>2015-12-02 02:09:50 +0500
committerAleksandr Likhanov <vegayours@gmail.com>2015-12-04 20:16:43 +0500
commitd891e75d9d51a4349c5e15af0d99b4a2cb7c8ac7 (patch)
treefcf920361788d4980d5ddfdb175e0311eac9a068 /components/script
parenta8cbc2864367da09fb31fb5f984a7b2d31b90b93 (diff)
downloadservo-d891e75d9d51a4349c5e15af0d99b4a2cb7c8ac7.tar.gz
servo-d891e75d9d51a4349c5e15af0d99b4a2cb7c8ac7.zip
fix intermittent Option::unwrap in timers
not allow to fire timers installed during another timer call
Diffstat (limited to 'components/script')
-rw-r--r--components/script/timers.rs22
1 files changed, 14 insertions, 8 deletions
diff --git a/components/script/timers.rs b/components/script/timers.rs
index 4b8a2b6d272..7e164bbe5eb 100644
--- a/components/script/timers.rs
+++ b/components/script/timers.rs
@@ -23,7 +23,7 @@ use std::rc::Rc;
use util::mem::HeapSizeOf;
use util::str::DOMString;
-#[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord)]
+#[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord, Debug)]
pub struct TimerHandle(i32);
#[derive(JSTraceable, HeapSizeOf)]
@@ -253,16 +253,22 @@ impl ActiveTimers {
// Since the event id was the expected one, at least one timer should be due.
assert!(base_time >= self.timers.borrow().last().unwrap().next_call);
+ // select timers to run to prevent firing timers
+ // that were installed during fire of another timer
+ let mut timers_to_run: Vec<Timer> = Vec::new();
+
loop {
- let timer = {
- let mut timers = self.timers.borrow_mut();
+ let mut timers = self.timers.borrow_mut();
- if timers.is_empty() || timers.last().unwrap().next_call > base_time {
- break;
- }
+ if timers.is_empty() || timers.last().unwrap().next_call > base_time {
+ break;
+ }
+
+ timers_to_run.push(timers.pop().unwrap());
+ }
+
+ for timer in timers_to_run {
- timers.pop().unwrap()
- };
let callback = timer.callback.clone();
// prep for step 6 in nested set_timeout_or_interval calls