Closed fafhrd91 closed 2 months ago
Yes. The cloned stream cannot be closed until the original one is dropped. It is just waiting for that. If you still want to use the stream, no need to close the cloned one.
thank. would be great to see this info in doc string
I slightly modified example, it still doesn't work even if I try to close original stream.
here is modification:
async fn read(mut io: TcpStream) {
let buf = Vec::with_capacity(1024);
let BufResult(_, buf) = io.read(buf).await;
let mut rd = io.clone();
compio::runtime::spawn(write(io, buf)).detach();
let buf = Vec::with_capacity(1024);
let BufResult(_, buf) = rd.read(buf).await;
}
async fn write(mut io: TcpStream, buf: Vec<u8>) {
println!("Writing {:?}", buf);
io.write(buf).await.0.unwrap();
// this line never completes
io.close().await.unwrap();
}
That's because rd
is still reading and not dropped. io
is waiting for it.
so it is not possible to close tcp stream while reading?
Yes. The read operation is submitted to the kernel, and it can only be closed after all related operations are completed.
It is a little helpless, but mainly for safety. The polling driver needs to ensure that the file descriptor is valid when the operation is completed.
what will happen if I drop io.read()
future? is it safe to drop read/write operations?
It is safe to drop the futures, but the operation may not be cancelled immediately, depends on the current state of the driver and the kernel. Finally, the operation may either complete or be cancelled, and the stream could be closed.
ok. thanks
I have 2 tasks, one for read and another for write. If I try to close stream from write task it never completes. Do I need to do anything special?
here is example: