Clean up of script timer code.

The code was split into the following two abstractions.
 - OneshotTimers can be used to schedule arbitrary oneshot timers, such
   as XHR-Timeouts.
 - JsTimers (`setTimeout` and `setInterval`) which use OneshotTimers to
   schedule individual callbacks.

With this change the implementation (of JsTimers in particular) is in
much closer alignment with the specification.
This commit is contained in:
benshu 2015-11-19 07:57:04 +01:00
parent 581aa1a14f
commit f2d4a7bbca
5 changed files with 371 additions and 277 deletions

View file

@ -59,7 +59,7 @@ use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};
use string_cache::Atom;
use time;
use timers::{ScheduledCallback, TimerHandle};
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::Url;
use url::percent_encoding::{utf8_percent_encode, USERNAME_ENCODE_SET, PASSWORD_ENCODE_SET};
use util::str::DOMString;
@ -146,7 +146,7 @@ pub struct XMLHttpRequest {
upload_events: Cell<bool>,
send_flag: Cell<bool>,
timeout_cancel: DOMRefCell<Option<TimerHandle>>,
timeout_cancel: DOMRefCell<Option<OneshotTimerHandle>>,
fetch_time: Cell<i64>,
generation_id: Cell<GenerationId>,
response_status: Cell<Result<(), ()>>,
@ -1055,39 +1055,15 @@ impl XMLHttpRequest {
self.dispatch_progress_event(false, type_, len, total);
}
fn set_timeout(&self, duration_ms: u32) {
#[derive(JSTraceable, HeapSizeOf)]
struct ScheduledXHRTimeout {
#[ignore_heap_size_of = "Because it is non-owning"]
xhr: Trusted<XMLHttpRequest>,
generation_id: GenerationId,
}
impl ScheduledCallback for ScheduledXHRTimeout {
fn invoke(self: Box<Self>) {
let this = *self;
let xhr = this.xhr.root();
if xhr.ready_state.get() != XMLHttpRequestState::Done {
xhr.process_partial_response(XHRProgress::Errored(this.generation_id, Error::Timeout));
}
}
fn box_clone(&self) -> Box<ScheduledCallback> {
box ScheduledXHRTimeout {
xhr: self.xhr.clone(),
generation_id: self.generation_id,
}
}
}
// Sets up the object to timeout in a given number of milliseconds
// This will cancel all previous timeouts
let global = self.global();
let callback = ScheduledXHRTimeout {
let callback = OneshotTimerCallback::XhrTimeout(XHRTimeoutCallback {
xhr: Trusted::new(self, global.r().networking_task_source()),
generation_id: self.generation_id.get(),
};
});
let duration = Length::new(duration_ms as u64);
*self.timeout_cancel.borrow_mut() = Some(global.r().schedule_callback(box callback, duration));
*self.timeout_cancel.borrow_mut() = Some(global.r().schedule_callback(callback, duration));
}
fn cancel_timeout(&self) {
@ -1368,6 +1344,22 @@ impl XMLHttpRequest {
}
}
#[derive(JSTraceable, HeapSizeOf)]
pub struct XHRTimeoutCallback {
#[ignore_heap_size_of = "Because it is non-owning"]
xhr: Trusted<XMLHttpRequest>,
generation_id: GenerationId,
}
impl XHRTimeoutCallback {
pub fn invoke(self) {
let xhr = self.xhr.root();
if xhr.ready_state.get() != XMLHttpRequestState::Done {
xhr.process_partial_response(XHRProgress::Errored(self.generation_id, Error::Timeout));
}
}
}
trait Extractable {
fn extract(&self) -> (Vec<u8>, Option<DOMString>);
}