From e86af4b7e56ed5b7050cb4f41ae534f54748598c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 9 Apr 2012 10:46:32 -0400 Subject: Change evutil_weakrand_() to avoid platform random() This change allows us to avoid perturbing the platform's random(), and to avoid hitting locks on random() in the platform's libc. evutil_weakrand_() is, well, weak, so we choose here an algorithm that favors speed over a number of other possibly desirable properties. We're using a linear congruential generator, and taking our parameters from those shared by the OpenBSD random() implementation, and Glibc's fastest random() implementation. The low bits of a LCG of modulus 2^32 are (notoriously) less random than the higher bits. So to generate a random value in a range, using the % operator is no good; we ought to divide. We add an evutil_weakrand_range_() function to do that. This code also changes the interface of evutil_weakrand_() so that it now manipulates an explicit seed, rather than having the seed in a static variable. This change enables us to use existing locks to achieve thread-safety, rather than having to rely on an additional lock. (Patch by Nicholas Marriott; commit message by Nick Mathewson.) --- select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'select.c') diff --git a/select.c b/select.c index e1d4987c..f9a0c206 100644 --- a/select.c +++ b/select.c @@ -186,7 +186,7 @@ select_dispatch(struct event_base *base, struct timeval *tv) event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); - i = random() % nfds; + i = evutil_weakrand_range_(&base->weakrand_seed, nfds); for (j = 0; j < nfds; ++j) { if (++i >= nfds) i = 0; -- cgit v1.2.1