@@ -76,6 +76,7 @@ println!("{:?}", tuple_ptr)
7676#[ phase( syntax, link) ] extern crate log;
7777
7878use std:: cast;
79+ use std:: io:: IoResult ;
7980use std:: kinds:: marker;
8081use std:: local_data;
8182use std:: str;
@@ -401,7 +402,7 @@ pub trait SeedableRng<Seed>: Rng {
401402/// appropriate.
402403#[ deprecated="use `task_rng` or `StdRng::new`" ]
403404pub fn rng ( ) -> StdRng {
404- StdRng :: new ( )
405+ StdRng :: new ( ) . unwrap ( )
405406}
406407
407408/// The standard RNG. This is designed to be efficient on the current
@@ -423,9 +424,12 @@ impl StdRng {
423424 /// number of random numbers, or doesn't need the utmost speed for
424425 /// generating each number, `task_rng` and/or `random` may be more
425426 /// appropriate.
427+ ///
428+ /// Reading the randomness from the OS may fail, and any error is
429+ /// propagated via the `IoResult` return value.
426430 #[ cfg( not( target_word_size="64" ) ) ]
427- pub fn new ( ) -> StdRng {
428- StdRng { rng : IsaacRng :: new ( ) }
431+ pub fn new ( ) -> IoResult < StdRng > {
432+ IsaacRng :: new ( ) . map ( |r| StdRng { rng : r } )
429433 }
430434 /// Create a randomly seeded instance of `StdRng`.
431435 ///
@@ -435,9 +439,12 @@ impl StdRng {
435439 /// number of random numbers, or doesn't need the utmost speed for
436440 /// generating each number, `task_rng` and/or `random` may be more
437441 /// appropriate.
442+ ///
443+ /// Reading the randomness from the OS may fail, and any error is
444+ /// propagated via the `IoResult` return value.
438445 #[ cfg( target_word_size="64" ) ]
439- pub fn new ( ) -> StdRng {
440- StdRng { rng : Isaac64Rng :: new ( ) }
446+ pub fn new ( ) -> IoResult < StdRng > {
447+ Isaac64Rng :: new ( ) . map ( |r| StdRng { rng : r } )
441448 }
442449}
443450
@@ -475,7 +482,10 @@ impl<'a> SeedableRng<&'a [uint]> for StdRng {
475482/// This will read randomness from the operating system to seed the
476483/// generator.
477484pub fn weak_rng ( ) -> XorShiftRng {
478- XorShiftRng :: new ( )
485+ match XorShiftRng :: new ( ) {
486+ Ok ( r) => r,
487+ Err ( e) => fail ! ( "weak_rng: failed to create seeded RNG: {}" , e)
488+ }
479489}
480490
481491/// An Xorshift[1] random number
@@ -537,21 +547,18 @@ impl SeedableRng<[u32, .. 4]> for XorShiftRng {
537547
538548impl XorShiftRng {
539549 /// Create an xor shift random number generator with a random seed.
540- pub fn new ( ) -> XorShiftRng {
550+ pub fn new ( ) -> IoResult < XorShiftRng > {
541551 let mut s = [ 0u8 , ..16 ] ;
552+ let mut r = try!( OSRng :: new( ) ) ;
542553 loop {
543- let mut r = match OSRng :: new( ) {
544- Ok ( r) => r,
545- Err ( e) => fail ! ( "XorShiftRng::new: creating OSRng failed: {}" , e)
546- } ;
547554 r. fill_bytes( s) ;
548555
549556 if !s. iter ( ) . all( |x| * x == 0 ) {
550557 break;
551558 }
552559 }
553560 let s: [ u32 , ..4 ] = unsafe { cast:: transmute ( s ) } ;
554- SeedableRng :: from_seed( s)
561+ Ok ( SeedableRng :: from_seed ( s ) )
555562 }
556563}
557564
@@ -560,7 +567,10 @@ struct TaskRngReseeder;
560567
561568impl reseeding:: Reseeder < StdRng > for TaskRngReseeder {
562569 fn reseed ( & mut self , rng : & mut StdRng ) {
563- * rng = StdRng :: new ( ) ;
570+ * rng = match StdRng :: new ( ) {
571+ Ok ( r) => r ,
572+ Err ( e) => fail ! ( "could not reseed task_rng: {}" , e)
573+ }
564574 }
565575}
566576static TASK_RNG_RESEED_THRESHOLD : uint = 32_768 ;
@@ -597,7 +607,11 @@ local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
597607 pub fn task_rng( ) -> TaskRng {
598608 local_data:: get_mut ( TASK_RNG_KEY , |rng| match rng {
599609 None => {
600- let mut rng = ~reseeding:: ReseedingRng :: new ( StdRng :: new ( ) ,
610+ let r = match StdRng :: new ( ) {
611+ Ok ( r) => r,
612+ Err ( e) => fail ! ( "could not initialize task_rng: {}" , e)
613+ } ;
614+ let mut rng = ~reseeding:: ReseedingRng :: new ( r,
601615 TASK_RNG_RESEED_THRESHOLD ,
602616 TaskRngReseeder ) ;
603617 let ptr = & mut * rng as * mut TaskRngInner ;
@@ -680,7 +694,7 @@ pub struct Closed01<F>(F);
680694#[ cfg( test) ]
681695mod test {
682696 use std:: slice;
683- use super :: { Rng , task_rng, random, OSRng , SeedableRng , StdRng } ;
697+ use super :: { Rng , task_rng, random, SeedableRng , StdRng } ;
684698
685699 struct ConstRng { i : u64 }
686700 impl Rng for ConstRng {
@@ -842,15 +856,15 @@ mod test {
842856
843857 #[ test]
844858 fn test_std_rng_seeded ( ) {
845- let s = OSRng :: new ( ) . gen_vec :: < uint > ( 256 ) ;
859+ let s = task_rng ( ) . gen_vec :: < uint > ( 256 ) ;
846860 let mut ra: StdRng = SeedableRng :: from_seed ( s. as_slice ( ) ) ;
847861 let mut rb: StdRng = SeedableRng :: from_seed ( s. as_slice ( ) ) ;
848862 assert_eq ! ( ra. gen_ascii_str( 100 u) , rb. gen_ascii_str( 100 u) ) ;
849863 }
850864
851865 #[ test]
852866 fn test_std_rng_reseed ( ) {
853- let s = OSRng :: new ( ) . gen_vec :: < uint > ( 256 ) ;
867+ let s = task_rng ( ) . gen_vec :: < uint > ( 256 ) ;
854868 let mut r: StdRng = SeedableRng :: from_seed ( s. as_slice ( ) ) ;
855869 let string1 = r. gen_ascii_str ( 100 ) ;
856870
@@ -873,7 +887,7 @@ mod bench {
873887
874888 #[ bench]
875889 fn rand_xorshift ( bh : & mut BenchHarness ) {
876- let mut rng = XorShiftRng :: new ( ) ;
890+ let mut rng = XorShiftRng :: new ( ) . unwrap ( ) ;
877891 bh. iter ( || {
878892 for _ in range ( 0 , RAND_BENCH_N ) {
879893 rng. gen :: < uint > ( ) ;
@@ -884,7 +898,7 @@ mod bench {
884898
885899 #[ bench]
886900 fn rand_isaac ( bh : & mut BenchHarness ) {
887- let mut rng = IsaacRng :: new ( ) ;
901+ let mut rng = IsaacRng :: new ( ) . unwrap ( ) ;
888902 bh. iter ( || {
889903 for _ in range ( 0 , RAND_BENCH_N ) {
890904 rng. gen :: < uint > ( ) ;
@@ -895,7 +909,7 @@ mod bench {
895909
896910 #[ bench]
897911 fn rand_isaac64 ( bh : & mut BenchHarness ) {
898- let mut rng = Isaac64Rng :: new ( ) ;
912+ let mut rng = Isaac64Rng :: new ( ) . unwrap ( ) ;
899913 bh. iter ( || {
900914 for _ in range ( 0 , RAND_BENCH_N ) {
901915 rng. gen :: < uint > ( ) ;
@@ -906,7 +920,7 @@ mod bench {
906920
907921 #[ bench]
908922 fn rand_std ( bh : & mut BenchHarness ) {
909- let mut rng = StdRng :: new ( ) ;
923+ let mut rng = StdRng :: new ( ) . unwrap ( ) ;
910924 bh. iter ( || {
911925 for _ in range ( 0 , RAND_BENCH_N ) {
912926 rng. gen :: < uint > ( ) ;
@@ -917,7 +931,7 @@ mod bench {
917931
918932 #[ bench]
919933 fn rand_shuffle_100 ( bh : & mut BenchHarness ) {
920- let mut rng = XorShiftRng :: new ( ) ;
934+ let mut rng = XorShiftRng :: new ( ) . unwrap ( ) ;
921935 let x : & mut [ uint ] = [ 1 , ..100 ] ;
922936 bh. iter ( || {
923937 rng. shuffle_mut ( x) ;
0 commit comments