about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNODA, Kai <nodakai@gmail.com>2014-09-05 15:05:22 +0800
committerNODA, Kai <nodakai@gmail.com>2014-09-08 08:17:13 +0800
commit52e99cbcaaac8cfdd54ad8b237785b5e5cd84b48 (patch)
tree3cc49eb648b92afe170f8b2ec2e02e105de3b782
parent67b97ab6d2b7de9b69fd97dc171fcf8feec932ff (diff)
downloadrust-52e99cbcaaac8cfdd54ad8b237785b5e5cd84b48.tar.gz
rust-52e99cbcaaac8cfdd54ad8b237785b5e5cd84b48.zip
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.
-rw-r--r--src/libnative/io/file_unix.rs12
-rw-r--r--src/libnative/io/mod.rs35
-rw-r--r--src/libnative/io/net.rs9
3 files changed, 22 insertions, 34 deletions
diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs
index 136652f3ebf..bc1d877dc54 100644
--- a/src/libnative/io/file_unix.rs
+++ b/src/libnative/io/file_unix.rs
@@ -11,12 +11,10 @@
 //! Blocking posix-based file I/O
 
 use alloc::arc::Arc;
-use libc::{c_int, c_void};
-use libc;
+use libc::{mod, c_int, c_void};
 use std::c_str::CString;
 use std::mem;
-use std::rt::rtio;
-use std::rt::rtio::IoResult;
+use std::rt::rtio::{mod, IoResult};
 
 use io::{retry, keep_going};
 use io::util;
@@ -55,7 +53,7 @@ impl FileDesc {
         let ret = retry(|| unsafe {
             libc::read(self.fd(),
                        buf.as_mut_ptr() as *mut libc::c_void,
-                       buf.len() as libc::size_t) as libc::c_int
+                       buf.len() as libc::size_t)
         });
         if ret == 0 {
             Err(util::eof())
@@ -93,7 +91,7 @@ impl rtio::RtioFileStream for FileDesc {
         match retry(|| unsafe {
             libc::pread(self.fd(), buf.as_ptr() as *mut _,
                         buf.len() as libc::size_t,
-                        offset as libc::off_t) as libc::c_int
+                        offset as libc::off_t)
         }) {
             -1 => Err(super::last_error()),
             n => Ok(n as int)
@@ -103,7 +101,7 @@ impl rtio::RtioFileStream for FileDesc {
         super::mkerr_libc(retry(|| unsafe {
             libc::pwrite(self.fd(), buf.as_ptr() as *const _,
                          buf.len() as libc::size_t, offset as libc::off_t)
-        } as c_int))
+        }))
     }
     fn seek(&mut self, pos: i64, whence: rtio::SeekStyle) -> IoResult<u64> {
         let whence = match whence {
diff --git a/src/libnative/io/mod.rs b/src/libnative/io/mod.rs
index 276194feaf0..7881e088388 100644
--- a/src/libnative/io/mod.rs
+++ b/src/libnative/io/mod.rs
@@ -23,12 +23,11 @@
 
 #![allow(non_snake_case)]
 
-use libc::c_int;
-use libc;
+use libc::{mod, c_int};
 use std::c_str::CString;
 use std::os;
-use std::rt::rtio;
-use std::rt::rtio::{IoResult, IoError};
+use std::rt::rtio::{mod, IoResult, IoError};
+use std::num;
 
 // Local re-exports
 pub use self::file::FileDesc;
@@ -97,8 +96,8 @@ fn last_error() -> IoError {
 }
 
 // unix has nonzero values as errors
-fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
-    if ret != 0 {
+fn mkerr_libc <Int: num::Zero>(ret: Int) -> IoResult<()> {
+    if !ret.is_zero() {
         Err(last_error())
     } else {
         Ok(())
@@ -117,39 +116,33 @@ fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
 
 #[cfg(windows)]
 #[inline]
-fn retry(f: || -> libc::c_int) -> libc::c_int {
-    loop {
-        match f() {
-            -1 if os::errno() as int == libc::WSAEINTR as int => {}
-            n => return n,
-        }
-    }
-}
+fn retry<I> (f: || -> I) -> I { f() } // PR rust-lang/rust/#17020
 
 #[cfg(unix)]
 #[inline]
-fn retry(f: || -> libc::c_int) -> libc::c_int {
+fn retry<I: PartialEq + num::One + Neg<I>> (f: || -> I) -> I {
+    let minus_one = -num::one::<I>();
     loop {
-        match f() {
-            -1 if os::errno() as int == libc::EINTR as int => {}
-            n => return n,
-        }
+        let n = f();
+        if n == minus_one && os::errno() == libc::EINTR as int { }
+        else { return n }
     }
 }
 
+
 fn keep_going(data: &[u8], f: |*const u8, uint| -> i64) -> i64 {
     let origamt = data.len();
     let mut data = data.as_ptr();
     let mut amt = origamt;
     while amt > 0 {
-        let ret = retry(|| f(data, amt) as libc::c_int);
+        let ret = retry(|| f(data, amt));
         if ret == 0 {
             break
         } else if ret != -1 {
             amt -= ret as uint;
             data = unsafe { data.offset(ret as int) };
         } else {
-            return ret as i64;
+            return ret;
         }
     }
     return (origamt - amt) as i64;
diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs
index cbfc673e6af..5820323e14b 100644
--- a/src/libnative/io/net.rs
+++ b/src/libnative/io/net.rs
@@ -13,8 +13,7 @@ use libc;
 use std::mem;
 use std::ptr;
 use std::rt::mutex;
-use std::rt::rtio;
-use std::rt::rtio::{IoResult, IoError};
+use std::rt::rtio::{mod, IoResult, IoError};
 use std::sync::atomic;
 
 use super::{retry, keep_going};
@@ -988,9 +987,7 @@ pub fn write<T>(fd: sock_t,
                 write(false, inner, len)
             });
         } else {
-            ret = retry(|| {
-                write(false, buf.as_ptr(), buf.len()) as libc::c_int
-            }) as i64;
+            ret = retry(|| { write(false, buf.as_ptr(), buf.len()) });
             if ret > 0 { written = ret as uint; }
         }
     }
@@ -1017,7 +1014,7 @@ pub fn write<T>(fd: sock_t,
             let _guard = lock();
             let ptr = buf.slice_from(written).as_ptr();
             let len = buf.len() - written;
-            match retry(|| write(deadline.is_some(), ptr, len) as libc::c_int) {
+            match retry(|| write(deadline.is_some(), ptr, len)) {
                 -1 if util::wouldblock() => {}
                 -1 => return Err(os::last_error()),
                 n => { written += n as uint; }