dpc / mioco.pre-0.9

Scalable, coroutine-based, asynchronous IO handling library for Rust programming language. (aka MIO COroutines).
Mozilla Public License 2.0
457 stars 30 forks source link

Prevent using mioco types from multiple thread(coroutines) at the same time. #144

Open dpc opened 8 years ago

dpc commented 8 years ago

Reported originally in #122

let mut remote: TcpStream = ...;
let mut origin = try!(TcpStream::connect(&addr));

let mut remote2 = try!(remote.try_clone());
let mut origin2 = try!(origin.try_clone());

mioco::spawn(move || -> io::Result<()> {
    let mut buf = [0; 1024];
    loop {
        let size = try!(remote2.read(&mut buf));
        if size == 0 {
            break;
        }
        origin2.write_all(&buf[..size]);
    }
    Ok(())
});

mioco::spawn(move || -> io::Result<()> {
    let mut buf = [0; 1024];
    loop {
        let size = try!(origin.read(&mut buf));
        if size == 0 {
            break;
        }
        remote.write_all(&buf[..size]);
    }
    Ok(())
});

try_clone must return a deep clone (new fd), or not work at all. Also: make sure mioco types can't be used from multiple threads/coroutines at the same time.

dpc commented 8 years ago

@sbstp: Do you happen to have a full example?

sbstp commented 8 years ago

Unfortunately I don't. I no longer have the code that does this. I rewrote it using select! and it looks much better and uses a single coroutine. What I gave you in the other issue is a partial reconstruction of what it looked like.

dpc commented 8 years ago

I think for whatever reason try_clone did not dup the actual fd. I need to reproduce and investigate more