Skip to content

Commit 52e99cb

Browse files
committed
libnative/io: generic retry() for Unix 64 bit read/write().
Win32/WinSock APIs never call WSASetLastError() with WSAEINTR unless a programmer specifically cancels the ongoing blocking call by a deprecated WinSock1 API WSACancelBlockingCall(). So the errno check was simply removed and retry() became an id function on Windows. Note: Windows' equivalent of SIGINT is always handled in a separate thread: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682541%28v=vs.85%29.aspx "CTRL+C and CTRL+BREAK Signals" Also, incidentally rename a type parameter and clean up some module imports.
1 parent 67b97ab commit 52e99cb

File tree

3 files changed

+22
-34
lines changed

3 files changed

+22
-34
lines changed

src/libnative/io/file_unix.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@
1111
//! Blocking posix-based file I/O
1212
1313
use alloc::arc::Arc;
14-
use libc::{c_int, c_void};
15-
use libc;
14+
use libc::{mod, c_int, c_void};
1615
use std::c_str::CString;
1716
use std::mem;
18-
use std::rt::rtio;
19-
use std::rt::rtio::IoResult;
17+
use std::rt::rtio::{mod, IoResult};
2018

2119
use io::{retry, keep_going};
2220
use io::util;
@@ -55,7 +53,7 @@ impl FileDesc {
5553
let ret = retry(|| unsafe {
5654
libc::read(self.fd(),
5755
buf.as_mut_ptr() as *mut libc::c_void,
58-
buf.len() as libc::size_t) as libc::c_int
56+
buf.len() as libc::size_t)
5957
});
6058
if ret == 0 {
6159
Err(util::eof())
@@ -93,7 +91,7 @@ impl rtio::RtioFileStream for FileDesc {
9391
match retry(|| unsafe {
9492
libc::pread(self.fd(), buf.as_ptr() as *mut _,
9593
buf.len() as libc::size_t,
96-
offset as libc::off_t) as libc::c_int
94+
offset as libc::off_t)
9795
}) {
9896
-1 => Err(super::last_error()),
9997
n => Ok(n as int)
@@ -103,7 +101,7 @@ impl rtio::RtioFileStream for FileDesc {
103101
super::mkerr_libc(retry(|| unsafe {
104102
libc::pwrite(self.fd(), buf.as_ptr() as *const _,
105103
buf.len() as libc::size_t, offset as libc::off_t)
106-
} as c_int))
104+
}))
107105
}
108106
fn seek(&mut self, pos: i64, whence: rtio::SeekStyle) -> IoResult<u64> {
109107
let whence = match whence {

src/libnative/io/mod.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323
2424
#![allow(non_snake_case)]
2525

26-
use libc::c_int;
27-
use libc;
26+
use libc::{mod, c_int};
2827
use std::c_str::CString;
2928
use std::os;
30-
use std::rt::rtio;
31-
use std::rt::rtio::{IoResult, IoError};
29+
use std::rt::rtio::{mod, IoResult, IoError};
30+
use std::num;
3231

3332
// Local re-exports
3433
pub use self::file::FileDesc;
@@ -97,8 +96,8 @@ fn last_error() -> IoError {
9796
}
9897

9998
// unix has nonzero values as errors
100-
fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
101-
if ret != 0 {
99+
fn mkerr_libc <Int: num::Zero>(ret: Int) -> IoResult<()> {
100+
if !ret.is_zero() {
102101
Err(last_error())
103102
} else {
104103
Ok(())
@@ -117,39 +116,33 @@ fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
117116

118117
#[cfg(windows)]
119118
#[inline]
120-
fn retry(f: || -> libc::c_int) -> libc::c_int {
121-
loop {
122-
match f() {
123-
-1 if os::errno() as int == libc::WSAEINTR as int => {}
124-
n => return n,
125-
}
126-
}
127-
}
119+
fn retry<I> (f: || -> I) -> I { f() } // PR rust-lang/rust/#17020
128120

129121
#[cfg(unix)]
130122
#[inline]
131-
fn retry(f: || -> libc::c_int) -> libc::c_int {
123+
fn retry<I: PartialEq + num::One + Neg<I>> (f: || -> I) -> I {
124+
let minus_one = -num::one::<I>();
132125
loop {
133-
match f() {
134-
-1 if os::errno() as int == libc::EINTR as int => {}
135-
n => return n,
136-
}
126+
let n = f();
127+
if n == minus_one && os::errno() == libc::EINTR as int { }
128+
else { return n }
137129
}
138130
}
139131

132+
140133
fn keep_going(data: &[u8], f: |*const u8, uint| -> i64) -> i64 {
141134
let origamt = data.len();
142135
let mut data = data.as_ptr();
143136
let mut amt = origamt;
144137
while amt > 0 {
145-
let ret = retry(|| f(data, amt) as libc::c_int);
138+
let ret = retry(|| f(data, amt));
146139
if ret == 0 {
147140
break
148141
} else if ret != -1 {
149142
amt -= ret as uint;
150143
data = unsafe { data.offset(ret as int) };
151144
} else {
152-
return ret as i64;
145+
return ret;
153146
}
154147
}
155148
return (origamt - amt) as i64;

src/libnative/io/net.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ use libc;
1313
use std::mem;
1414
use std::ptr;
1515
use std::rt::mutex;
16-
use std::rt::rtio;
17-
use std::rt::rtio::{IoResult, IoError};
16+
use std::rt::rtio::{mod, IoResult, IoError};
1817
use std::sync::atomic;
1918

2019
use super::{retry, keep_going};
@@ -988,9 +987,7 @@ pub fn write<T>(fd: sock_t,
988987
write(false, inner, len)
989988
});
990989
} else {
991-
ret = retry(|| {
992-
write(false, buf.as_ptr(), buf.len()) as libc::c_int
993-
}) as i64;
990+
ret = retry(|| { write(false, buf.as_ptr(), buf.len()) });
994991
if ret > 0 { written = ret as uint; }
995992
}
996993
}
@@ -1017,7 +1014,7 @@ pub fn write<T>(fd: sock_t,
10171014
let _guard = lock();
10181015
let ptr = buf.slice_from(written).as_ptr();
10191016
let len = buf.len() - written;
1020-
match retry(|| write(deadline.is_some(), ptr, len) as libc::c_int) {
1017+
match retry(|| write(deadline.is_some(), ptr, len)) {
10211018
-1 if util::wouldblock() => {}
10221019
-1 => return Err(os::last_error()),
10231020
n => { written += n as uint; }

0 commit comments

Comments
 (0)