Skip to content

Commit fffacb3

Browse files
committed
auto merge of #10646 : alexcrichton/rust/issue-10645, r=luqmana
This is a behavioral difference in libuv between different platforms in different situations. It turns out that libuv on windows will immediately allocate a buffer instead of waiting for data to be ready. What this implies is that we must have our custom data set on the handle before we call uv_read_start. I wish I knew of a way to test this, but this relies to being on the windows platform *and* reading from a true TTY handle which only happens when this is actually attached to a terminal. I have manually verified this works. Closes #10645
2 parents 1746c02 + 6acf227 commit fffacb3

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

src/librustuv/stream.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,27 @@ impl StreamWatcher {
6969
// uv_read_stop function
7070
let _f = ForbidUnwind::new("stream read");
7171

72+
let mut rcx = ReadContext {
73+
buf: Some(slice_to_uv_buf(buf)),
74+
result: 0,
75+
task: None,
76+
};
77+
// When reading a TTY stream on windows, libuv will invoke alloc_cb
78+
// immediately as part of the call to alloc_cb. What this means is that
79+
// we must be ready for this to happen (by setting the data in the uv
80+
// handle). In theory this otherwise doesn't need to happen until after
81+
// the read is succesfully started.
82+
unsafe {
83+
uvll::set_data_for_uv_handle(self.handle, &rcx)
84+
}
85+
7286
// Send off the read request, but don't block until we're sure that the
7387
// read request is queued.
7488
match unsafe {
7589
uvll::uv_read_start(self.handle, alloc_cb, read_cb)
7690
} {
7791
0 => {
78-
let mut rcx = ReadContext {
79-
buf: Some(slice_to_uv_buf(buf)),
80-
result: 0,
81-
task: None,
82-
};
83-
do wait_until_woken_after(&mut rcx.task) {
84-
unsafe {
85-
uvll::set_data_for_uv_handle(self.handle, &rcx)
86-
}
87-
}
92+
wait_until_woken_after(&mut rcx.task, || {});
8893
match rcx.result {
8994
n if n < 0 => Err(UvError(n as c_int)),
9095
n => Ok(n as uint),

0 commit comments

Comments
 (0)