diff options
| author | bors <bors@rust-lang.org> | 2013-11-25 05:46:37 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-11-25 05:46:37 -0800 |
| commit | fffacb34fec23da45c4d18ce8504c7947527aa78 (patch) | |
| tree | a59470563bc3b39b3d32f16ea5fb235c0a1d48e6 | |
| parent | 1746c0269d356a93aaef367541872d363651cb23 (diff) | |
| parent | 6acf227cc8db09ca25d274918f860849c41df19a (diff) | |
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
| -rw-r--r-- | src/librustuv/stream.rs | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/librustuv/stream.rs b/src/librustuv/stream.rs index 08b307700c7..47ef26ee9d4 100644 --- a/src/librustuv/stream.rs +++ b/src/librustuv/stream.rs @@ -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), |
