Skip to content

Commit 1f279bf

Browse files
committed
auto merge of #9721 : klutzy/rust/uv-net-read-fix, r=alexcrichton
See #9605 for detailed information. This also fixes two tests of #8811.
2 parents c92f216 + ade57d9 commit 1f279bf

File tree

5 files changed

+38
-8
lines changed

5 files changed

+38
-8
lines changed

src/libstd/rt/io/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ pub enum IoErrorKind {
371371
Closed,
372372
ConnectionRefused,
373373
ConnectionReset,
374+
NotConnected,
374375
BrokenPipe,
375376
PathAlreadyExists,
376377
PathDoesntExist,
@@ -390,6 +391,7 @@ impl ToStr for IoErrorKind {
390391
Closed => ~"Closed",
391392
ConnectionRefused => ~"ConnectionRefused",
392393
ConnectionReset => ~"ConnectionReset",
394+
NotConnected => ~"NotConnected",
393395
BrokenPipe => ~"BrokenPipe",
394396
PathAlreadyExists => ~"PathAlreadyExists",
395397
PathDoesntExist => ~"PathDoesntExist",

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

+20-6
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ mod test {
306306
}
307307

308308
#[test]
309-
#[ignore(cfg(windows))] // FIXME #8811
310309
fn read_eof_twice_ip4() {
311310
do run_in_mt_newsched_task {
312311
let addr = next_test_ip4();
@@ -321,8 +320,16 @@ mod test {
321320
let mut buf = [0];
322321
let nread = stream.read(buf);
323322
assert!(nread.is_none());
324-
let nread = stream.read(buf);
325-
assert!(nread.is_none());
323+
do read_error::cond.trap(|e| {
324+
if cfg!(windows) {
325+
assert_eq!(e.kind, NotConnected);
326+
} else {
327+
fail2!();
328+
}
329+
}).inside {
330+
let nread = stream.read(buf);
331+
assert!(nread.is_none());
332+
}
326333
}
327334

328335
do spawntask {
@@ -334,7 +341,6 @@ mod test {
334341
}
335342

336343
#[test]
337-
#[ignore(cfg(windows))] // FIXME #8811
338344
fn read_eof_twice_ip6() {
339345
do run_in_mt_newsched_task {
340346
let addr = next_test_ip6();
@@ -349,8 +355,16 @@ mod test {
349355
let mut buf = [0];
350356
let nread = stream.read(buf);
351357
assert!(nread.is_none());
352-
let nread = stream.read(buf);
353-
assert!(nread.is_none());
358+
do read_error::cond.trap(|e| {
359+
if cfg!(windows) {
360+
assert_eq!(e.kind, NotConnected);
361+
} else {
362+
fail2!();
363+
}
364+
}).inside {
365+
let nread = stream.read(buf);
366+
assert!(nread.is_none());
367+
}
354368
}
355369

356370
do spawntask {

src/libstd/rt/uv/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
267267
EACCES => PermissionDenied,
268268
ECONNREFUSED => ConnectionRefused,
269269
ECONNRESET => ConnectionReset,
270+
ENOTCONN => NotConnected,
270271
EPIPE => BrokenPipe,
271272
err => {
272273
rtdebug!("uverr.code {}", err as int);

src/libstd/rt/uv/net.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rt::uv::uvll;
1414
use rt::uv::uvll::*;
1515
use rt::uv::{AllocCallback, ConnectionCallback, ReadCallback, UdpReceiveCallback, UdpSendCallback};
1616
use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle, NullCallback,
17-
status_to_maybe_uv_error};
17+
status_to_maybe_uv_error, vec_to_uv_buf};
1818
use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
1919
use vec;
2020
use str;
@@ -147,7 +147,18 @@ impl StreamWatcher {
147147
data.read_cb = Some(cb);
148148
}
149149

150-
unsafe { uvll::read_start(self.native_handle(), alloc_cb, read_cb); }
150+
let ret = unsafe { uvll::read_start(self.native_handle(), alloc_cb, read_cb) };
151+
152+
if ret != 0 {
153+
// uvll::read_start failed, so read_cb will not be called.
154+
// Call it manually for scheduling.
155+
call_read_cb(self.native_handle(), ret as ssize_t);
156+
}
157+
158+
fn call_read_cb(stream: *uvll::uv_stream_t, errno: ssize_t) {
159+
#[fixed_stack_segment]; #[inline(never)];
160+
read_cb(stream, errno, vec_to_uv_buf(~[]));
161+
}
151162

152163
extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf {
153164
let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);

src/libstd/rt/uv/uvll.rs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod errors {
5353
pub static EACCES: c_int = -4093;
5454
pub static ECONNREFUSED: c_int = -4079;
5555
pub static ECONNRESET: c_int = -4078;
56+
pub static ENOTCONN: c_int = -4054;
5657
pub static EPIPE: c_int = -4048;
5758
}
5859
#[cfg(not(windows))]
@@ -63,6 +64,7 @@ pub mod errors {
6364
pub static EACCES: c_int = -libc::EACCES;
6465
pub static ECONNREFUSED: c_int = -libc::ECONNREFUSED;
6566
pub static ECONNRESET: c_int = -libc::ECONNRESET;
67+
pub static ENOTCONN: c_int = -libc::ENOTCONN;
6668
pub static EPIPE: c_int = -libc::EPIPE;
6769
}
6870

0 commit comments

Comments
 (0)