aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/eventsource.rs46
1 files changed, 39 insertions, 7 deletions
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index 34fd2d427fb..780d4563469 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -31,6 +31,9 @@ use url::Url;
header! { (LastEventId, "Last-Event-ID") => [String] }
#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)]
+struct GenerationId(u32);
+
+#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)]
/// https://html.spec.whatwg.org/multipage/#dom-eventsource-readystate
enum ReadyState {
Connecting = 0,
@@ -43,18 +46,24 @@ pub struct EventSource {
eventtarget: EventTarget,
url: DOMRefCell<Option<Url>>,
request: DOMRefCell<Option<RequestInit>>,
+ last_event_id: DOMRefCell<DOMString>,
+ generation_id: Cell<GenerationId>,
+
ready_state: Cell<ReadyState>,
with_credentials: bool,
- last_event_id: DOMRefCell<DOMString>
}
struct EventSourceContext {
- event_source: Trusted<EventSource>
+ event_source: Trusted<EventSource>,
+ gen_id: GenerationId
}
impl EventSourceContext {
fn announce_the_connection(&self) {
let event_source = self.event_source.root();
+ if self.gen_id != event_source.generation_id.get() {
+ return;
+ }
let runnable = box AnnounceConnectionRunnable {
event_source: self.event_source.clone()
};
@@ -63,6 +72,9 @@ impl EventSourceContext {
fn fail_the_connection(&self) {
let event_source = self.event_source.root();
+ if self.gen_id != event_source.generation_id.get() {
+ return;
+ }
let runnable = box FailConnectionRunnable {
event_source: self.event_source.clone()
};
@@ -78,13 +90,23 @@ impl EventSourceContext {
event_source: self.event_source.clone(),
done_chan: sender
};
+ if self.gen_id != self.event_source.root().generation_id.get() {
+ return;
+ }
let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
// Step 4
+ if self.gen_id != self.event_source.root().generation_id.get() {
+ return;
+ }
let _ = receiver.recv();
// Step 5
let runnable = box RefetchRequestRunnable {
event_source: self.event_source.clone(),
+ gen_id: self.gen_id
};
+ if self.gen_id != self.event_source.root().generation_id.get() {
+ return;
+ }
let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
}
}
@@ -129,7 +151,11 @@ impl FetchResponseListener for EventSourceContext {
}
}
-impl PreInvoke for EventSourceContext {}
+impl PreInvoke for EventSourceContext {
+ fn should_invoke(&self) -> bool {
+ self.event_source.root().generation_id.get() == self.gen_id
+ }
+}
impl EventSource {
fn new_inherited(with_credentials: bool) -> EventSource {
@@ -137,9 +163,11 @@ impl EventSource {
eventtarget: EventTarget::new_inherited(),
url: DOMRefCell::new(None),
request: DOMRefCell::new(None),
+ last_event_id: DOMRefCell::new(DOMString::from("")),
+ generation_id: Cell::new(GenerationId(0)),
+
ready_state: Cell::new(ReadyState::Connecting),
with_credentials: with_credentials,
- last_event_id: DOMRefCell::new(DOMString::from(""))
}
}
@@ -202,7 +230,8 @@ impl EventSource {
*ev.request.borrow_mut() = Some(request.clone());
// Step 14
let context = EventSourceContext {
- event_source: Trusted::new(&ev)
+ event_source: Trusted::new(&ev),
+ gen_id: ev.generation_id.get()
};
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),
@@ -246,8 +275,9 @@ impl EventSourceMethods for EventSource {
// https://html.spec.whatwg.org/multipage/#dom-eventsource-close
fn Close(&self) {
+ let GenerationId(prev_id) = self.generation_id.get();
+ self.generation_id.set(GenerationId(prev_id + 1));
self.ready_state.set(ReadyState::Closed);
- // TODO: Terminate ongoing fetch
}
}
@@ -311,6 +341,7 @@ impl Runnable for ReestablishConnectionRunnable {
pub struct RefetchRequestRunnable {
event_source: Trusted<EventSource>,
+ gen_id: GenerationId
}
impl Runnable for RefetchRequestRunnable {
@@ -332,7 +363,8 @@ impl Runnable for RefetchRequestRunnable {
}
// Step 5.4
let context = EventSourceContext {
- event_source: self.event_source.clone()
+ event_source: self.event_source.clone(),
+ gen_id: self.gen_id
};
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),