[master] 217d927 serialize access to heritage.socks in the child
Nils Goroll
nils.goroll at uplex.de
Mon Nov 6 17:05:07 UTC 2017
commit 217d9277fa4b6fc44a9d4c9b8736a937aa4029ba
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Mon Nov 6 17:51:23 2017 +0100
serialize access to heritage.socks in the child
I did consider avoiding locks, but as long as the close() in VCA_Shutdown()
happens concurrent to vca_acct(), the file descriptor could become invalid
at any time, so even if we'd not hit the sock > 0 assertion, other errors
could occur / assertions be hit.
We could also move the close to vca_acct() and just signal it to finish off,
but this would delay the close by the sleep(1), unless we further complicated
things with a condvar.
Avoiding the lock would require us to make any operation on a socket fd
ignore errors, which is totally against our policy to assert on everything.
(see vca_tcp_opt_set() for example).
So, for the time being, I think simple serialization using a pthread mutex
is the safest and simplest solution. A varnish lock would be overkill, as
this lock is really only relevant during VCA_Shutdown.
IMHO, the primary risk involved here is delayed VCA_Shutdown() due to
vca_acct() hanging in a syscall. Famous Last Words - sigh.
Fixes #2482
diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index f552b85..523bba9 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -53,6 +53,7 @@ static pthread_t VCA_thread;
static double vca_pace = 0.0;
static struct lock pace_mtx;
static unsigned pool_accepting;
+static pthread_mutex_t shut_mtx = PTHREAD_MUTEX_INITIALIZER;
struct wrk_accept {
unsigned magic;
@@ -529,9 +530,12 @@ vca_acct(void *arg)
(void)vca_tcp_opt_init();
+ AZ(pthread_mutex_lock(&shut_mtx));
VTAILQ_FOREACH(ls, &heritage.socks, list) {
CHECK_OBJ_NOTNULL(ls->transport, TRANSPORT_MAGIC);
- assert (ls->sock > 0); // We know where stdin is
+ if (ls->sock == -2)
+ continue; // VCA_Shutdown
+ assert (ls->sock > 0); // We know where stdin is
if (cache_param->tcp_fastopen) {
int i;
i = VTCP_fastopen(ls->sock, cache_param->listen_depth);
@@ -551,6 +555,7 @@ vca_acct(void *arg)
ls->sock, i, strerror(errno));
}
}
+ AZ(pthread_mutex_unlock(&shut_mtx));
need_test = 1;
pool_accepting = 1;
@@ -559,12 +564,14 @@ vca_acct(void *arg)
while (1) {
(void)sleep(1);
if (vca_tcp_opt_init()) {
+ AZ(pthread_mutex_lock(&shut_mtx));
VTAILQ_FOREACH(ls, &heritage.socks, list) {
if (ls->sock == -2)
- continue; // raced VCA_Shutdown
+ continue; // VCA_Shutdown
assert (ls->sock > 0);
vca_tcp_opt_set(ls->sock, 1);
}
+ AZ(pthread_mutex_unlock(&shut_mtx));
}
now = VTIM_real();
VSC_C_main->uptime = (uint64_t)(now - t0);
@@ -606,10 +613,12 @@ ccf_listen_address(struct cli *cli, const char * const *av, void *priv)
while (!pool_accepting)
VTIM_sleep(.1);
+ AZ(pthread_mutex_lock(&shut_mtx));
VTAILQ_FOREACH(ls, &heritage.socks, list) {
VTCP_myname(ls->sock, h, sizeof h, p, sizeof p);
VCLI_Out(cli, "%s %s\n", h, p);
}
+ AZ(pthread_mutex_unlock(&shut_mtx));
}
/*--------------------------------------------------------------------*/
@@ -634,11 +643,13 @@ VCA_Shutdown(void)
struct listen_sock *ls;
int i;
+ AZ(pthread_mutex_lock(&shut_mtx));
VTAILQ_FOREACH(ls, &heritage.socks, list) {
i = ls->sock;
ls->sock = -2;
(void)close(i);
}
+ AZ(pthread_mutex_unlock(&shut_mtx));
}
/*--------------------------------------------------------------------
More information about the varnish-commit
mailing list