samedi 14 février 2015

Using trait methods in threads

Basically, I'm making a program that's listening to a bunch of ports and that handles incoming packets in different ways. I decide to bundle this code into a Trait:



trait Server {
pub fn new(port: u16) -> Self;

fn hostname(&self) -> String;

pub fn initialize(&self, detached: bool) {
let acceptor = TcpListener::bind(self.hostname().as_slice()).listen().unwrap();
Thread::spawn(move|| {
let mut acceptor = acceptor;
for incoming_stream in acceptor.incoming() {
match incoming_stream {
Ok(stream) => {
self.handle_client(stream);
},
Err(ref e) if e.kind == EndOfFile => break,
Err(e) => panic!("Unexpected error: {}", e),
}
}
});
}

fn handle_client(stream: TcpStream) -> ();
}


And each server would extend these methods. For example:



pub struct InternodeServer {
hostname: String,
}

impl Server for InternodeServer {
pub fn new(port: u16) -> InternodeServer {
let hostname = format!("127.0.0.1:{}", port);
InternodeServer {
hostname: hostname,
}
}

fn hostname(&self) -> String {
self.hostname
}

fn handle_client(stream: TcpStream) {
println!("Received connection");
let mut stream = stream;
let response = b"Hello\r\n";
let _ = stream.write_all(response);
let _ = stream.close_write();
}
}


However, this code won't work because &self isn't Thread-safe.


So I also tried making handle_client a static method to avoid self. However, I can't reference InternodeServer's static methods from Server's initialize method. If I use Server::handle_client, I get an error like:



error: type annotations required: cannot resolve `_ : internode::Server`


Is there any way around this?


Aucun commentaire:

Enregistrer un commentaire