auto merge of #13115 : huonw/rust/rand-errors, r=alexcrichton
move errno -> IoError converter into std, bubble up OSRng errors Also adds a general errno -> `~str` converter to `std::os`, and makes the failure messages for the things using `OSRng` (e.g. (transitively) the task-local RNG, meaning hashmap initialisation failures aren't such a black box).
This commit is contained in:
@@ -52,7 +52,7 @@ pub mod bench {
|
|||||||
map: &mut M,
|
map: &mut M,
|
||||||
bh: &mut BenchHarness) {
|
bh: &mut BenchHarness) {
|
||||||
// setup
|
// setup
|
||||||
let mut rng = rand::XorShiftRng::new();
|
let mut rng = rand::weak_rng();
|
||||||
|
|
||||||
map.clear();
|
map.clear();
|
||||||
for _ in range(0, n) {
|
for _ in range(0, n) {
|
||||||
@@ -89,7 +89,7 @@ pub mod bench {
|
|||||||
map: &mut M,
|
map: &mut M,
|
||||||
bh: &mut BenchHarness) {
|
bh: &mut BenchHarness) {
|
||||||
// setup
|
// setup
|
||||||
let mut rng = rand::XorShiftRng::new();
|
let mut rng = rand::weak_rng();
|
||||||
let mut keys = slice::from_fn(n, |_| rng.gen::<uint>() % n);
|
let mut keys = slice::from_fn(n, |_| rng.gen::<uint>() % n);
|
||||||
|
|
||||||
for k in keys.iter() {
|
for k in keys.iter() {
|
||||||
|
|||||||
@@ -967,7 +967,12 @@ impl ClosureConverter for UnsafeTaskReceiver {
|
|||||||
// worry there.
|
// worry there.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn new_sched_rng() -> XorShiftRng {
|
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)]
|
#[cfg(unix)]
|
||||||
fn new_sched_rng() -> XorShiftRng {
|
fn new_sched_rng() -> XorShiftRng {
|
||||||
|
|||||||
@@ -96,10 +96,8 @@ extern "system" {
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn get_error(_: c_int) -> IoError {
|
fn get_error(_: c_int) -> IoError {
|
||||||
use super::translate_error;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
translate_error(WSAGetLastError() as i32, true)
|
IoError::from_errno(WSAGetLastError() as uint, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,73 +86,10 @@ fn unimpl() -> IoError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_error(errno: i32, detail: bool) -> IoError {
|
fn last_error() -> IoError {
|
||||||
#[cfg(windows)]
|
IoError::last_error()
|
||||||
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 { translate_error(os::errno() as i32, true) }
|
|
||||||
|
|
||||||
// unix has nonzero values as errors
|
// unix has nonzero values as errors
|
||||||
fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
|
fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ fn last_error() -> io::IoError {
|
|||||||
extern "system" {
|
extern "system" {
|
||||||
fn WSAGetLastError() -> libc::c_int;
|
fn WSAGetLastError() -> libc::c_int;
|
||||||
}
|
}
|
||||||
super::translate_error(unsafe { WSAGetLastError() }, true)
|
io::IoError::from_errno(unsafe { WSAGetLastError() } as uint, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ fn spawn_process_os(config: p::ProcessConfig,
|
|||||||
(bytes[1] << 16) as i32 |
|
(bytes[1] << 16) as i32 |
|
||||||
(bytes[2] << 8) as i32 |
|
(bytes[2] << 8) as i32 |
|
||||||
(bytes[3] << 0) as i32;
|
(bytes[3] << 0) as i32;
|
||||||
Err(super::translate_error(errno, false))
|
Err(io::IoError::from_errno(errno as uint, false))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
assert!(e.kind == io::BrokenPipe ||
|
assert!(e.kind == io::BrokenPipe ||
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_exp(bh: &mut BenchHarness) {
|
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);
|
let mut exp = Exp::new(2.71828 * 3.14159);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
|
|||||||
@@ -370,14 +370,14 @@ mod bench {
|
|||||||
use self::test::BenchHarness;
|
use self::test::BenchHarness;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use distributions::IndependentSample;
|
use distributions::IndependentSample;
|
||||||
use {StdRng, RAND_BENCH_N};
|
use {XorShiftRng, RAND_BENCH_N};
|
||||||
use super::Gamma;
|
use super::Gamma;
|
||||||
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_gamma_large_shape(bh: &mut BenchHarness) {
|
fn bench_gamma_large_shape(bh: &mut BenchHarness) {
|
||||||
let gamma = Gamma::new(10., 1.0);
|
let gamma = Gamma::new(10., 1.0);
|
||||||
let mut rng = StdRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for _ in range(0, RAND_BENCH_N) {
|
for _ in range(0, RAND_BENCH_N) {
|
||||||
@@ -390,7 +390,7 @@ mod bench {
|
|||||||
#[bench]
|
#[bench]
|
||||||
fn bench_gamma_small_shape(bh: &mut BenchHarness) {
|
fn bench_gamma_small_shape(bh: &mut BenchHarness) {
|
||||||
let gamma = Gamma::new(0.1, 1.0);
|
let gamma = Gamma::new(0.1, 1.0);
|
||||||
let mut rng = StdRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for _ in range(0, RAND_BENCH_N) {
|
for _ in range(0, RAND_BENCH_N) {
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_normal(bh: &mut BenchHarness) {
|
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);
|
let mut normal = Normal::new(-2.71828, 3.14159);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
//! The ISAAC random number generator.
|
//! The ISAAC random number generator.
|
||||||
|
|
||||||
use {Rng, SeedableRng, OSRng};
|
use {Rng, SeedableRng, OSRng};
|
||||||
|
use std::io::IoResult;
|
||||||
use std::iter::{range_step, Repeat};
|
use std::iter::{range_step, Repeat};
|
||||||
use std::slice::raw;
|
use std::slice::raw;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@@ -44,19 +45,23 @@ static EMPTY: IsaacRng = IsaacRng {
|
|||||||
|
|
||||||
impl IsaacRng {
|
impl IsaacRng {
|
||||||
/// Create an ISAAC random number generator with a random seed.
|
/// 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 rng = EMPTY;
|
||||||
|
let mut os_rng = try!(OSRng::new());
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = rng.rsl.as_mut_ptr();
|
let ptr = rng.rsl.as_mut_ptr();
|
||||||
|
|
||||||
raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
|
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.init(true);
|
||||||
rng
|
Ok(rng)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an ISAAC random number generator using the default
|
/// Create an ISAAC random number generator using the default
|
||||||
@@ -249,19 +254,24 @@ static EMPTY_64: Isaac64Rng = Isaac64Rng {
|
|||||||
impl Isaac64Rng {
|
impl Isaac64Rng {
|
||||||
/// Create a 64-bit ISAAC random number generator with a random
|
/// Create a 64-bit ISAAC random number generator with a random
|
||||||
/// seed.
|
/// 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 rng = EMPTY_64;
|
||||||
|
let mut os_rng = try!(OSRng::new());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = rng.rsl.as_mut_ptr();
|
let ptr = rng.rsl.as_mut_ptr();
|
||||||
|
|
||||||
raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
|
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.init(true);
|
||||||
rng
|
Ok(rng)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a 64-bit ISAAC random number generator using the
|
/// Create a 64-bit ISAAC random number generator using the
|
||||||
@@ -430,19 +440,19 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{IsaacRng, Isaac64Rng};
|
use super::{IsaacRng, Isaac64Rng};
|
||||||
use {Rng, SeedableRng, OSRng};
|
use {Rng, SeedableRng, task_rng};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rng_32_rand_seeded() {
|
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 ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
|
||||||
let mut rb: 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));
|
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rng_64_rand_seeded() {
|
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 ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
|
||||||
let mut rb: 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));
|
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
|
||||||
@@ -465,7 +475,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rng_32_reseed() {
|
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 mut r: IsaacRng = SeedableRng::from_seed(s.as_slice());
|
||||||
let string1 = r.gen_ascii_str(100);
|
let string1 = r.gen_ascii_str(100);
|
||||||
|
|
||||||
@@ -476,7 +486,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rng_64_reseed() {
|
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 mut r: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
|
||||||
let string1 = r.gen_ascii_str(100);
|
let string1 = r.gen_ascii_str(100);
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ println!("{:?}", tuple_ptr)
|
|||||||
#[phase(syntax, link)] extern crate log;
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
use std::io::IoResult;
|
||||||
use std::kinds::marker;
|
use std::kinds::marker;
|
||||||
use std::local_data;
|
use std::local_data;
|
||||||
use std::str;
|
use std::str;
|
||||||
@@ -403,7 +404,7 @@ pub trait SeedableRng<Seed>: Rng {
|
|||||||
/// appropriate.
|
/// appropriate.
|
||||||
#[deprecated="use `task_rng` or `StdRng::new`"]
|
#[deprecated="use `task_rng` or `StdRng::new`"]
|
||||||
pub fn rng() -> StdRng {
|
pub fn rng() -> StdRng {
|
||||||
StdRng::new()
|
StdRng::new().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The standard RNG. This is designed to be efficient on the current
|
/// The standard RNG. This is designed to be efficient on the current
|
||||||
@@ -425,9 +426,12 @@ impl StdRng {
|
|||||||
/// number of random numbers, or doesn't need the utmost speed for
|
/// number of random numbers, or doesn't need the utmost speed for
|
||||||
/// generating each number, `task_rng` and/or `random` may be more
|
/// generating each number, `task_rng` and/or `random` may be more
|
||||||
/// appropriate.
|
/// appropriate.
|
||||||
|
///
|
||||||
|
/// Reading the randomness from the OS may fail, and any error is
|
||||||
|
/// propagated via the `IoResult` return value.
|
||||||
#[cfg(not(target_word_size="64"))]
|
#[cfg(not(target_word_size="64"))]
|
||||||
pub fn new() -> StdRng {
|
pub fn new() -> IoResult<StdRng> {
|
||||||
StdRng { rng: IsaacRng::new() }
|
IsaacRng::new().map(|r| StdRng { rng: r })
|
||||||
}
|
}
|
||||||
/// Create a randomly seeded instance of `StdRng`.
|
/// Create a randomly seeded instance of `StdRng`.
|
||||||
///
|
///
|
||||||
@@ -437,9 +441,12 @@ impl StdRng {
|
|||||||
/// number of random numbers, or doesn't need the utmost speed for
|
/// number of random numbers, or doesn't need the utmost speed for
|
||||||
/// generating each number, `task_rng` and/or `random` may be more
|
/// generating each number, `task_rng` and/or `random` may be more
|
||||||
/// appropriate.
|
/// appropriate.
|
||||||
|
///
|
||||||
|
/// Reading the randomness from the OS may fail, and any error is
|
||||||
|
/// propagated via the `IoResult` return value.
|
||||||
#[cfg(target_word_size="64")]
|
#[cfg(target_word_size="64")]
|
||||||
pub fn new() -> StdRng {
|
pub fn new() -> IoResult<StdRng> {
|
||||||
StdRng { rng: Isaac64Rng::new() }
|
Isaac64Rng::new().map(|r| StdRng { rng: r })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,7 +484,10 @@ impl<'a> SeedableRng<&'a [uint]> for StdRng {
|
|||||||
/// This will read randomness from the operating system to seed the
|
/// This will read randomness from the operating system to seed the
|
||||||
/// generator.
|
/// generator.
|
||||||
pub fn weak_rng() -> XorShiftRng {
|
pub fn weak_rng() -> XorShiftRng {
|
||||||
XorShiftRng::new()
|
match XorShiftRng::new() {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => fail!("weak_rng: failed to create seeded RNG: {}", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An Xorshift[1] random number
|
/// An Xorshift[1] random number
|
||||||
@@ -539,10 +549,10 @@ impl SeedableRng<[u32, .. 4]> for XorShiftRng {
|
|||||||
|
|
||||||
impl XorShiftRng {
|
impl XorShiftRng {
|
||||||
/// Create an xor shift random number generator with a random seed.
|
/// Create an xor shift random number generator with a random seed.
|
||||||
pub fn new() -> XorShiftRng {
|
pub fn new() -> IoResult<XorShiftRng> {
|
||||||
let mut s = [0u8, ..16];
|
let mut s = [0u8, ..16];
|
||||||
|
let mut r = try!(OSRng::new());
|
||||||
loop {
|
loop {
|
||||||
let mut r = OSRng::new();
|
|
||||||
r.fill_bytes(s);
|
r.fill_bytes(s);
|
||||||
|
|
||||||
if !s.iter().all(|x| *x == 0) {
|
if !s.iter().all(|x| *x == 0) {
|
||||||
@@ -550,7 +560,7 @@ impl XorShiftRng {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let s: [u32, ..4] = unsafe { cast::transmute(s) };
|
let s: [u32, ..4] = unsafe { cast::transmute(s) };
|
||||||
SeedableRng::from_seed(s)
|
Ok(SeedableRng::from_seed(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,7 +569,10 @@ struct TaskRngReseeder;
|
|||||||
|
|
||||||
impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
|
impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
|
||||||
fn reseed(&mut self, rng: &mut StdRng) {
|
fn reseed(&mut self, rng: &mut StdRng) {
|
||||||
*rng = StdRng::new();
|
*rng = match StdRng::new() {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => fail!("could not reseed task_rng: {}", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
|
static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
|
||||||
@@ -596,7 +609,11 @@ local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
|
|||||||
pub fn task_rng() -> TaskRng {
|
pub fn task_rng() -> TaskRng {
|
||||||
local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
|
local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
|
||||||
None => {
|
None => {
|
||||||
let mut rng = ~reseeding::ReseedingRng::new(StdRng::new(),
|
let r = match StdRng::new() {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => fail!("could not initialize task_rng: {}", e)
|
||||||
|
};
|
||||||
|
let mut rng = ~reseeding::ReseedingRng::new(r,
|
||||||
TASK_RNG_RESEED_THRESHOLD,
|
TASK_RNG_RESEED_THRESHOLD,
|
||||||
TaskRngReseeder);
|
TaskRngReseeder);
|
||||||
let ptr = &mut *rng as *mut TaskRngInner;
|
let ptr = &mut *rng as *mut TaskRngInner;
|
||||||
@@ -679,7 +696,7 @@ pub struct Closed01<F>(F);
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use super::{Rng, task_rng, random, OSRng, SeedableRng, StdRng};
|
use super::{Rng, task_rng, random, SeedableRng, StdRng};
|
||||||
|
|
||||||
struct ConstRng { i: u64 }
|
struct ConstRng { i: u64 }
|
||||||
impl Rng for ConstRng {
|
impl Rng for ConstRng {
|
||||||
@@ -841,7 +858,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_std_rng_seeded() {
|
fn test_std_rng_seeded() {
|
||||||
let s = OSRng::new().gen_vec::<uint>(256);
|
let s = task_rng().gen_vec::<uint>(256);
|
||||||
let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
|
let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
|
||||||
let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
|
let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
|
||||||
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
|
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
|
||||||
@@ -849,7 +866,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_std_rng_reseed() {
|
fn test_std_rng_reseed() {
|
||||||
let s = OSRng::new().gen_vec::<uint>(256);
|
let s = task_rng().gen_vec::<uint>(256);
|
||||||
let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
|
let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
|
||||||
let string1 = r.gen_ascii_str(100);
|
let string1 = r.gen_ascii_str(100);
|
||||||
|
|
||||||
@@ -872,7 +889,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_xorshift(bh: &mut BenchHarness) {
|
fn rand_xorshift(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for _ in range(0, RAND_BENCH_N) {
|
for _ in range(0, RAND_BENCH_N) {
|
||||||
rng.gen::<uint>();
|
rng.gen::<uint>();
|
||||||
@@ -883,7 +900,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_isaac(bh: &mut BenchHarness) {
|
fn rand_isaac(bh: &mut BenchHarness) {
|
||||||
let mut rng = IsaacRng::new();
|
let mut rng = IsaacRng::new().unwrap();
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for _ in range(0, RAND_BENCH_N) {
|
for _ in range(0, RAND_BENCH_N) {
|
||||||
rng.gen::<uint>();
|
rng.gen::<uint>();
|
||||||
@@ -894,7 +911,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_isaac64(bh: &mut BenchHarness) {
|
fn rand_isaac64(bh: &mut BenchHarness) {
|
||||||
let mut rng = Isaac64Rng::new();
|
let mut rng = Isaac64Rng::new().unwrap();
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for _ in range(0, RAND_BENCH_N) {
|
for _ in range(0, RAND_BENCH_N) {
|
||||||
rng.gen::<uint>();
|
rng.gen::<uint>();
|
||||||
@@ -905,7 +922,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_std(bh: &mut BenchHarness) {
|
fn rand_std(bh: &mut BenchHarness) {
|
||||||
let mut rng = StdRng::new();
|
let mut rng = StdRng::new().unwrap();
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for _ in range(0, RAND_BENCH_N) {
|
for _ in range(0, RAND_BENCH_N) {
|
||||||
rng.gen::<uint>();
|
rng.gen::<uint>();
|
||||||
@@ -916,7 +933,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn rand_shuffle_100(bh: &mut BenchHarness) {
|
fn rand_shuffle_100(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
let x : &mut[uint] = [1,..100];
|
let x : &mut[uint] = [1,..100];
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
rng.shuffle_mut(x);
|
rng.shuffle_mut(x);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub use self::imp::OSRng;
|
|||||||
mod imp {
|
mod imp {
|
||||||
use Rng;
|
use Rng;
|
||||||
use reader::ReaderRng;
|
use reader::ReaderRng;
|
||||||
use std::io::File;
|
use std::io::{IoResult, File};
|
||||||
|
|
||||||
/// A random number generator that retrieves randomness straight from
|
/// A random number generator that retrieves randomness straight from
|
||||||
/// the operating system. Platform sources:
|
/// the operating system. Platform sources:
|
||||||
@@ -35,12 +35,11 @@ mod imp {
|
|||||||
|
|
||||||
impl OSRng {
|
impl OSRng {
|
||||||
/// Create a new `OSRng`.
|
/// Create a new `OSRng`.
|
||||||
pub fn new() -> OSRng {
|
pub fn new() -> IoResult<OSRng> {
|
||||||
let reader = File::open(&Path::new("/dev/urandom"));
|
let reader = try!(File::open(&Path::new("/dev/urandom")));
|
||||||
let reader = reader.ok().expect("Error opening /dev/urandom");
|
|
||||||
let reader_rng = ReaderRng::new(reader);
|
let reader_rng = ReaderRng::new(reader);
|
||||||
|
|
||||||
OSRng { inner: reader_rng }
|
Ok(OSRng { inner: reader_rng })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +60,7 @@ mod imp {
|
|||||||
mod imp {
|
mod imp {
|
||||||
use Rng;
|
use Rng;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
use std::io::{IoResult, IoError};
|
||||||
use std::libc::{c_ulong, DWORD, BYTE, LPCSTR, BOOL};
|
use std::libc::{c_ulong, DWORD, BYTE, LPCSTR, BOOL};
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::rt::stack;
|
use std::rt::stack;
|
||||||
@@ -99,7 +99,7 @@ mod imp {
|
|||||||
|
|
||||||
impl OSRng {
|
impl OSRng {
|
||||||
/// Create a new `OSRng`.
|
/// Create a new `OSRng`.
|
||||||
pub fn new() -> OSRng {
|
pub fn new() -> IoResult<OSRng> {
|
||||||
let mut hcp = 0;
|
let mut hcp = 0;
|
||||||
let mut ret = unsafe {
|
let mut ret = unsafe {
|
||||||
CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
|
CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
|
||||||
@@ -143,9 +143,10 @@ mod imp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
fail!("couldn't create context: {}", os::last_os_error());
|
Err(IoError::last_error())
|
||||||
|
} else {
|
||||||
|
Ok(OSRng { hcryptprov: hcp })
|
||||||
}
|
}
|
||||||
OSRng { hcryptprov: hcp }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +192,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_os_rng() {
|
fn test_os_rng() {
|
||||||
let mut r = OSRng::new();
|
let mut r = OSRng::new().unwrap();
|
||||||
|
|
||||||
r.next_u32();
|
r.next_u32();
|
||||||
r.next_u64();
|
r.next_u64();
|
||||||
@@ -213,7 +214,7 @@ mod test {
|
|||||||
|
|
||||||
// deschedule to attempt to interleave things as much
|
// deschedule to attempt to interleave things as much
|
||||||
// as possible (XXX: is this a good test?)
|
// as possible (XXX: is this a good test?)
|
||||||
let mut r = OSRng::new();
|
let mut r = OSRng::new().unwrap();
|
||||||
task::deschedule();
|
task::deschedule();
|
||||||
let mut v = [0u8, .. 1000];
|
let mut v = [0u8, .. 1000];
|
||||||
|
|
||||||
|
|||||||
@@ -100,12 +100,12 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>>
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use rand::{Rng, SeedableRng};
|
/// use rand::{Rng, SeedableRng, StdRng};
|
||||||
/// use rand::reseeding::{Reseeder, ReseedingRng};
|
/// use rand::reseeding::{Reseeder, ReseedingRng};
|
||||||
///
|
///
|
||||||
/// struct TickTockReseeder { tick: bool }
|
/// struct TickTockReseeder { tick: bool }
|
||||||
/// impl Reseeder<rand::StdRng> for TickTockReseeder {
|
/// impl Reseeder<StdRng> for TickTockReseeder {
|
||||||
/// fn reseed(&mut self, rng: &mut rand::StdRng) {
|
/// fn reseed(&mut self, rng: &mut StdRng) {
|
||||||
/// let val = if self.tick {0} else {1};
|
/// let val = if self.tick {0} else {1};
|
||||||
/// rng.reseed(&[val]);
|
/// rng.reseed(&[val]);
|
||||||
/// self.tick = !self.tick;
|
/// self.tick = !self.tick;
|
||||||
@@ -113,7 +113,9 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>>
|
|||||||
/// }
|
/// }
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let rsdr = TickTockReseeder { tick: true };
|
/// let rsdr = TickTockReseeder { tick: true };
|
||||||
/// let mut rng = ReseedingRng::new(rand::StdRng::new(), 10, rsdr);
|
///
|
||||||
|
/// let inner = StdRng::new().unwrap();
|
||||||
|
/// let mut rng = ReseedingRng::new(inner, 10, rsdr);
|
||||||
///
|
///
|
||||||
/// // this will repeat, because it gets reseeded very regularly.
|
/// // this will repeat, because it gets reseeded very regularly.
|
||||||
/// println!("{}", rng.gen_ascii_str(100));
|
/// println!("{}", rng.gen_ascii_str(100));
|
||||||
|
|||||||
@@ -400,31 +400,31 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_bin(bh: &mut BenchHarness) {
|
fn format_bin(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:t}", rng.gen::<uint>()); })
|
bh.iter(|| { format!("{:t}", rng.gen::<uint>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_oct(bh: &mut BenchHarness) {
|
fn format_oct(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:o}", rng.gen::<uint>()); })
|
bh.iter(|| { format!("{:o}", rng.gen::<uint>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_dec(bh: &mut BenchHarness) {
|
fn format_dec(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:u}", rng.gen::<uint>()); })
|
bh.iter(|| { format!("{:u}", rng.gen::<uint>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_hex(bh: &mut BenchHarness) {
|
fn format_hex(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:x}", rng.gen::<uint>()); })
|
bh.iter(|| { format!("{:x}", rng.gen::<uint>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_base_36(bh: &mut BenchHarness) {
|
fn format_base_36(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{}", radix(rng.gen::<uint>(), 36)); })
|
bh.iter(|| { format!("{}", radix(rng.gen::<uint>(), 36)); })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,31 +436,31 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_bin(bh: &mut BenchHarness) {
|
fn format_bin(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:t}", rng.gen::<int>()); })
|
bh.iter(|| { format!("{:t}", rng.gen::<int>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_oct(bh: &mut BenchHarness) {
|
fn format_oct(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:o}", rng.gen::<int>()); })
|
bh.iter(|| { format!("{:o}", rng.gen::<int>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_dec(bh: &mut BenchHarness) {
|
fn format_dec(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:d}", rng.gen::<int>()); })
|
bh.iter(|| { format!("{:d}", rng.gen::<int>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_hex(bh: &mut BenchHarness) {
|
fn format_hex(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{:x}", rng.gen::<int>()); })
|
bh.iter(|| { format!("{:x}", rng.gen::<int>()); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn format_base_36(bh: &mut BenchHarness) {
|
fn format_base_36(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { format!("{}", radix(rng.gen::<int>(), 36)); })
|
bh.iter(|| { format!("{}", radix(rng.gen::<int>(), 36)); })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1286,7 +1286,7 @@ mod test {
|
|||||||
use rand::{StdRng, Rng};
|
use rand::{StdRng, Rng};
|
||||||
|
|
||||||
let mut bytes = [0, ..1024];
|
let mut bytes = [0, ..1024];
|
||||||
StdRng::new().fill_bytes(bytes);
|
StdRng::new().unwrap().fill_bytes(bytes);
|
||||||
|
|
||||||
let tmpdir = tmpdir();
|
let tmpdir = tmpdir();
|
||||||
|
|
||||||
|
|||||||
@@ -216,6 +216,8 @@ use container::Container;
|
|||||||
use fmt;
|
use fmt;
|
||||||
use int;
|
use int;
|
||||||
use iter::Iterator;
|
use iter::Iterator;
|
||||||
|
use libc;
|
||||||
|
use os;
|
||||||
use option::{Option, Some, None};
|
use option::{Option, Some, None};
|
||||||
use path::Path;
|
use path::Path;
|
||||||
use result::{Ok, Err, Result};
|
use result::{Ok, Err, Result};
|
||||||
@@ -290,6 +292,88 @@ pub struct IoError {
|
|||||||
pub detail: Option<~str>
|
pub detail: Option<~str>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IoError {
|
||||||
|
/// Convert an `errno` value into an `IoError`.
|
||||||
|
///
|
||||||
|
/// If `detail` is `true`, the `detail` field of the `IoError`
|
||||||
|
/// struct is filled with an allocated string describing the error
|
||||||
|
/// in more detail, retrieved from the operating system.
|
||||||
|
pub fn from_errno(errno: uint, detail: bool) -> IoError {
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn get_err(errno: i32) -> (IoErrorKind, &'static str) {
|
||||||
|
match errno {
|
||||||
|
libc::EOF => (EndOfFile, "end of file"),
|
||||||
|
libc::ERROR_NO_DATA => (BrokenPipe, "the pipe is being closed"),
|
||||||
|
libc::ERROR_FILE_NOT_FOUND => (FileNotFound, "file not found"),
|
||||||
|
libc::ERROR_INVALID_NAME => (InvalidInput, "invalid file name"),
|
||||||
|
libc::WSAECONNREFUSED => (ConnectionRefused, "connection refused"),
|
||||||
|
libc::WSAECONNRESET => (ConnectionReset, "connection reset"),
|
||||||
|
libc::WSAEACCES => (PermissionDenied, "permission denied"),
|
||||||
|
libc::WSAEWOULDBLOCK => {
|
||||||
|
(ResourceUnavailable, "resource temporarily unavailable")
|
||||||
|
}
|
||||||
|
libc::WSAENOTCONN => (NotConnected, "not connected"),
|
||||||
|
libc::WSAECONNABORTED => (ConnectionAborted, "connection aborted"),
|
||||||
|
libc::WSAEADDRNOTAVAIL => (ConnectionRefused, "address not available"),
|
||||||
|
libc::WSAEADDRINUSE => (ConnectionRefused, "address in use"),
|
||||||
|
libc::ERROR_BROKEN_PIPE => (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 => (InvalidInput,
|
||||||
|
"illegal operation on a directory"),
|
||||||
|
|
||||||
|
_ => (OtherIoError, "unknown error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn get_err(errno: i32) -> (IoErrorKind, &'static str) {
|
||||||
|
// FIXME: this should probably be a bit more descriptive...
|
||||||
|
match errno {
|
||||||
|
libc::EOF => (EndOfFile, "end of file"),
|
||||||
|
libc::ECONNREFUSED => (ConnectionRefused, "connection refused"),
|
||||||
|
libc::ECONNRESET => (ConnectionReset, "connection reset"),
|
||||||
|
libc::EPERM | libc::EACCES =>
|
||||||
|
(PermissionDenied, "permission denied"),
|
||||||
|
libc::EPIPE => (BrokenPipe, "broken pipe"),
|
||||||
|
libc::ENOTCONN => (NotConnected, "not connected"),
|
||||||
|
libc::ECONNABORTED => (ConnectionAborted, "connection aborted"),
|
||||||
|
libc::EADDRNOTAVAIL => (ConnectionRefused, "address not available"),
|
||||||
|
libc::EADDRINUSE => (ConnectionRefused, "address in use"),
|
||||||
|
libc::ENOENT => (FileNotFound, "no such file or directory"),
|
||||||
|
libc::EISDIR => (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 =>
|
||||||
|
(ResourceUnavailable, "resource temporarily unavailable"),
|
||||||
|
|
||||||
|
_ => (OtherIoError, "unknown error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (kind, desc) = get_err(errno as i32);
|
||||||
|
IoError {
|
||||||
|
kind: kind,
|
||||||
|
desc: desc,
|
||||||
|
detail: if detail {Some(os::error_string(errno))} else {None},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the last error to occur as a (detailed) IoError.
|
||||||
|
///
|
||||||
|
/// This uses the OS `errno`, and so there should not be any task
|
||||||
|
/// descheduling or migration (other than that performed by the
|
||||||
|
/// operating system) between the call(s) for which errors are
|
||||||
|
/// being checked and the call of this function.
|
||||||
|
pub fn last_error() -> IoError {
|
||||||
|
IoError::from_errno(os::errno() as uint, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Show for IoError {
|
impl fmt::Show for IoError {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
try!(fmt.buf.write_str(self.desc));
|
try!(fmt.buf.write_str(self.desc));
|
||||||
|
|||||||
@@ -821,31 +821,31 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_bin(bh: &mut BenchHarness) {
|
fn to_str_bin(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<uint>().to_str_radix(2); })
|
bh.iter(|| { rng.gen::<uint>().to_str_radix(2); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_oct(bh: &mut BenchHarness) {
|
fn to_str_oct(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<uint>().to_str_radix(8); })
|
bh.iter(|| { rng.gen::<uint>().to_str_radix(8); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_dec(bh: &mut BenchHarness) {
|
fn to_str_dec(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<uint>().to_str_radix(10); })
|
bh.iter(|| { rng.gen::<uint>().to_str_radix(10); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_hex(bh: &mut BenchHarness) {
|
fn to_str_hex(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<uint>().to_str_radix(16); })
|
bh.iter(|| { rng.gen::<uint>().to_str_radix(16); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_base_36(bh: &mut BenchHarness) {
|
fn to_str_base_36(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<uint>().to_str_radix(36); })
|
bh.iter(|| { rng.gen::<uint>().to_str_radix(36); })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -857,31 +857,31 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_bin(bh: &mut BenchHarness) {
|
fn to_str_bin(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<int>().to_str_radix(2); })
|
bh.iter(|| { rng.gen::<int>().to_str_radix(2); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_oct(bh: &mut BenchHarness) {
|
fn to_str_oct(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<int>().to_str_radix(8); })
|
bh.iter(|| { rng.gen::<int>().to_str_radix(8); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_dec(bh: &mut BenchHarness) {
|
fn to_str_dec(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<int>().to_str_radix(10); })
|
bh.iter(|| { rng.gen::<int>().to_str_radix(10); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_hex(bh: &mut BenchHarness) {
|
fn to_str_hex(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<int>().to_str_radix(16); })
|
bh.iter(|| { rng.gen::<int>().to_str_radix(16); })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn to_str_base_36(bh: &mut BenchHarness) {
|
fn to_str_base_36(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { rng.gen::<int>().to_str_radix(36); })
|
bh.iter(|| { rng.gen::<int>().to_str_radix(36); })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,7 +893,7 @@ mod bench {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn float_to_str(bh: &mut BenchHarness) {
|
fn float_to_str(bh: &mut BenchHarness) {
|
||||||
let mut rng = XorShiftRng::new();
|
let mut rng = XorShiftRng::new().unwrap();
|
||||||
bh.iter(|| { f64::to_str(rng.gen()); })
|
bh.iter(|| { f64::to_str(rng.gen()); })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -663,10 +663,12 @@ pub fn errno() -> uint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a string representing the platform-dependent last error
|
/// Return the string corresponding to an `errno()` value of `errnum`.
|
||||||
pub fn last_os_error() -> ~str {
|
pub fn error_string(errnum: uint) -> ~str {
|
||||||
|
return strerror(errnum);
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn strerror() -> ~str {
|
fn strerror(errnum: uint) -> ~str {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[cfg(target_os = "freebsd")]
|
#[cfg(target_os = "freebsd")]
|
||||||
@@ -702,7 +704,7 @@ pub fn last_os_error() -> ~str {
|
|||||||
|
|
||||||
let p = buf.as_mut_ptr();
|
let p = buf.as_mut_ptr();
|
||||||
unsafe {
|
unsafe {
|
||||||
if strerror_r(errno() as c_int, p, buf.len() as libc::size_t) < 0 {
|
if strerror_r(errnum as c_int, p, buf.len() as libc::size_t) < 0 {
|
||||||
fail!("strerror_r failure");
|
fail!("strerror_r failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +713,7 @@ pub fn last_os_error() -> ~str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn strerror() -> ~str {
|
fn strerror(errnum: uint) -> ~str {
|
||||||
use libc::types::os::arch::extra::DWORD;
|
use libc::types::os::arch::extra::DWORD;
|
||||||
use libc::types::os::arch::extra::LPWSTR;
|
use libc::types::os::arch::extra::LPWSTR;
|
||||||
use libc::types::os::arch::extra::LPVOID;
|
use libc::types::os::arch::extra::LPVOID;
|
||||||
@@ -735,7 +737,6 @@ pub fn last_os_error() -> ~str {
|
|||||||
// This value is calculated from the macro
|
// This value is calculated from the macro
|
||||||
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
|
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
|
||||||
let langId = 0x0800 as DWORD;
|
let langId = 0x0800 as DWORD;
|
||||||
let err = errno() as DWORD;
|
|
||||||
|
|
||||||
let mut buf = [0 as WCHAR, ..TMPBUF_SZ];
|
let mut buf = [0 as WCHAR, ..TMPBUF_SZ];
|
||||||
|
|
||||||
@@ -743,7 +744,7 @@ pub fn last_os_error() -> ~str {
|
|||||||
let res = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
let res = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
ptr::mut_null(),
|
ptr::mut_null(),
|
||||||
err,
|
errnum as DWORD,
|
||||||
langId,
|
langId,
|
||||||
buf.as_mut_ptr(),
|
buf.as_mut_ptr(),
|
||||||
buf.len() as DWORD,
|
buf.len() as DWORD,
|
||||||
@@ -751,18 +752,21 @@ pub fn last_os_error() -> ~str {
|
|||||||
if res == 0 {
|
if res == 0 {
|
||||||
// Sometimes FormatMessageW can fail e.g. system doesn't like langId,
|
// Sometimes FormatMessageW can fail e.g. system doesn't like langId,
|
||||||
let fm_err = errno();
|
let fm_err = errno();
|
||||||
return format!("OS Error {} (FormatMessageW() returned error {})", err, fm_err);
|
return format!("OS Error {} (FormatMessageW() returned error {})", errnum, fm_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = str::from_utf16(str::truncate_utf16_at_nul(buf));
|
let msg = str::from_utf16(str::truncate_utf16_at_nul(buf));
|
||||||
match msg {
|
match msg {
|
||||||
Some(msg) => format!("OS Error {}: {}", err, msg),
|
Some(msg) => format!("OS Error {}: {}", errnum, msg),
|
||||||
None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", err),
|
None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strerror()
|
/// Get a string representing the platform-dependent last error
|
||||||
|
pub fn last_os_error() -> ~str {
|
||||||
|
error_string(errno() as uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;
|
static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rng() {
|
fn rng() {
|
||||||
use rand::{StdRng, Rng};
|
use rand::{StdRng, Rng};
|
||||||
let mut r = StdRng::new();
|
let mut r = StdRng::new().unwrap();
|
||||||
let _ = r.next_u32();
|
let _ = r.next_u32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct Noise2DContext {
|
|||||||
|
|
||||||
impl Noise2DContext {
|
impl Noise2DContext {
|
||||||
fn new() -> Noise2DContext {
|
fn new() -> Noise2DContext {
|
||||||
let mut rng = StdRng::new();
|
let mut rng = StdRng::new().unwrap();
|
||||||
|
|
||||||
let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }, ..256];
|
let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }, ..256];
|
||||||
for x in rgradients.mut_iter() {
|
for x in rgradients.mut_iter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user