about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-06-29 09:38:07 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-29 09:38:07 -0700
commitca7fb82e0b9fb47e4addcee7b993993e7ce27fde (patch)
tree2ee0c282447aaf007baffa1d8acba64b74c92dd8 /src/libstd
parentbd9563aa382ccfbda36049786329edcdc609930c (diff)
downloadrust-ca7fb82e0b9fb47e4addcee7b993993e7ce27fde.tar.gz
rust-ca7fb82e0b9fb47e4addcee7b993993e7ce27fde.zip
rustuv: Don't zero-out data on clones
When cloning a stream, the data is already guaranteed to be in a consistent
state, so there's no need to perform a zeroing. This prevents segfaults as seen
in #15231

Closes #15231
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/net/tcp.rs40
-rw-r--r--src/libstd/task.rs2
2 files changed, 41 insertions, 1 deletions
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index b79e831ff61..baf53251fbe 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -1360,4 +1360,44 @@ mod test {
 
         rx2.recv();
     })
+
+    iotest!(fn clone_while_reading() {
+        let addr = next_test_ip6();
+        let listen = TcpListener::bind(addr.ip.to_str().as_slice(), addr.port);
+        let mut accept = listen.listen().unwrap();
+
+        // Enqueue a task to write to a socket
+        let (tx, rx) = channel();
+        let (txdone, rxdone) = channel();
+        let txdone2 = txdone.clone();
+        spawn(proc() {
+            let mut tcp = TcpStream::connect(addr.ip.to_str().as_slice(),
+                                             addr.port).unwrap();
+            rx.recv();
+            tcp.write_u8(0).unwrap();
+            txdone2.send(());
+        });
+
+        // Spawn off a reading clone
+        let tcp = accept.accept().unwrap();
+        let tcp2 = tcp.clone();
+        let txdone3 = txdone.clone();
+        spawn(proc() {
+            let mut tcp2 = tcp2;
+            tcp2.read_u8().unwrap();
+            txdone3.send(());
+        });
+
+        // Try to ensure that the reading clone is indeed reading
+        for _ in range(0i, 50) {
+            ::task::deschedule();
+        }
+
+        // clone the handle again while it's reading, then let it finish the
+        // read.
+        let _ = tcp.clone();
+        tx.send(());
+        rxdone.recv();
+        rxdone.recv();
+    })
 }
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index 21d19deb0c7..6492717d3ec 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -649,7 +649,7 @@ fn task_abort_no_kill_runtime() {
     use std::io::timer;
     use mem;
 
-    let mut tb = TaskBuilder::new();
+    let tb = TaskBuilder::new();
     let rx = tb.try_future(proc() {});
     mem::drop(rx);
     timer::sleep(1000);