From b8fdbb4ffff384019a585c3f82fadad7b4d9a328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 28 Oct 2003 23:10:08 +0000 Subject: [PATCH] The driver no longer crashes the system when it couldn't allocate its resources. It's now smarter and only initializes the random generator when the device is opened, not in init_driver(). init_driver() assumed that this driver could not be opened under another team as the kernel (which does not have to be true when it's rescanned). Some more cleanup. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5210 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/drivers/random/driver.c | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/drivers/random/driver.c b/src/add-ons/kernel/drivers/random/driver.c index 0b26d82c10..d5f7992076 100644 --- a/src/add-ons/kernel/drivers/random/driver.c +++ b/src/add-ons/kernel/drivers/random/driver.c @@ -85,7 +85,7 @@ typedef struct _ch_randgen { static ch_randgen *sRandomEnv; -static unsigned int randcount=0; +static uint32 sRandomCount = 0; static sem_id sRandomSem; @@ -310,7 +310,6 @@ new_chrand(const unsigned int inittimes) static void kill_chrand(ch_randgen *randgen) { - memset(randgen, 0, sizeof (ch_randgen)); free(randgen); } @@ -331,8 +330,9 @@ status_t init_driver(void) { TRACE((DRIVER_NAME ": init_driver()\n")); - sRandomEnv = new_chrand(8); + sRandomSem = create_sem(1, "RNG semaphore"); + set_sem_owner(sRandomSem, B_SYSTEM_TEAM); return B_OK; } @@ -376,7 +376,15 @@ static status_t random_open(const char *name, uint32 flags, void **cookie) { TRACE((DRIVER_NAME ": open(\"%s\")\n", name)); - return B_OK; + acquire_sem(sRandomSem); + + sRandomEnv = new_chrand(8); + // the random generator is only initialized on demand, but + // remains valid as long as the driver is loaded + + release_sem(sRandomSem); + + return sRandomEnv != NULL ? B_OK : B_NO_MEMORY; } @@ -388,18 +396,18 @@ random_read(void *cookie, off_t position, void *_buffer, size_t *_numBytes) uint32 i, j; acquire_sem(sRandomSem); - randcount += *_numBytes; + sRandomCount += *_numBytes; /* Reseed if we have or are gonna use up > 1/16th the entropy around */ - if (randcount >= NK/8) { - randcount = 0; + if (sRandomCount >= NK/8) { + sRandomCount = 0; reseed(sRandomEnv, 1); } - /* Yes, i know this is not the way we should do it. What we really should do is + /* ToDo: Yes, i know this is not the way we should do it. What we really should do is * take the md5 or sha1 hash of the state of the pool, and return that. Someday. */ - for (i = 0; i < (*_numBytes)/4; i++) + for (i = 0; i < (*_numBytes) / 4; i++) buffer[i] = chrand32(sRandomEnv); for (j = 0; j < (*_numBytes) % 4; j++) buffer8[(i*4) + j] = chrand8(sRandomEnv);