Skip to content

what should we do in async with ownership with tcpstream? #563

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
aohan237 opened this issue Nov 20, 2019 · 8 comments
Closed

what should we do in async with ownership with tcpstream? #563

aohan237 opened this issue Nov 20, 2019 · 8 comments
Labels
duplicate This issue or pull request already exists

Comments

@aohan237
Copy link

what should we do in async with ownership if something like spawn task which uses tcpstreams, which requires a mut borrow of the stream if you want to read or write

@yoshuawuyts yoshuawuyts added the duplicate This issue or pull request already exists label Nov 20, 2019
@yoshuawuyts
Copy link
Contributor

@aohan237 Thanks for opening this issue. The way we're going to resolve this is by implementing Clone for TcpStream so it can be passed around without problem. See #553.

Because of interior mutability we don't need a mutable reference, but instead a normal reference is good enough. Which sidesteps a lot of issues. Prior discussion on this can also be found here: #365.

Because we already have two open issues about it, and a solution in the works, I'm going to go ahead and close this issue as "duplicate". Thanks heaps for filing; we hope we'll have a solution out soon!

@aohan237
Copy link
Author

@yoshuawuyts
let (reader, writer) = &mut (&stream, &stream); seems odd, as the read() requires a &mut self, and it seems not do anything about interior mutability , how this works?
thanks in advance

@ghost
Copy link

ghost commented Nov 21, 2019

@aohan237 If we implement Clone for TcpStream, you'd be able to do:

async fn process(mut stream: TcpStream) -> io::Result<()> {
    let mut dest = stream.clone();
    io::copy(&mut stream, &mut dest).await?;
    Ok(())
}

@aohan237
Copy link
Author

@stjepang sorry for my slow understandings.

io::copy seems that only copy steam content to dest, what's the different of simply copying the content?

and here is the scene:
such as we have to impl an tcp stream client, camunicating with a server

what if we have a task continously reads the stream, and multi task which can simutanously write different commands to the stream?

if implement clone for tcpstream, the writer seems mutex?
how can we do this?

still if we need to write then we need a mut borrow? i cant figure out how this works. is there any some docs can refer to ?

thanks in advance

@ghost
Copy link

ghost commented Nov 21, 2019

stream.clone() does not copy the contents of the stream, it only creates another handle to the same stream. TcpStream doesn't really need mutable access to read/write, that is only required by Read/Write traits. No mutex is therefore needed because the operating system will internally use a mutex on read/write operations.

@aohan237
Copy link
Author

you make it very clear. many thanks.

TcpStream doesn't really need mutable access to read/write, that is only required by Read/Write traits.

this make sense why let (reader, writer) = &mut (&stream, &stream); works.

but why cant we make use of the Arc? the Read/Write traits require only a mut borrow

@ghost
Copy link

ghost commented Nov 21, 2019

@aohan237 Arc<TcpStream> would also work, but it's more work :)

async fn process(stream: Arc<TcpStream>) -> io::Result<()> {
    let dest = stream.clone();
    io::copy(&mut &*stream, &mut &*dest).await?;
    Ok(())
}

@aohan237
Copy link
Author

@stjepang sorry for my late response.
thanks a lot. it really solves my problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants