]> git.lizzy.rs Git - rust.git/commitdiff
Don't wait for a full buffer when reading TCP
authorAlex Crichton <alex@alexcrichton.com>
Mon, 6 Jan 2014 06:16:16 +0000 (22:16 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 6 Jan 2014 08:08:18 +0000 (00:08 -0800)
libnative erroneously would attempt to fill the entire buffer in a call to
`read` before returning, when rather it should return immediately because
there's not guaranteed to be any data that will ever be received again.

Close #11328

src/libnative/io/net.rs
src/libstd/io/net/tcp.rs

index b26ac141192bfb93ea9bff1859744332ea55343e..adcd21f0ac4c5d85b6e5797d00d75569881e1fcc 100644 (file)
@@ -275,12 +275,12 @@ fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
 
 impl rtio::RtioTcpStream for TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
-        let ret = keep_going(buf, |buf, len| {
+        let ret = retry(|| {
             unsafe {
                 libc::recv(self.fd,
-                           buf as *mut libc::c_void,
-                           len as wrlen,
-                           0) as i64
+                           buf.as_ptr() as *mut libc::c_void,
+                           buf.len() as wrlen,
+                           0) as libc::c_int
             }
         });
         if ret == 0 {
index 52cca7f622b532984e0da0794f903eaf9e3203f1..c2a70e0120d2968fc794ea45cda40d8475348bd2 100644 (file)
@@ -589,4 +589,25 @@ pub fn peer_name(addr: SocketAddr) {
         //peer_name(next_test_ip6());
         socket_name(next_test_ip6());
     })
+
+    iotest!(fn partial_read() {
+        let addr = next_test_ip4();
+        let (p, c) = Chan::new();
+        do spawn {
+            let mut srv = TcpListener::bind(addr).listen();
+            c.send(());
+            let mut cl = srv.accept().unwrap();
+            cl.write([10]);
+            let mut b = [0];
+            cl.read(b);
+            c.send(());
+        }
+
+        p.recv();
+        let mut c = TcpStream::connect(addr).unwrap();
+        let mut b = [0, ..10];
+        assert_eq!(c.read(b), Some(1));
+        c.write([1]);
+        p.recv();
+    })
 }