Skip to content

move errno -> IoError converter into std, bubble up OSRng errors #13115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 1, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libcollections/deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub mod bench {
map: &mut M,
bh: &mut BenchHarness) {
// setup
let mut rng = rand::XorShiftRng::new();
let mut rng = rand::weak_rng();

map.clear();
for _ in range(0, n) {
Expand Down Expand Up @@ -89,7 +89,7 @@ pub mod bench {
map: &mut M,
bh: &mut BenchHarness) {
// setup
let mut rng = rand::XorShiftRng::new();
let mut rng = rand::weak_rng();
let mut keys = slice::from_fn(n, |_| rng.gen::<uint>() % n);

for k in keys.iter() {
Expand Down
7 changes: 6 additions & 1 deletion src/libgreen/sched.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,12 @@ impl ClosureConverter for UnsafeTaskReceiver {
// worry there.
#[cfg(windows)]
fn new_sched_rng() -> XorShiftRng {
XorShiftRng::new()
match XorShiftRng::new() {
Ok(r) => r,
Err(e) => {
rtabort!("sched: failed to create seeded RNG: {}", e)
}
}
}
#[cfg(unix)]
fn new_sched_rng() -> XorShiftRng {
Expand Down
4 changes: 1 addition & 3 deletions src/libnative/io/addrinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,8 @@ extern "system" {

#[cfg(windows)]
fn get_error(_: c_int) -> IoError {
use super::translate_error;

unsafe {
translate_error(WSAGetLastError() as i32, true)
IoError::from_errno(WSAGetLastError() as uint, true)
}
}

Expand Down
67 changes: 2 additions & 65 deletions src/libnative/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,73 +86,10 @@ fn unimpl() -> IoError {
}
}

fn translate_error(errno: i32, detail: bool) -> IoError {
#[cfg(windows)]
fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
match errno {
libc::EOF => (io::EndOfFile, "end of file"),
libc::ERROR_NO_DATA => (io::BrokenPipe, "the pipe is being closed"),
libc::ERROR_FILE_NOT_FOUND => (io::FileNotFound, "file not found"),
libc::ERROR_INVALID_NAME => (io::InvalidInput, "invalid file name"),
libc::WSAECONNREFUSED => (io::ConnectionRefused, "connection refused"),
libc::WSAECONNRESET => (io::ConnectionReset, "connection reset"),
libc::WSAEACCES => (io::PermissionDenied, "permission denied"),
libc::WSAEWOULDBLOCK => {
(io::ResourceUnavailable, "resource temporarily unavailable")
}
libc::WSAENOTCONN => (io::NotConnected, "not connected"),
libc::WSAECONNABORTED => (io::ConnectionAborted, "connection aborted"),
libc::WSAEADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
libc::WSAEADDRINUSE => (io::ConnectionRefused, "address in use"),
libc::ERROR_BROKEN_PIPE => (io::EndOfFile, "the pipe has ended"),

// libuv maps this error code to EISDIR. we do too. if it is found
// to be incorrect, we can add in some more machinery to only
// return this message when ERROR_INVALID_FUNCTION after certain
// win32 calls.
libc::ERROR_INVALID_FUNCTION => (io::InvalidInput,
"illegal operation on a directory"),

_ => (io::OtherIoError, "unknown error")
}
}

#[cfg(not(windows))]
fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
// FIXME: this should probably be a bit more descriptive...
match errno {
libc::EOF => (io::EndOfFile, "end of file"),
libc::ECONNREFUSED => (io::ConnectionRefused, "connection refused"),
libc::ECONNRESET => (io::ConnectionReset, "connection reset"),
libc::EPERM | libc::EACCES =>
(io::PermissionDenied, "permission denied"),
libc::EPIPE => (io::BrokenPipe, "broken pipe"),
libc::ENOTCONN => (io::NotConnected, "not connected"),
libc::ECONNABORTED => (io::ConnectionAborted, "connection aborted"),
libc::EADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
libc::EADDRINUSE => (io::ConnectionRefused, "address in use"),
libc::ENOENT => (io::FileNotFound, "no such file or directory"),
libc::EISDIR => (io::InvalidInput, "illegal operation on a directory"),

// These two constants can have the same value on some systems, but
// different values on others, so we can't use a match clause
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
(io::ResourceUnavailable, "resource temporarily unavailable"),

_ => (io::OtherIoError, "unknown error")
}
}

let (kind, desc) = get_err(errno);
IoError {
kind: kind,
desc: desc,
detail: if detail {Some(os::last_os_error())} else {None},
}
fn last_error() -> IoError {
IoError::last_error()
}

fn last_error() -> IoError { translate_error(os::errno() as i32, true) }

// unix has nonzero values as errors
fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
if ret != 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/libnative/io/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ fn last_error() -> io::IoError {
extern "system" {
fn WSAGetLastError() -> libc::c_int;
}
super::translate_error(unsafe { WSAGetLastError() }, true)
io::IoError::from_errno(unsafe { WSAGetLastError() } as uint, true)
}

#[cfg(not(windows))]
Expand Down
2 changes: 1 addition & 1 deletion src/libnative/io/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ fn spawn_process_os(config: p::ProcessConfig,
(bytes[1] << 16) as i32 |
(bytes[2] << 8) as i32 |
(bytes[3] << 0) as i32;
Err(super::translate_error(errno, false))
Err(io::IoError::from_errno(errno as uint, false))
}
Err(e) => {
assert!(e.kind == io::BrokenPipe ||
Expand Down
2 changes: 1 addition & 1 deletion src/librand/distributions/exponential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ mod bench {

#[bench]
fn rand_exp(bh: &mut BenchHarness) {
let mut rng = XorShiftRng::new();
let mut rng = XorShiftRng::new().unwrap();
let mut exp = Exp::new(2.71828 * 3.14159);

bh.iter(|| {
Expand Down
6 changes: 3 additions & 3 deletions src/librand/distributions/gamma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,14 +370,14 @@ mod bench {
use self::test::BenchHarness;
use std::mem::size_of;
use distributions::IndependentSample;
use {StdRng, RAND_BENCH_N};
use {XorShiftRng, RAND_BENCH_N};
use super::Gamma;


#[bench]
fn bench_gamma_large_shape(bh: &mut BenchHarness) {
let gamma = Gamma::new(10., 1.0);
let mut rng = StdRng::new();
let mut rng = XorShiftRng::new().unwrap();

bh.iter(|| {
for _ in range(0, RAND_BENCH_N) {
Expand All @@ -390,7 +390,7 @@ mod bench {
#[bench]
fn bench_gamma_small_shape(bh: &mut BenchHarness) {
let gamma = Gamma::new(0.1, 1.0);
let mut rng = StdRng::new();
let mut rng = XorShiftRng::new().unwrap();

bh.iter(|| {
for _ in range(0, RAND_BENCH_N) {
Expand Down
2 changes: 1 addition & 1 deletion src/librand/distributions/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod bench {

#[bench]
fn rand_normal(bh: &mut BenchHarness) {
let mut rng = XorShiftRng::new();
let mut rng = XorShiftRng::new().unwrap();
let mut normal = Normal::new(-2.71828, 3.14159);

bh.iter(|| {
Expand Down
34 changes: 22 additions & 12 deletions src/librand/isaac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! The ISAAC random number generator.

use {Rng, SeedableRng, OSRng};
use std::io::IoResult;
use std::iter::{range_step, Repeat};
use std::slice::raw;
use std::mem;
Expand Down Expand Up @@ -44,19 +45,23 @@ static EMPTY: IsaacRng = IsaacRng {

impl IsaacRng {
/// Create an ISAAC random number generator with a random seed.
pub fn new() -> IsaacRng {
///
/// This reads randomness from the operating system (via `OSRng`)
/// which may fail, any error is propagated via the `IoResult`
/// return value.
pub fn new() -> IoResult<IsaacRng> {
let mut rng = EMPTY;

let mut os_rng = try!(OSRng::new());
unsafe {
let ptr = rng.rsl.as_mut_ptr();

raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
OSRng::new().fill_bytes(slice);
os_rng.fill_bytes(slice);
})
}

rng.init(true);
rng
Ok(rng)
}

/// Create an ISAAC random number generator using the default
Expand Down Expand Up @@ -249,19 +254,24 @@ static EMPTY_64: Isaac64Rng = Isaac64Rng {
impl Isaac64Rng {
/// Create a 64-bit ISAAC random number generator with a random
/// seed.
pub fn new() -> Isaac64Rng {
///
/// This reads randomness from the operating system (via `OSRng`)
/// which may fail, any error is propagated via the `IoResult`
/// return value.
pub fn new() -> IoResult<Isaac64Rng> {
let mut rng = EMPTY_64;
let mut os_rng = try!(OSRng::new());

unsafe {
let ptr = rng.rsl.as_mut_ptr();

raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
OSRng::new().fill_bytes(slice);
os_rng.fill_bytes(slice);
})
}

rng.init(true);
rng
Ok(rng)
}

/// Create a 64-bit ISAAC random number generator using the
Expand Down Expand Up @@ -430,19 +440,19 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
#[cfg(test)]
mod test {
use super::{IsaacRng, Isaac64Rng};
use {Rng, SeedableRng, OSRng};
use {Rng, SeedableRng, task_rng};
use std::slice;

#[test]
fn test_rng_32_rand_seeded() {
let s = OSRng::new().gen_vec::<u32>(256);
let s = task_rng().gen_vec::<u32>(256);
let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice());
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
}
#[test]
fn test_rng_64_rand_seeded() {
let s = OSRng::new().gen_vec::<u64>(256);
let s = task_rng().gen_vec::<u64>(256);
let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
Expand All @@ -465,7 +475,7 @@ mod test {

#[test]
fn test_rng_32_reseed() {
let s = OSRng::new().gen_vec::<u32>(256);
let s = task_rng().gen_vec::<u32>(256);
let mut r: IsaacRng = SeedableRng::from_seed(s.as_slice());
let string1 = r.gen_ascii_str(100);

Expand All @@ -476,7 +486,7 @@ mod test {
}
#[test]
fn test_rng_64_reseed() {
let s = OSRng::new().gen_vec::<u64>(256);
let s = task_rng().gen_vec::<u64>(256);
let mut r: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
let string1 = r.gen_ascii_str(100);

Expand Down
Loading