From a402fb27faabbe33f03d461d6684af4501db5ac4 Mon Sep 17 00:00:00 2001 From: klutzy Date: Sat, 5 Oct 2013 06:03:42 +0900 Subject: [PATCH 1/3] std::rt::uv::net: Handle `read_start` error cc #9605 --- src/libstd/rt/uv/net.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs index ca42fd32f09..2c27db982aa 100644 --- a/src/libstd/rt/uv/net.rs +++ b/src/libstd/rt/uv/net.rs @@ -14,7 +14,7 @@ use rt::uv::uvll; use rt::uv::uvll::*; use rt::uv::{AllocCallback, ConnectionCallback, ReadCallback, UdpReceiveCallback, UdpSendCallback}; use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle, NullCallback, - status_to_maybe_uv_error}; + status_to_maybe_uv_error, vec_to_uv_buf}; use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr}; use vec; use str; @@ -147,7 +147,18 @@ impl StreamWatcher { data.read_cb = Some(cb); } - unsafe { uvll::read_start(self.native_handle(), alloc_cb, read_cb); } + let ret = unsafe { uvll::read_start(self.native_handle(), alloc_cb, read_cb) }; + + if ret != 0 { + // uvll::read_start failed, so read_cb will not be called. + // Call it manually for scheduling. + call_read_cb(self.native_handle(), ret as ssize_t); + } + + fn call_read_cb(stream: *uvll::uv_stream_t, errno: ssize_t) { + #[fixed_stack_segment]; #[inline(never)]; + read_cb(stream, errno, vec_to_uv_buf(~[])); + } extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf { let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream); From 8aadcd4851d90adfb32da6ba8da3e7e29d97c28e Mon Sep 17 00:00:00 2001 From: klutzy Date: Sat, 5 Oct 2013 06:10:02 +0900 Subject: [PATCH 2/3] std::rt: Add NotConnected to IoErrorKind --- src/libstd/rt/io/mod.rs | 2 ++ src/libstd/rt/uv/mod.rs | 1 + src/libstd/rt/uv/uvll.rs | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs index c2f137ba119..6e622c9572c 100644 --- a/src/libstd/rt/io/mod.rs +++ b/src/libstd/rt/io/mod.rs @@ -367,6 +367,7 @@ pub enum IoErrorKind { Closed, ConnectionRefused, ConnectionReset, + NotConnected, BrokenPipe, PathAlreadyExists, PathDoesntExist, @@ -386,6 +387,7 @@ impl ToStr for IoErrorKind { Closed => ~"Closed", ConnectionRefused => ~"ConnectionRefused", ConnectionReset => ~"ConnectionReset", + NotConnected => ~"NotConnected", BrokenPipe => ~"BrokenPipe", PathAlreadyExists => ~"PathAlreadyExists", PathDoesntExist => ~"PathDoesntExist", diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs index 0c5351ea9e4..67926b35a62 100644 --- a/src/libstd/rt/uv/mod.rs +++ b/src/libstd/rt/uv/mod.rs @@ -267,6 +267,7 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError { EACCES => PermissionDenied, ECONNREFUSED => ConnectionRefused, ECONNRESET => ConnectionReset, + ENOTCONN => NotConnected, EPIPE => BrokenPipe, err => { rtdebug!("uverr.code {}", err as int); diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs index 790bf53a291..a80d5cbc1fb 100644 --- a/src/libstd/rt/uv/uvll.rs +++ b/src/libstd/rt/uv/uvll.rs @@ -53,6 +53,7 @@ pub mod errors { pub static EACCES: c_int = -4093; pub static ECONNREFUSED: c_int = -4079; pub static ECONNRESET: c_int = -4078; + pub static ENOTCONN: c_int = -4054; pub static EPIPE: c_int = -4048; } #[cfg(not(windows))] @@ -63,6 +64,7 @@ pub mod errors { pub static EACCES: c_int = -libc::EACCES; pub static ECONNREFUSED: c_int = -libc::ECONNREFUSED; pub static ECONNRESET: c_int = -libc::ECONNRESET; + pub static ENOTCONN: c_int = -libc::ENOTCONN; pub static EPIPE: c_int = -libc::EPIPE; } From ade57d9f5827f0753cd0acee025f830a5256a78a Mon Sep 17 00:00:00 2001 From: klutzy Date: Sat, 5 Oct 2013 06:45:08 +0900 Subject: [PATCH 3/3] rt::io::net::tcp: Fix eof_twice tests on Win32 cc #8811 --- src/libstd/rt/io/net/tcp.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs index ff2802c75b0..3b894b9d331 100644 --- a/src/libstd/rt/io/net/tcp.rs +++ b/src/libstd/rt/io/net/tcp.rs @@ -306,7 +306,6 @@ mod test { } #[test] - #[ignore(cfg(windows))] // FIXME #8811 fn read_eof_twice_ip4() { do run_in_mt_newsched_task { let addr = next_test_ip4(); @@ -321,8 +320,16 @@ mod test { let mut buf = [0]; let nread = stream.read(buf); assert!(nread.is_none()); - let nread = stream.read(buf); - assert!(nread.is_none()); + do read_error::cond.trap(|e| { + if cfg!(windows) { + assert_eq!(e.kind, NotConnected); + } else { + fail2!(); + } + }).inside { + let nread = stream.read(buf); + assert!(nread.is_none()); + } } do spawntask { @@ -334,7 +341,6 @@ mod test { } #[test] - #[ignore(cfg(windows))] // FIXME #8811 fn read_eof_twice_ip6() { do run_in_mt_newsched_task { let addr = next_test_ip6(); @@ -349,8 +355,16 @@ mod test { let mut buf = [0]; let nread = stream.read(buf); assert!(nread.is_none()); - let nread = stream.read(buf); - assert!(nread.is_none()); + do read_error::cond.trap(|e| { + if cfg!(windows) { + assert_eq!(e.kind, NotConnected); + } else { + fail2!(); + } + }).inside { + let nread = stream.read(buf); + assert!(nread.is_none()); + } } do spawntask {