Skip to content

Commit b71c02e

Browse files
committed
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).
2 parents b8ef9fd + bc7a2d7 commit b71c02e

File tree

20 files changed

+216
-158
lines changed

20 files changed

+216
-158
lines changed

src/libcollections/deque.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub mod bench {
5252
map: &mut M,
5353
bh: &mut BenchHarness) {
5454
// setup
55-
let mut rng = rand::XorShiftRng::new();
55+
let mut rng = rand::weak_rng();
5656

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

9595
for k in keys.iter() {

src/libgreen/sched.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,12 @@ impl ClosureConverter for UnsafeTaskReceiver {
967967
// worry there.
968968
#[cfg(windows)]
969969
fn new_sched_rng() -> XorShiftRng {
970-
XorShiftRng::new()
970+
match XorShiftRng::new() {
971+
Ok(r) => r,
972+
Err(e) => {
973+
rtabort!("sched: failed to create seeded RNG: {}", e)
974+
}
975+
}
971976
}
972977
#[cfg(unix)]
973978
fn new_sched_rng() -> XorShiftRng {

src/libnative/io/addrinfo.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,8 @@ extern "system" {
9696

9797
#[cfg(windows)]
9898
fn get_error(_: c_int) -> IoError {
99-
use super::translate_error;
100-
10199
unsafe {
102-
translate_error(WSAGetLastError() as i32, true)
100+
IoError::from_errno(WSAGetLastError() as uint, true)
103101
}
104102
}
105103

src/libnative/io/mod.rs

+2-65
Original file line numberDiff line numberDiff line change
@@ -86,73 +86,10 @@ fn unimpl() -> IoError {
8686
}
8787
}
8888

89-
fn translate_error(errno: i32, detail: bool) -> IoError {
90-
#[cfg(windows)]
91-
fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
92-
match errno {
93-
libc::EOF => (io::EndOfFile, "end of file"),
94-
libc::ERROR_NO_DATA => (io::BrokenPipe, "the pipe is being closed"),
95-
libc::ERROR_FILE_NOT_FOUND => (io::FileNotFound, "file not found"),
96-
libc::ERROR_INVALID_NAME => (io::InvalidInput, "invalid file name"),
97-
libc::WSAECONNREFUSED => (io::ConnectionRefused, "connection refused"),
98-
libc::WSAECONNRESET => (io::ConnectionReset, "connection reset"),
99-
libc::WSAEACCES => (io::PermissionDenied, "permission denied"),
100-
libc::WSAEWOULDBLOCK => {
101-
(io::ResourceUnavailable, "resource temporarily unavailable")
102-
}
103-
libc::WSAENOTCONN => (io::NotConnected, "not connected"),
104-
libc::WSAECONNABORTED => (io::ConnectionAborted, "connection aborted"),
105-
libc::WSAEADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
106-
libc::WSAEADDRINUSE => (io::ConnectionRefused, "address in use"),
107-
libc::ERROR_BROKEN_PIPE => (io::EndOfFile, "the pipe has ended"),
108-
109-
// libuv maps this error code to EISDIR. we do too. if it is found
110-
// to be incorrect, we can add in some more machinery to only
111-
// return this message when ERROR_INVALID_FUNCTION after certain
112-
// win32 calls.
113-
libc::ERROR_INVALID_FUNCTION => (io::InvalidInput,
114-
"illegal operation on a directory"),
115-
116-
_ => (io::OtherIoError, "unknown error")
117-
}
118-
}
119-
120-
#[cfg(not(windows))]
121-
fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
122-
// FIXME: this should probably be a bit more descriptive...
123-
match errno {
124-
libc::EOF => (io::EndOfFile, "end of file"),
125-
libc::ECONNREFUSED => (io::ConnectionRefused, "connection refused"),
126-
libc::ECONNRESET => (io::ConnectionReset, "connection reset"),
127-
libc::EPERM | libc::EACCES =>
128-
(io::PermissionDenied, "permission denied"),
129-
libc::EPIPE => (io::BrokenPipe, "broken pipe"),
130-
libc::ENOTCONN => (io::NotConnected, "not connected"),
131-
libc::ECONNABORTED => (io::ConnectionAborted, "connection aborted"),
132-
libc::EADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
133-
libc::EADDRINUSE => (io::ConnectionRefused, "address in use"),
134-
libc::ENOENT => (io::FileNotFound, "no such file or directory"),
135-
libc::EISDIR => (io::InvalidInput, "illegal operation on a directory"),
136-
137-
// These two constants can have the same value on some systems, but
138-
// different values on others, so we can't use a match clause
139-
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
140-
(io::ResourceUnavailable, "resource temporarily unavailable"),
141-
142-
_ => (io::OtherIoError, "unknown error")
143-
}
144-
}
145-
146-
let (kind, desc) = get_err(errno);
147-
IoError {
148-
kind: kind,
149-
desc: desc,
150-
detail: if detail {Some(os::last_os_error())} else {None},
151-
}
89+
fn last_error() -> IoError {
90+
IoError::last_error()
15291
}
15392

154-
fn last_error() -> IoError { translate_error(os::errno() as i32, true) }
155-
15693
// unix has nonzero values as errors
15794
fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
15895
if ret != 0 {

src/libnative/io/net.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ fn last_error() -> io::IoError {
120120
extern "system" {
121121
fn WSAGetLastError() -> libc::c_int;
122122
}
123-
super::translate_error(unsafe { WSAGetLastError() }, true)
123+
io::IoError::from_errno(unsafe { WSAGetLastError() } as uint, true)
124124
}
125125

126126
#[cfg(not(windows))]

src/libnative/io/process.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ fn spawn_process_os(config: p::ProcessConfig,
481481
(bytes[1] << 16) as i32 |
482482
(bytes[2] << 8) as i32 |
483483
(bytes[3] << 0) as i32;
484-
Err(super::translate_error(errno, false))
484+
Err(io::IoError::from_errno(errno as uint, false))
485485
}
486486
Err(e) => {
487487
assert!(e.kind == io::BrokenPipe ||

src/librand/distributions/exponential.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ mod bench {
126126

127127
#[bench]
128128
fn rand_exp(bh: &mut BenchHarness) {
129-
let mut rng = XorShiftRng::new();
129+
let mut rng = XorShiftRng::new().unwrap();
130130
let mut exp = Exp::new(2.71828 * 3.14159);
131131

132132
bh.iter(|| {

src/librand/distributions/gamma.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,14 @@ mod bench {
370370
use self::test::BenchHarness;
371371
use std::mem::size_of;
372372
use distributions::IndependentSample;
373-
use {StdRng, RAND_BENCH_N};
373+
use {XorShiftRng, RAND_BENCH_N};
374374
use super::Gamma;
375375

376376

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

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

395395
bh.iter(|| {
396396
for _ in range(0, RAND_BENCH_N) {

src/librand/distributions/normal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ mod bench {
193193

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

199199
bh.iter(|| {

src/librand/isaac.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//! The ISAAC random number generator.
1212
1313
use {Rng, SeedableRng, OSRng};
14+
use std::io::IoResult;
1415
use std::iter::{range_step, Repeat};
1516
use std::slice::raw;
1617
use std::mem;
@@ -44,19 +45,23 @@ static EMPTY: IsaacRng = IsaacRng {
4445

4546
impl IsaacRng {
4647
/// Create an ISAAC random number generator with a random seed.
47-
pub fn new() -> IsaacRng {
48+
///
49+
/// This reads randomness from the operating system (via `OSRng`)
50+
/// which may fail, any error is propagated via the `IoResult`
51+
/// return value.
52+
pub fn new() -> IoResult<IsaacRng> {
4853
let mut rng = EMPTY;
49-
54+
let mut os_rng = try!(OSRng::new());
5055
unsafe {
5156
let ptr = rng.rsl.as_mut_ptr();
5257

5358
raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
54-
OSRng::new().fill_bytes(slice);
59+
os_rng.fill_bytes(slice);
5560
})
5661
}
5762

5863
rng.init(true);
59-
rng
64+
Ok(rng)
6065
}
6166

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

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

258268
raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
259-
OSRng::new().fill_bytes(slice);
269+
os_rng.fill_bytes(slice);
260270
})
261271
}
262272

263273
rng.init(true);
264-
rng
274+
Ok(rng)
265275
}
266276

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

436446
#[test]
437447
fn test_rng_32_rand_seeded() {
438-
let s = OSRng::new().gen_vec::<u32>(256);
448+
let s = task_rng().gen_vec::<u32>(256);
439449
let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
440450
let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice());
441451
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
442452
}
443453
#[test]
444454
fn test_rng_64_rand_seeded() {
445-
let s = OSRng::new().gen_vec::<u64>(256);
455+
let s = task_rng().gen_vec::<u64>(256);
446456
let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
447457
let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
448458
assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
@@ -465,7 +475,7 @@ mod test {
465475

466476
#[test]
467477
fn test_rng_32_reseed() {
468-
let s = OSRng::new().gen_vec::<u32>(256);
478+
let s = task_rng().gen_vec::<u32>(256);
469479
let mut r: IsaacRng = SeedableRng::from_seed(s.as_slice());
470480
let string1 = r.gen_ascii_str(100);
471481

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

0 commit comments

Comments
 (0)