tokio-rs / tokio-core

I/O primitives and event loop for async I/O in Rust
Apache License 2.0
638 stars 115 forks source link

Problem with global variable lifetime in a single threaded context. #300

Closed George3d6 closed 6 years ago

George3d6 commented 6 years ago

I have the following code:

fn main() {
    let status_map = HashMap::new();

    let listener = TcpListener::bind(&"127.0.0.1:1478".parse().unwrap()).unwrap();
    let receptor = listener.incoming().for_each(move |stream| {
        let (reader, _) = stream.split();
        let conn = io::read_to_end(reader, Vec::new()).then(|res| {
            let entry = status_map.entry('test').or_insert(vec![1]);
            Ok(())
        });
        current_thread::spawn(conn);
        Ok(())
    })
    .map_err(|err| {
        println!("IO error {:?}", err);
    });

    current_thread::run(move |_| {
        current_thread::spawn(receptor);
    });
}

Which refuses to compile with the error status_map does not live long enough

Seeing as status_map is declared in the outermost scope and the server is multithreaded, why would this happen ? Is there a way to achieve what I'm trying (accessing a variable declared inside main from inside the Future object).

carllerche commented 6 years ago

current_thread::spawn requires a 'static bound. This is because there is no guarantee that the stack stays around.

In your example, it looks like you can add some move statements to your callbacks to move status_map into the inner closure, then it should work.