aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavi Shankar <wafflespeanut@gmail.com>2015-11-07 20:44:12 +0530
committerRavi Shankar <wafflespeanut@gmail.com>2015-11-12 14:04:38 +0530
commitc4cf72db6e69cda90f4ad98933da95cead7da243 (patch)
tree5047b9fbb03eb53cbcfc62cd13abf4f89ec5cf6e
parent10f5584f78faac769f5b6807eaf683b79554a27f (diff)
downloadservo-c4cf72db6e69cda90f4ad98933da95cead7da243.tar.gz
servo-c4cf72db6e69cda90f4ad98933da95cead7da243.zip
Added support for synchronization along with an unit test for cancellation listener
-rw-r--r--components/net/resource_task.rs3
-rw-r--r--components/net_traits/lib.rs2
-rw-r--r--tests/unit/net/resource_task.rs54
3 files changed, 59 insertions, 0 deletions
diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs
index caf73c4a976..31993b8122a 100644
--- a/components/net/resource_task.rs
+++ b/components/net/resource_task.rs
@@ -187,6 +187,9 @@ impl ResourceChannelManager {
}
self.resource_manager.cancel_load_map.remove(&res_id);
}
+ ControlMsg::Synchronize(sender) => {
+ let _ = sender.send(());
+ }
ControlMsg::Exit => break,
}
}
diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs
index 5671ee200a1..f5e70489fd4 100644
--- a/components/net_traits/lib.rs
+++ b/components/net_traits/lib.rs
@@ -234,6 +234,8 @@ pub enum ControlMsg {
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
/// Cancel a network request corresponding to a given `ResourceId`
Cancel(ResourceId),
+ /// Synchronization message solely for knowing the state of the ResourceChannelManager loop
+ Synchronize(IpcSender<()>),
/// Break the load handler loop and exit
Exit,
}
diff --git a/tests/unit/net/resource_task.rs b/tests/unit/net/resource_task.rs
index 8d925082aa6..18d6a086e11 100644
--- a/tests/unit/net/resource_task.rs
+++ b/tests/unit/net/resource_task.rs
@@ -170,3 +170,57 @@ fn test_replace_hosts() {
let url = Url::parse("http://a.foo.bar.com").unwrap();
assert_eq!(host_replacement(host_table, &url).domain().unwrap(), "a.foo.bar.com");
}
+
+#[test]
+fn test_cancelled_listener() {
+ use std::io::Write;
+ use std::net::TcpListener;
+ use std::thread;
+
+ // http_loader always checks for headers in the response
+ let header = vec!["HTTP/1.1 200 OK",
+ "Server: test-server",
+ "Content-Type: text/plain",
+ "\r\n"];
+ let body = vec!["Yay!", "We're doomed!"];
+
+ // Setup a TCP server to which requests are made
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let port = listener.local_addr().unwrap().port();
+ let (body_sender, body_receiver) = channel();
+ thread::spawn(move || {
+ if let Ok((mut stream, _)) = listener.accept() {
+ // immediately stream the headers once the connection has been established
+ let _ = stream.write(header.join("\r\n").as_bytes());
+ // wait for the main thread to send the body, so as to ensure that we're
+ // doing everything sequentially
+ let body_vec: Vec<&str> = body_receiver.recv().unwrap();
+ let _ = stream.write(body_vec.join("\r\n").as_bytes());
+ }
+ });
+
+ let resource_task = new_resource_task("".to_owned(), None);
+ let (sender, receiver) = ipc::channel().unwrap();
+ let (id_sender, id_receiver) = ipc::channel().unwrap();
+ let (sync_sender, sync_receiver) = ipc::channel().unwrap();
+ let url = Url::parse(&format!("http://127.0.0.1:{}", port)).unwrap();
+
+ resource_task.send(ControlMsg::Load(LoadData::new(url, None),
+ LoadConsumer::Channel(sender),
+ Some(id_sender))).unwrap();
+ // get the `ResourceId` and send a cancel message, which should stop the loading loop
+ let res_id = id_receiver.recv().unwrap();
+ resource_task.send(ControlMsg::Cancel(res_id)).unwrap();
+ // synchronize with the resource_task loop, so that we don't simply send everything at once!
+ resource_task.send(ControlMsg::Synchronize(sync_sender)).unwrap();
+ let _ = sync_receiver.recv();
+ // now, let's send the body, because the connection is still active and data would be loaded
+ // (but, the loading has been cancelled)
+ let _ = body_sender.send(body);
+ let response = receiver.recv().unwrap();
+ match response.progress_port.recv().unwrap() {
+ ProgressMsg::Done(result) => assert_eq!(result.unwrap_err(), "load cancelled".to_owned()),
+ _ => panic!("baaaah!"),
+ }
+ resource_task.send(ControlMsg::Exit).unwrap();
+}