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
This commit is contained in:
commit
fffacb34fe
|
@ -69,22 +69,27 @@ impl StreamWatcher {
|
|||
// uv_read_stop function
|
||||
let _f = ForbidUnwind::new("stream read");
|
||||
|
||||
let mut rcx = ReadContext {
|
||||
buf: Some(slice_to_uv_buf(buf)),
|
||||
result: 0,
|
||||
task: None,
|
||||
};
|
||||
// When reading a TTY stream on windows, libuv will invoke alloc_cb
|
||||
// immediately as part of the call to alloc_cb. What this means is that
|
||||
// we must be ready for this to happen (by setting the data in the uv
|
||||
// handle). In theory this otherwise doesn't need to happen until after
|
||||
// the read is succesfully started.
|
||||
unsafe {
|
||||
uvll::set_data_for_uv_handle(self.handle, &rcx)
|
||||
}
|
||||
|
||||
// Send off the read request, but don't block until we're sure that the
|
||||
// read request is queued.
|
||||
match unsafe {
|
||||
uvll::uv_read_start(self.handle, alloc_cb, read_cb)
|
||||
} {
|
||||
0 => {
|
||||
let mut rcx = ReadContext {
|
||||
buf: Some(slice_to_uv_buf(buf)),
|
||||
result: 0,
|
||||
task: None,
|
||||
};
|
||||
do wait_until_woken_after(&mut rcx.task) {
|
||||
unsafe {
|
||||
uvll::set_data_for_uv_handle(self.handle, &rcx)
|
||||
}
|
||||
}
|
||||
wait_until_woken_after(&mut rcx.task, || {});
|
||||
match rcx.result {
|
||||
n if n < 0 => Err(UvError(n as c_int)),
|
||||
n => Ok(n as uint),
|
||||
|
|
Loading…
Reference in New Issue