[master] 84b14ba Wrap the testable VRND in program supplied locking, because it is not thread-safe.
Poul-Henning Kamp
phk at FreeBSD.org
Wed Jun 6 13:44:16 UTC 2018
commit 84b14baa085d6d20051bb8af04af09e3c466aa76
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Jun 6 13:42:51 2018 +0000
Wrap the testable VRND in program supplied locking, because it
is not thread-safe.
Switch from random(3) to testable VRND for same reason.
diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c
index acc1104..b1f993d 100644
--- a/bin/varnishd/cache/cache_esi_fetch.c
+++ b/bin/varnishd/cache/cache_esi_fetch.c
@@ -39,6 +39,8 @@
#include "cache_esi.h"
+#include "vrnd.h"
+
/*---------------------------------------------------------------------
*/
@@ -198,7 +200,7 @@ vfp_esi_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
*lp = 0;
l = vef->ibuf_sz - (vef->ibuf_i - vef->ibuf);
if (DO_DEBUG(DBG_ESI_CHOP)) {
- d = (random() & 3) + 1;
+ d = (VRND_RandomTestable() & 3) + 1;
if (d < l)
l = d;
}
@@ -259,7 +261,7 @@ vfp_esi_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp)
AN(p);
AN(lp);
if (DO_DEBUG(DBG_ESI_CHOP)) {
- d = (random() & 3) + 1;
+ d = (VRND_RandomTestable() & 3) + 1;
if (d < *lp)
*lp = d;
}
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 8b7a63e..4683a3f 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -52,6 +52,19 @@
volatile struct params *cache_param;
+static pthread_mutex_t cache_vrnd_mtx;
+
+static void
+cache_vrnd_lock(void)
+{
+ AZ(pthread_mutex_lock(&cache_vrnd_mtx));
+}
+
+static void
+cache_vrnd_unlock(void)
+{
+ AZ(pthread_mutex_unlock(&cache_vrnd_mtx));
+}
/*--------------------------------------------------------------------
* Per thread storage for the session currently being processed by
@@ -339,6 +352,10 @@ child_main(int sigmagic, size_t altstksz)
THR_SetName("cache-main");
+ AZ(pthread_mutex_init(&cache_vrnd_mtx, NULL));
+ VRND_Lock = cache_vrnd_lock;
+ VRND_Unlock = cache_vrnd_unlock;
+
VSM_Init(); /* First, LCK needs it. */
LCK_Init(); /* Second, locking */
diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c
index 69b2d3d..2765665 100644
--- a/bin/varnishtest/vtc.c
+++ b/bin/varnishtest/vtc.c
@@ -40,6 +40,7 @@
#include "vtc.h"
#include "vav.h"
+#include "vrnd.h"
#include "vtim.h"
#define MAX_TOKENS 200
@@ -50,6 +51,20 @@ pthread_t vtc_thread;
int ign_unknown_macro = 0;
static struct vtclog *vltop;
+static pthread_mutex_t vtc_vrnd_mtx;
+
+static void
+vtc_vrnd_lock(void)
+{
+ AZ(pthread_mutex_lock(&vtc_vrnd_mtx));
+}
+
+static void
+vtc_vrnd_unlock(void)
+{
+ AZ(pthread_mutex_unlock(&vtc_vrnd_mtx));
+}
+
/**********************************************************************
* Macro facility
*/
@@ -465,6 +480,11 @@ exec_file(const char *fn, const char *script, const char *tmpdir,
(void)signal(SIGPIPE, SIG_IGN);
+ AZ(pthread_mutex_init(&vtc_vrnd_mtx, NULL));
+ VRND_Lock = vtc_vrnd_lock;
+ VRND_Unlock = vtc_vrnd_unlock;
+ VRND_SeedAll();
+
tfn = fn;
vtc_loginit(logbuf, loglen);
vltop = vtc_logopen("top");
diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c
index 54b2a20..741c5f1 100644
--- a/bin/varnishtest/vtc_http.c
+++ b/bin/varnishtest/vtc_http.c
@@ -45,6 +45,7 @@
#include "vfil.h"
#include "vgz.h"
#include "vnum.h"
+#include "vrnd.h"
#include "vtcp.h"
#include "hpack.h"
@@ -189,7 +190,7 @@ synth_body(const char *len, int rnd)
k = '!';
l = k;
} else if (rnd) {
- b[j] = (random() % 95) + ' ';
+ b[j] = (VRND_RandomTestable() % 95) + ' ';
} else {
b[j] = (char)l;
if (++l == '~')
@@ -1970,7 +1971,7 @@ xxx(void)
*ibuf = 0;
for (j = 0; j < 7; j++) {
snprintf(strchr(ibuf, 0), 5, "%x",
- (unsigned)random() & 0xffff);
+ (unsigned)VRND_RandomTestable() & 0xffff);
vz.next_in = TRUST_ME(ibuf);
vz.avail_in = strlen(ibuf);
vz.next_out = TRUST_ME(obuf);
diff --git a/include/vrnd.h b/include/vrnd.h
index 6a89762..a828af8 100644
--- a/include/vrnd.h
+++ b/include/vrnd.h
@@ -28,7 +28,13 @@
* Random functions
*/
+typedef void vrnd_lock_f(void);
+
+extern vrnd_lock_f *VRND_Lock;
+extern vrnd_lock_f *VRND_Unlock;
+
int VRND_RandomCrypto(void *, size_t);
+
long VRND_RandomTestable(void);
double VRND_RandomTestableDouble(void);
void VRND_SeedTestable(unsigned int);
diff --git a/lib/libvarnish/binary_heap.c b/lib/libvarnish/binary_heap.c
index b49f9d6..fee40c9 100644
--- a/lib/libvarnish/binary_heap.c
+++ b/lib/libvarnish/binary_heap.c
@@ -519,6 +519,11 @@ chk2(struct binheap *bh)
}
#endif
+static void
+vrnd_lock(void)
+{
+}
+
int
main(void)
{
@@ -528,6 +533,9 @@ main(void)
VRND_SeedAll();
VRND_SeedTestable(1);
+ VRND_Lock = vrnd_lock;
+ VRND_Unlock = vrnd_lock;
+
bh = binheap_new(NULL, cmp, update);
for (n = 2; n; n += n) {
child(bh, n - 1, &u, &v);
diff --git a/lib/libvarnish/vrnd.c b/lib/libvarnish/vrnd.c
index 3dc8b18..13557b0 100644
--- a/lib/libvarnish/vrnd.c
+++ b/lib/libvarnish/vrnd.c
@@ -45,6 +45,10 @@
#include "vas.h"
#include "vrnd.h"
+
+vrnd_lock_f *VRND_Lock;
+vrnd_lock_f *VRND_Unlock;
+
/**********************************************************************
* Stripped down random(3) implementation from FreeBSD, to provide
* predicatable "random" numbers of testing purposes.
@@ -96,23 +100,8 @@ good_rand(uint32_t ctx)
return (x - 1);
}
-void
-VRND_SeedTestable(unsigned int x)
-{
- int i, lim;
-
- state[0] = (uint32_t)x;
- for (i = 1; i < rand_deg; i++)
- state[i] = good_rand(state[i - 1]);
- fptr = &state[rand_sep];
- rptr = &state[0];
- lim = 10 * rand_deg;
- for (i = 0; i < lim; i++)
- (void)VRND_RandomTestable();
-}
-
-long
-VRND_RandomTestable(void)
+static long
+vrnd_RandomTestable(void)
{
uint32_t i;
uint32_t *f, *r;
@@ -135,6 +124,35 @@ VRND_RandomTestable(void)
return ((long)i);
}
+
+void
+VRND_SeedTestable(unsigned int x)
+{
+ int i, lim;
+
+ state[0] = (uint32_t)x;
+ for (i = 1; i < rand_deg; i++)
+ state[i] = good_rand(state[i - 1]);
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ lim = 10 * rand_deg;
+ for (i = 0; i < lim; i++)
+ (void)vrnd_RandomTestable();
+}
+
+long
+VRND_RandomTestable(void)
+{
+ long l;
+
+ AN(VRND_Lock);
+ VRND_Lock();
+ l = vrnd_RandomTestable();
+ AN(VRND_Unlock);
+ VRND_Unlock();
+ return (l);
+}
+
double
VRND_RandomTestableDouble(void)
{
More information about the varnish-commit
mailing list