r780 - in trunk/varnish-cache: . bin/varnishd
des at projects.linpro.no
des at projects.linpro.no
Wed Aug 9 16:49:49 CEST 2006
Author: des
Date: 2006-08-09 16:49:49 +0200 (Wed, 09 Aug 2006)
New Revision: 780
Modified:
trunk/varnish-cache/bin/varnishd/cache_acceptor.c
trunk/varnish-cache/configure.ac
Log:
Add an epoll()-based acceptor for Linux 2.6. Simple empirical tests indicate
that epoll() performs significantly better than poll() (less CPU usage).
Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor.c 2006-08-09 12:38:11 UTC (rev 779)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor.c 2006-08-09 14:49:49 UTC (rev 780)
@@ -7,10 +7,13 @@
*/
#undef ACCEPTOR_USE_KQUEUE
+#undef ACCEPTOR_USE_EPOLL
#undef ACCEPTOR_USE_POLL
#if defined(HAVE_KQUEUE)
#define ACCEPTOR_USE_KQUEUE 1
+#elif defined(HAVE_EPOLL_CTL)
+#define ACCEPTOR_USE_EPOLL 1
#elif defined(HAVE_POLL)
#define ACCEPTOR_USE_POLL 1
#else
@@ -260,6 +263,125 @@
#endif /* ACCEPTOR_USE_POLL */
/*====================================================================*/
+#ifdef ACCEPTOR_USE_EPOLL
+
+#include <sys/epoll.h>
+
+static int epfd = -1;
+static int pipes[2];
+
+static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead);
+
+static void
+vca_add(int fd, void *data)
+{
+ struct epoll_event ev = { EPOLLIN | EPOLLPRI, { data } };
+ AZ(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev));
+}
+
+static void
+vca_del(int fd)
+{
+ AZ(epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL));
+}
+
+static void
+vca_rcvhdev(struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ clock_gettime(CLOCK_MONOTONIC, &sp->t_idle);
+ TAILQ_INSERT_TAIL(&sesshead, sp, list);
+ vca_add(sp->fd, sp);
+}
+
+static void
+accept_f(int fd)
+{
+ struct sess *sp;
+
+ sp = vca_accept_sess(fd);
+ if (sp == NULL)
+ return;
+ http_RecvPrep(sp->http);
+ vca_rcvhdev(sp);
+}
+
+static void *
+vca_main(void *arg)
+{
+ struct epoll_event ev;
+ struct timespec t;
+ struct sess *sp, *sp2;
+ int i;
+
+ (void)arg;
+
+ epfd = epoll_create(16);
+ assert(epfd >= 0);
+
+ AZ(pipe(pipes));
+ vca_add(pipes[0], pipes);
+
+ if (heritage.socket >= 0)
+ vca_add(heritage.socket, accept_f);
+
+ while (1) {
+ if (epoll_wait(epfd, &ev, 1, 5000) > 0) {
+ if (ev.data.ptr == pipes) {
+ i = read(pipes[0], &sp, sizeof sp);
+ assert(i == sizeof sp);
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (http_RecvPrepAgain(sp->http))
+ vca_handover(sp, 0);
+ else
+ vca_rcvhdev(sp);
+ } else if (ev.data.ptr == accept_f) {
+ accept_f(heritage.socket);
+ } else {
+ CAST_OBJ_NOTNULL(sp, ev.data.ptr, SESS_MAGIC);
+ i = http_RecvSome(sp->fd, sp->http);
+ if (i != -1) {
+ TAILQ_REMOVE(&sesshead, sp, list);
+ vca_del(sp->fd);
+ vca_handover(sp, i);
+ }
+ }
+ }
+ /* check for timeouts */
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ TAILQ_FOREACH_SAFE(sp, &sesshead, list, sp2) {
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (sp->t_idle.tv_sec + 5 < t.tv_sec) {
+ TAILQ_REMOVE(&sesshead, sp, list);
+ vca_del(sp->fd);
+ vca_close_session(sp, "timeout");
+ vca_return_session(sp);
+ continue;
+ }
+ }
+ }
+
+ INCOMPL();
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+vca_return_session(struct sess *sp)
+{
+
+ if (sp->fd < 0) {
+ SES_Delete(sp);
+ return;
+ }
+ (void)clock_gettime(CLOCK_REALTIME, &sp->t_open);
+ VSL(SLT_SessionReuse, sp->fd, "%s %s", sp->addr, sp->port);
+ assert(sizeof sp == write(pipes[1], &sp, sizeof sp));
+}
+
+#endif /* ACCEPTOR_USE_EPOLL */
+/*====================================================================*/
#ifdef ACCEPTOR_USE_KQUEUE
#include <sys/event.h>
Modified: trunk/varnish-cache/configure.ac
===================================================================
--- trunk/varnish-cache/configure.ac 2006-08-09 12:38:11 UTC (rev 779)
+++ trunk/varnish-cache/configure.ac 2006-08-09 14:49:49 UTC (rev 780)
@@ -90,6 +90,7 @@
# Check which mechanism to use for the acceptor
AC_CHECK_FUNCS([kqueue])
+AC_CHECK_FUNCS([epoll_ctl])
AC_CHECK_FUNCS([poll])
AC_CONFIG_FILES([
More information about the varnish-commit
mailing list