net: Use a thread for each AsyncResponseTarget to avoid having to send

trait objects across process boundaries.
This commit is contained in:
Patrick Walton 2015-07-09 16:50:06 -07:00
parent 9c9d7dc93b
commit 44d13f7fd4
10 changed files with 78 additions and 31 deletions

View file

@ -14,6 +14,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem;
use std::sync::Arc;
use std::sync::mpsc::{channel, Sender, Receiver, Select};
use std::thread;
use util::resource_files::resources_dir_path;
use util::task::spawn_named;
use util::taskpool::TaskPool;
@ -100,14 +101,17 @@ struct ResourceLoadInfo {
struct ResourceListener {
url: Url,
sender: Sender<ResourceLoadInfo>,
receiver: Receiver<ResponseAction>,
}
impl AsyncResponseTarget for ResourceListener {
fn invoke_with_listener(&self, action: ResponseAction) {
self.sender.send(ResourceLoadInfo {
action: action,
url: self.url.clone(),
}).unwrap();
impl ResourceListener {
fn run(&self) {
while let Ok(action) = self.receiver.recv() {
self.sender.send(ResourceLoadInfo {
action: action,
url: self.url.clone(),
}).unwrap();
}
}
}
@ -330,11 +334,17 @@ impl ImageCache {
e.insert(pending_load);
let load_data = LoadData::new(url.clone(), None);
let (action_sender, action_receiver) = channel();
let listener = box ResourceListener {
url: url,
sender: self.progress_sender.clone(),
receiver: action_receiver,
};
let msg = ControlMsg::Load(load_data, LoadConsumer::Listener(listener));
let msg = ControlMsg::Load(load_data,
LoadConsumer::Listener(AsyncResponseTarget {
sender: action_sender,
}));
thread::spawn(move || listener.run());
self.resource_task.send(msg).unwrap();
}
}