Commit 4e540dde authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Set sockopts on the listen socket and probe the accepted socket (once)

to see which we do not need to set there because they are inherited.

This could potentially save three syscalls per session.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1045 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent cee00cf9
...@@ -42,68 +42,114 @@ static struct acceptor *vca_acceptors[] = { ...@@ -42,68 +42,114 @@ static struct acceptor *vca_acceptors[] = {
static struct acceptor *vca_act; static struct acceptor *vca_act;
static pthread_t vca_thread_acct; static pthread_t vca_thread_acct;
static struct timeval tv_sndtimeo;
static struct timeval tv_rcvtimeo;
static struct linger linger;
static struct sess * static unsigned char need_sndtimeo, need_rcvtimeo, need_linger, need_test;
vca_accept_sess(int fd)
static void
sock_test(int fd)
{ {
struct linger lin;
struct timeval tv;
socklen_t l; socklen_t l;
struct sockaddr addr[2]; /* XXX: IPv6 hack */
struct sess *sp;
int i;
VSL_stats->client_conn++;
l = sizeof addr; l = sizeof lin;
i = accept(fd, addr, &l); AZ(getsockopt(fd, SOL_SOCKET, SO_LINGER, &lin, &l));
if (i < 0) { assert(l == sizeof lin);
VSL(SLT_Debug, fd, "Accept failed errno=%d", errno); if (memcmp(&lin, &linger, l))
/* XXX: stats ? */ need_linger = 1;
return (NULL);
} l = sizeof tv;
sp = SES_New(addr, l); AZ(getsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &l));
XXXAN(sp); assert(l == sizeof tv);
if (memcmp(&tv, &tv_sndtimeo, l))
sp->fd = i; need_sndtimeo = 1;
sp->id = i;
(void)clock_gettime(CLOCK_REALTIME, &sp->t_open); l = sizeof tv;
AZ(getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &l));
return (sp); assert(l == sizeof tv);
if (memcmp(&tv, &tv_rcvtimeo, l))
need_rcvtimeo = 1;
need_test = 0;
printf("socktest: linger=%d sndtimeo=%d rcvtimeo=%d\n",
need_linger, need_sndtimeo, need_rcvtimeo);
} }
void void
VCA_Prep(struct sess *sp) VCA_Prep(struct sess *sp)
{ {
struct linger linger;
TCP_name(sp->sockaddr, sp->sockaddrlen, TCP_name(sp->sockaddr, sp->sockaddrlen,
sp->addr, sizeof sp->addr, sp->port, sizeof sp->port); sp->addr, sizeof sp->addr, sp->port, sizeof sp->port);
VSL(SLT_SessionOpen, sp->fd, "%s %s", sp->addr, sp->port); VSL(SLT_SessionOpen, sp->fd, "%s %s", sp->addr, sp->port);
sp->acct.first = sp->t_open.tv_sec; sp->acct.first = sp->t_open.tv_sec;
#ifdef SO_LINGER /* XXX Linux*/ if (need_test)
linger.l_onoff = 0; sock_test(sp->fd);
linger.l_linger = 0; if (need_linger)
AZ(setsockopt(sp->fd, SOL_SOCKET, SO_LINGER, &linger, sizeof linger)); AZ(setsockopt(sp->fd, SOL_SOCKET, SO_LINGER,
#endif &linger, sizeof linger));
#ifdef SO_SNDTIMEO if (need_sndtimeo)
{ AZ(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
struct timeval tv; &tv_sndtimeo, sizeof tv_sndtimeo));
if (need_rcvtimeo)
AZ(setsockopt(sp->fd, SOL_SOCKET, SO_RCVTIMEO,
&tv_rcvtimeo, sizeof tv_rcvtimeo));
}
tv.tv_sec = params->send_timeout; /*--------------------------------------------------------------------*/
tv.tv_usec = 0;
AZ(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv));
}
#endif
#ifdef SO_RCVTIMEO
{
struct timeval tv;
tv.tv_sec = params->sess_timeout; static void *
tv.tv_usec = 0; vca_acct(void *arg)
AZ(setsockopt(sp->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv)); {
struct sess *sp;
socklen_t l;
struct sockaddr addr[2]; /* XXX: IPv6 hack */
int i;
(void)arg;
need_test = 1;
AZ(setsockopt(heritage.socket, SOL_SOCKET, SO_LINGER,
&linger, sizeof linger));
while (1) {
if (params->send_timeout != tv_sndtimeo.tv_sec) {
need_test = 1;
tv_sndtimeo.tv_sec = params->send_timeout;
AZ(setsockopt(heritage.socket, SOL_SOCKET,
SO_SNDTIMEO, &tv_sndtimeo, sizeof tv_sndtimeo));
}
if (params->sess_timeout != tv_rcvtimeo.tv_sec) {
need_test = 1;
tv_rcvtimeo.tv_sec = params->sess_timeout;
AZ(setsockopt(heritage.socket, SOL_SOCKET,
SO_RCVTIMEO, &tv_rcvtimeo, sizeof tv_rcvtimeo));
}
VSL_stats->client_conn++;
l = sizeof addr;
i = accept(heritage.socket, addr, &l);
if (i < 0) {
VSL(SLT_Debug, heritage.socket,
"Accept failed errno=%d", errno);
/* XXX: stats ? */
continue;
}
sp = SES_New(addr, l);
XXXAN(sp);
sp->fd = i;
sp->id = i;
(void)clock_gettime(CLOCK_REALTIME, &sp->t_open);
http_RecvPrep(sp->http);
sp->step = STP_FIRST;
WRK_QueueSession(sp);
} }
#endif
} }
/*--------------------------------------------------------------------*/
void void
vca_handover(struct sess *sp, int bad) vca_handover(struct sess *sp, int bad)
{ {
...@@ -160,24 +206,6 @@ vca_return_session(struct sess *sp) ...@@ -160,24 +206,6 @@ vca_return_session(struct sess *sp)
vca_act->recycle(sp); vca_act->recycle(sp);
} }
/*--------------------------------------------------------------------*/
static void *
vca_acct(void *arg)
{
struct sess *sp;
(void)arg;
while (1) {
sp = vca_accept_sess(heritage.socket);
if (sp == NULL)
continue;
http_RecvPrep(sp->http);
sp->step = STP_FIRST;
WRK_QueueSession(sp);
}
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment