diff --git a/core/hash.c b/core/hash.c index d70f7d50..a1288fa4 100644 --- a/core/hash.c +++ b/core/hash.c @@ -17,7 +17,7 @@ uint32_t djb33x_hash(char *key, uint64_t keylen) { // Murmur2 hash Copyright (C) Austin Appleby // adapted from nginx -uint32_t murmur2_hash(char *key, uint64_t keylen) { +static uint32_t murmur2_hash(char *key, uint64_t keylen) { uint32_t h, k; uint8_t *ukey = (uint8_t *) key; @@ -56,6 +56,23 @@ uint32_t murmur2_hash(char *key, uint64_t keylen) { return h; } +static uint32_t random_hash(char *key, uint64_t keylen) { + return (uint32_t) rand(); +} + +/* + not atomic, avoid its use in multithreaded modes +*/ +static uint32_t rr_hash(char *key, uint64_t keylen) { + static uint32_t rr = 0; + uint32_t max_value = uwsgi_str_num(key, keylen); + uint32_t ret = rr; + rr++; + if (rr > max_value) { + rr = 0; + } + return ret; +} struct uwsgi_hash_algo *uwsgi_hash_algo_get(char *name) { struct uwsgi_hash_algo *uha = uwsgi.hash_algos; @@ -90,4 +107,7 @@ void uwsgi_hash_algo_register(char *name, uint32_t (*func)(char *, uint64_t)) { void uwsgi_hash_algo_register_all() { uwsgi_hash_algo_register("djb33x", djb33x_hash); uwsgi_hash_algo_register("murmur2", murmur2_hash); + uwsgi_hash_algo_register("random", random_hash); + uwsgi_hash_algo_register("rand", random_hash); + uwsgi_hash_algo_register("rr", rr_hash); } diff --git a/core/utils.c b/core/utils.c index 9cfc6788..ebffbe13 100644 --- a/core/utils.c +++ b/core/utils.c @@ -3972,7 +3972,6 @@ void uwsgi_uuid(char *buf) { uuid_unparse(uuid_zmq, buf); #else int i,r[11]; - static int srand_called = 0; if (!uwsgi_file_exists("/dev/urandom")) goto fallback; int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) goto fallback; @@ -3984,10 +3983,6 @@ void uwsgi_uuid(char *buf) { close(fd); goto done; fallback: - if (!srand_called) { - srand((unsigned int) getpid()); - srand_called = 1; - } for(i=0;i<11;i++) { r[i] = rand(); } diff --git a/core/uwsgi.c b/core/uwsgi.c index 8a411913..5c49908f 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -1869,6 +1869,12 @@ static struct uwsgi_clock uwsgi_unix_clock = { .microseconds = uwsgi_unix_microseconds, }; +void uwsgi_init_random() { + struct timeval t; + gettimeofday(&t, NULL); + srand((unsigned int) (t.tv_usec * t.tv_sec)); +} + #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int argc, char *argv[], char *envp[]) { @@ -1903,6 +1909,9 @@ int main(int argc, char *argv[], char *envp[]) { //initialize masterpid with a default value masterpid = getpid(); + // initialize random engine + uwsgi_init_random(); + memset(&uwsgi, 0, sizeof(struct uwsgi_server)); uwsgi_proto_hooks_setup(); uwsgi.cwd = uwsgi_get_cwd();