[master] 5d5e873 Prepare the acceptor code to become multithreaded by moving the pacing under a dedicated lock.
Poul-Henning Kamp
phk at varnish-cache.org
Sat Sep 17 19:36:52 CEST 2011
commit 5d5e8732ad589a0b417e8f78585e4c252ea07c15
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Sat Sep 17 17:36:06 2011 +0000
Prepare the acceptor code to become multithreaded by moving the
pacing under a dedicated lock.
diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index 65d1886..6c0c525 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -299,8 +299,13 @@ struct worker {
void *nhashpriv;
struct dstat stats;
+ /* Pool stuff */
double lastused;
+ /* Accept stuff */
+ struct sockaddr_storage acceptaddr;
+ int acceptsock;
+
struct wrw wrw;
pthread_cond_t cond;
@@ -634,6 +639,7 @@ struct vbc {
void VCA_Prep(struct sess *sp);
void VCA_Init(void);
void VCA_Shutdown(void);
+int VCA_Accept(int sock, socklen_t *slp, struct sockaddr_storage *sap);
extern pthread_t VCA_thread;
/* cache_backend.c */
diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c
index 23752f3..0022037 100644
--- a/bin/varnishd/cache_acceptor.c
+++ b/bin/varnishd/cache_acceptor.c
@@ -153,6 +153,85 @@ VCA_Prep(struct sess *sp)
#endif
}
+/*--------------------------------------------------------------------
+ * If accept(2)'ing fails, we pace ourselves to relive any resource
+ * shortage if possible.
+ */
+
+static double vca_pace = 0.0;
+static struct lock pace_mtx;
+
+static void
+vca_pace_check(void)
+{
+ double p;
+
+ if (vca_pace == 0.0)
+ return;
+ Lck_Lock(&pace_mtx);
+ p = vca_pace;
+ Lck_Unlock(&pace_mtx);
+ if (p > 0.0)
+ TIM_sleep(p);
+}
+
+static void
+vca_pace_bad(void)
+{
+ Lck_Lock(&pace_mtx);
+ vca_pace += params->acceptor_sleep_incr;
+ if (vca_pace > params->acceptor_sleep_max)
+ vca_pace = params->acceptor_sleep_max;
+ Lck_Unlock(&pace_mtx);
+}
+
+static void
+vca_pace_good(void)
+{
+
+ if (vca_pace == 0.0)
+ return;
+ Lck_Lock(&pace_mtx);
+ vca_pace *= params->acceptor_sleep_decay;
+ if (vca_pace < params->acceptor_sleep_incr)
+ vca_pace = 0.0;
+ Lck_Unlock(&pace_mtx);
+}
+
+/*--------------------------------------------------------------------
+ * Accept on a listen socket, and handle error returns.
+ */
+
+int
+VCA_Accept(int sock, socklen_t *slp, struct sockaddr_storage *sap)
+{
+ int i;
+
+ vca_pace_check();
+
+ *slp = sizeof *sap;
+ i = accept(sock, (void*)sap, slp);
+
+ if (i < 0) {
+ VSC_C_main->accept_fail++;
+ switch (errno) {
+ case EAGAIN:
+ case ECONNABORTED:
+ break;
+ case EMFILE:
+ VSL(SLT_Debug, sock, "Too many open files");
+ vca_pace_bad();
+ break;
+ default:
+ VSL(SLT_Debug, sock, "Accept failed: %s",
+ strerror(errno));
+ vca_pace_bad();
+ break;
+ }
+ }
+ return (i);
+}
+
/*--------------------------------------------------------------------*/
static void *
@@ -172,7 +251,7 @@ vca_acct(void *arg)
struct pollfd *pfd;
struct listen_sock *ls;
unsigned u;
- double t0, now, pace;
+ double t0, now;
THR_SetName("cache-acceptor");
(void)arg;
@@ -192,7 +271,6 @@ vca_acct(void *arg)
}
need_test = 1;
- pace = 0;
t0 = TIM_real();
while (1) {
#ifdef SO_SNDTIMEO_WORKS
@@ -223,13 +301,6 @@ vca_acct(void *arg)
}
}
#endif
- /* Bound the pacing delay by parameter */
- if (pace > params->acceptor_sleep_max)
- pace = params->acceptor_sleep_max;
- if (pace < params->acceptor_sleep_incr)
- pace = 0.0;
- if (pace > 0.0)
- TIM_sleep(pace);
i = poll(pfd, heritage.nsocks, 1000);
now = TIM_real();
VSC_C_main->uptime = (uint64_t)(now - t0);
@@ -242,33 +313,14 @@ vca_acct(void *arg)
VSC_C_main->client_conn++;
l = sizeof addr_s;
addr = (void*)&addr_s;
- i = accept(ls->sock, addr, &l);
- if (i < 0) {
- VSC_C_main->accept_fail++;
- switch (errno) {
- case EAGAIN:
- case ECONNABORTED:
- break;
- case EMFILE:
- VSL(SLT_Debug, ls->sock,
- "Too many open files "
- "when accept(2)ing. Sleeping.");
- pace += params->acceptor_sleep_incr;
- break;
- default:
- VSL(SLT_Debug, ls->sock,
- "Accept failed: %s",
- strerror(errno));
- pace += params->acceptor_sleep_incr;
- break;
- }
+ i = VCA_Accept(ls->sock, &l, &addr_s);
+ if (i < 0)
continue;
- }
sp = SES_New();
if (sp == NULL) {
AZ(close(i));
VSC_C_main->client_drop++;
- pace += params->acceptor_sleep_incr;
+ vca_pace_bad();
continue;
}
sp->fd = i;
@@ -283,9 +335,9 @@ vca_acct(void *arg)
sp->step = STP_FIRST;
if (Pool_QueueSession(sp)) {
VSC_C_main->client_drop++;
- pace += params->acceptor_sleep_incr;
+ vca_pace_bad();
} else {
- pace *= params->acceptor_sleep_decay;
+ vca_pace_good();
}
}
}
@@ -341,6 +393,7 @@ VCA_Init(void)
{
CLI_AddFuncs(vca_cmds);
+ Lck_New(&pace_mtx, lck_vcapace);
}
void
diff --git a/bin/varnishd/locks.h b/bin/varnishd/locks.h
index e0a6bd5..6cbf91f 100644
--- a/bin/varnishd/locks.h
+++ b/bin/varnishd/locks.h
@@ -49,4 +49,5 @@ LOCK(ban)
LOCK(vbp)
LOCK(vbe)
LOCK(backend)
+LOCK(vcapace)
/*lint -restore */
More information about the varnish-commit
mailing list