Index: trunk/psLib/src/math/psRandom.c
===================================================================
--- trunk/psLib/src/math/psRandom.c	(revision 20547)
+++ trunk/psLib/src/math/psRandom.c	(revision 23259)
@@ -29,4 +29,5 @@
 #include <inttypes.h>
 
+#include "psAbort.h"
 #include "psMemory.h"
 #include "psRandom.h"
@@ -38,19 +39,24 @@
 
 
+unsigned long seed = 0;                 // Seed for RNG
+
+
 psU64 p_psRandomGetSystemSeed(bool log)
 {
-    FILE*  fd;
-    psU64  seedVal = 0;
-    time_t timeVal;
+    psU64 seedVal = 0;                  // Seed value to return
 
-    fd = fopen("/dev/urandom","r");
-    if(fd == NULL) {
-        // Read system clock to get seed
-        seedVal = (psU64)time(&timeVal);
-    } else {
-        // Read urandom to get seed
-        if (fread(&seedVal, sizeof(psU64),1,fd)) {;} // ignore return value
-        // Close file
-        fclose(fd);
+    // Since zero is a special value in our context, don't allow the final value chosen to be zero
+    while (seedVal == 0) {
+        FILE *fd = fopen("/dev/urandom", "r");
+        if (fd) {
+            // Read urandom to get seed
+            if (fread(&seedVal, sizeof(psU64), 1, fd)) {;} // ignore return value
+            // Close file
+            fclose(fd);
+        } else {
+            // Read system clock to get seed
+            time_t timeVal;                 // Time value
+            seedVal = (psU64)time(&timeVal);
+        }
     }
 
@@ -63,100 +69,94 @@
 }
 
-psRandom *psRandomAlloc(psRandomType type,
-                        unsigned long seed)
+psU64 psRandomSeed(psU64 value)
 {
-    gsl_rng   *r      = NULL;
-    psRandom  *myRNG  = NULL;
+    while (value == 0) {
+        value = p_psRandomGetSystemSeed(true);
+    }
+    seed = value;
+    return seed;
+}
 
+// Destructor for psRandom
+static void randomFree(psRandom *rng)
+{
+    if (rng->gsl) {
+        gsl_rng_free(rng->gsl);
+    }
+    return;
+}
+
+// Constructor for psRandom
+static psRandom *randomAlloc(psRandomType type)
+{
+    psRandom *rng = psAlloc(sizeof(psRandom)); // Random number generator to return
+    psMemSetDeallocator(rng, (psFreeFunc)randomFree);
+
+    rng->type = type;
+
+    const gsl_rng_type *gslType;        // Type of RNG according to GSL
     switch (type) {
-    case PS_RANDOM_TAUS:
-        myRNG = (psRandom*)psAlloc(sizeof(psRandom));
-        r = gsl_rng_alloc(gsl_rng_taus);
-        myRNG->gsl = r;
-        if(seed == 0) {
-            gsl_rng_set(myRNG->gsl, p_psRandomGetSystemSeed(true));
-        } else {
-            gsl_rng_set(myRNG->gsl, seed);
-        }
-        myRNG->type = type;
+      case PS_RANDOM_TAUS:
+        gslType = gsl_rng_taus;
         break;
-
-    default:
-        psError(PS_ERR_UNEXPECTED_NULL, true, _("Unknown Random Number Generator Type"));
+      default:
+        psAbort("Unknown Random Number Generator Type: %x", type);
         break;
     }
 
-    return(myRNG);
+    rng->gsl = gsl_rng_alloc(gslType);
+    return rng;
 }
 
-void psRandomReset(psRandom *rand,
-                   unsigned long seed)
+psRandom *psRandomAlloc(psRandomType type)
 {
-    // Check null psRandom
-    if(rand==NULL) {
-        psError(PS_ERR_UNEXPECTED_NULL,
-                true,
-                _("Random variable is NULL."));
-    } else {
-        // Check seed value to see if system seed should be used
-        if(seed == 0) {
-            gsl_rng_set(rand->gsl,p_psRandomGetSystemSeed(true));
-        } else {
-            gsl_rng_set(rand->gsl, seed);
-        }
+    psRandom *rng = randomAlloc(type);
+    psRandomReset(rng);
+
+    return rng;
+}
+
+psRandom *psRandomAllocSpecific(psRandomType type, psU64 specificSeed)
+{
+    psRandom *rng = randomAlloc(type);
+    if (specificSeed == 0) {
+        specificSeed = p_psRandomGetSystemSeed(true);
     }
+    gsl_rng_set(rng->gsl, specificSeed);
+    return rng;
+}
+
+bool psRandomReset(psRandom *rand)
+{
+    PS_ASSERT_RANDOM_NON_NULL(rand, false);
+    if (seed == 0) {
+        seed = p_psRandomGetSystemSeed(true);
+    }
+    gsl_rng_set(rand->gsl, seed);
+    return true;
 }
 
 double psRandomUniform(const psRandom *r)
 {
-    // Check null psRandom variable
-    if(r == NULL) {
-        psError(PS_ERR_UNEXPECTED_NULL,
-                true,
-                _("Random variable is NULL."));
-        return(0);
-    } else {
-        return(gsl_rng_uniform(r->gsl));
-    }
+    PS_ASSERT_RANDOM_NON_NULL(r, NAN);
+    return gsl_rng_uniform(r->gsl);
 }
 
 double psRandomGaussian(const psRandom *r)
 {
-    // Check null psRandom variable
-    if(r == NULL) {
-        psError(PS_ERR_UNEXPECTED_NULL,
-                true,
-                _("Random variable is NULL."));
-        return(0);
-    } else {
-        // XXX: What should sigma be?
-        return(gsl_ran_gaussian(r->gsl, 1.0));
-    }
+    PS_ASSERT_RANDOM_NON_NULL(r, NAN);
+    return gsl_ran_gaussian(r->gsl, 1.0);
 }
 
 double p_psRandomGaussian(const psRandom *r, double sigma)
 {
-    // Check null psRandom variable
-    if(r == NULL) {
-        psError(PS_ERR_UNEXPECTED_NULL,
-                true,
-                _("Random variable is NULL."));
-        return(0);
-    } else {
-        return(gsl_ran_gaussian(r->gsl, sigma));
-    }
+    PS_ASSERT_RANDOM_NON_NULL(r, NAN);
+    return gsl_ran_gaussian(r->gsl, sigma);
 }
 
 double psRandomPoisson(const psRandom *r, double mean)
 {
-    // Check null psRandom variable
-    if(r == NULL) {
-        psError(PS_ERR_UNEXPECTED_NULL,
-                true,
-                _("Random variable is NULL."));
-        return(0);
-    } else {
-        return((psF64) gsl_ran_poisson(r->gsl, mean));
-    }
+    PS_ASSERT_RANDOM_NON_NULL(r, NAN);
+    return gsl_ran_poisson(r->gsl, mean);
 }
 
