r6 - trunk
des at projects.linpro.no
des at projects.linpro.no
Fri Feb 10 17:05:32 CET 2006
Author: des
Date: 2006-02-10 17:05:32 +0100 (Fri, 10 Feb 2006)
New Revision: 6
Added:
trunk/log.h
trunk/system-common.c
trunk/system-linux-gnu.c
trunk/system.h
Modified:
trunk/Makefile.am
trunk/configure.ac
trunk/connection.c
trunk/connection.h
trunk/listener.c
trunk/listener.h
trunk/log.c
trunk/request.c
trunk/request.h
trunk/varnish.c
trunk/varnish.h
Log:
Disentangle listener and connection, allowing the struct definitions to move
out of the headers into the code, reducing header dependencies.
Add code to detect the number of CPU cores on Linux.
Fork as many listening child processes as we have CPU cores.
Add timestamps and the current PID to log messages.
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/Makefile.am 2006-02-10 16:05:32 UTC (rev 6)
@@ -7,4 +7,6 @@
listener.c \
log.c \
request.c \
+ system-common.c \
+ system- at target_os@.c \
varnish.c
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/configure.ac 2006-02-10 16:05:32 UTC (rev 6)
@@ -35,6 +35,8 @@
# Checks for header files.
AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
AC_CHECK_HEADERS([sys/socket.h])
AC_CHECK_HEADERS([netinet/in.h])
AC_CHECK_HEADERS([stddef.h])
Modified: trunk/connection.c
===================================================================
--- trunk/connection.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/connection.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -11,8 +11,66 @@
#include <unistd.h>
#include "varnish.h"
+#include "log.h"
#include "connection.h"
+struct connection {
+ int sd;
+ struct sockaddr_storage addr;
+};
+
+/*
+ * Accepts a connection from the provided listening descriptor. Does not
+ * loop to handle EINTR or other similar conditions.
+ */
+connection_t *
+connection_accept(int ld)
+{
+ connection_t *c;
+ socklen_t len;
+
+ if ((c = calloc(1, sizeof *c)) == NULL)
+ return (NULL);
+
+ len = sizeof c->addr;
+ if ((c->sd = accept(ld, (struct sockaddr *)&c->addr, &len)) == -1) {
+ free(c);
+ return (NULL);
+ }
+ switch (c->addr.ss_family) {
+#if defined(AF_INET6)
+ case AF_INET6: {
+ struct sockaddr_in6 *addr =
+ (struct sockaddr_in6 *)&c->addr;
+ uint16_t *ip = (uint16_t *)&addr->sin6_addr;
+
+ log_info("%s(): [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%u",
+ __func__,
+ ntohs(ip[0]), ntohs(ip[1]),
+ ntohs(ip[2]), ntohs(ip[3]),
+ ntohs(ip[4]), ntohs(ip[5]),
+ ntohs(ip[6]), ntohs(ip[7]),
+ ntohs(addr->sin6_port));
+ break;
+ }
+#endif
+ case AF_INET: {
+ struct sockaddr_in *addr =
+ (struct sockaddr_in *)&c->addr;
+ uint8_t *ip = (uint8_t *)&addr->sin_addr;
+
+ log_info("%s(): %u.%u.%u.%u:%u",
+ __func__,
+ ip[0], ip[1], ip[2], ip[3],
+ ntohs(addr->sin_port));
+ break;
+ }
+ default:
+ LOG_UNREACHABLE();
+ }
+ return (c);
+}
+
void
connection_destroy(struct connection *c)
{
Modified: trunk/connection.h
===================================================================
--- trunk/connection.h 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/connection.h 2006-02-10 16:05:32 UTC (rev 6)
@@ -5,9 +5,9 @@
#ifndef CONNECTION_H_INCLUDED
#define CONNECTION_H_INCLUDED
-struct connection {
- int sd;
- struct sockaddr_storage addr;
-};
+typedef struct connection connection_t;
+connection_t *connection_accept(int ld);
+void connection_destroy(connection_t *c);
+
#endif
Modified: trunk/listener.c
===================================================================
--- trunk/listener.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/listener.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -13,9 +13,15 @@
#include <unistd.h>
#include "varnish.h"
-#include "listener.h"
#include "connection.h"
+#include "listener.h"
+#include "log.h"
+struct listener {
+ int sd;
+ struct sockaddr_storage addr;
+};
+
/*
* Create a socket that listens on the specified port. We use an IPv6 TCP
* socket and clear the IPV6_V6ONLY option to accept IPv4 connections on
@@ -83,50 +89,14 @@
free(l);
}
-struct connection *
+connection_t *
listener_accept(struct listener *l)
{
- struct connection *c;
- socklen_t len;
+ connection_t *c;
- c = calloc(1, sizeof *c);
for (;;) {
- len = sizeof c->addr;
- c->sd = accept(l->sd, (struct sockaddr *)&c->addr, &len);
- if (c->sd != -1) {
- switch (c->addr.ss_family) {
-#if defined(AF_INET6)
- case AF_INET6: {
- struct sockaddr_in6 *addr =
- (struct sockaddr_in6 *)&c->addr;
- uint16_t *ip = (uint16_t *)&addr->sin6_addr;
-
- log_info("%s(): [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%u",
- __func__,
- ntohs(ip[0]), ntohs(ip[1]),
- ntohs(ip[2]), ntohs(ip[3]),
- ntohs(ip[4]), ntohs(ip[5]),
- ntohs(ip[6]), ntohs(ip[7]),
- ntohs(addr->sin6_port));
- break;
- }
-#endif
- case AF_INET: {
- struct sockaddr_in *addr =
- (struct sockaddr_in *)&c->addr;
- uint8_t *ip = (uint8_t *)&addr->sin_addr;
-
- log_info("%s(): %u.%u.%u.%u:%u",
- __func__,
- ip[0], ip[1], ip[2], ip[3],
- ntohs(addr->sin_port));
- break;
- }
- default:
- LOG_UNREACHABLE();
- }
+ if ((c = connection_accept(l->sd)) != NULL)
return (c);
- }
if (errno != EINTR) {
log_syserr("accept()");
free(c);
Modified: trunk/listener.h
===================================================================
--- trunk/listener.h 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/listener.h 2006-02-10 16:05:32 UTC (rev 6)
@@ -5,9 +5,12 @@
#ifndef LISTENER_H_INCLUDED
#define LISTENER_H_INCLUDED
-struct listener {
- int sd;
- struct sockaddr_storage addr;
-};
+#include "connection.h"
+typedef struct listener listener_t;
+
+listener_t *listener_create(int port);
+void listener_destroy(listener_t *l);
+connection_t *listener_accept(listener_t *l);
+
#endif
Modified: trunk/log.c
===================================================================
--- trunk/log.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/log.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -2,20 +2,41 @@
* $Id$
*/
+#include <sys/types.h>
#include <sys/signal.h>
+#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
#include <unistd.h>
#include "varnish.h"
+#include "log.h"
+#include "system.h"
static void
+timestamp(void)
+{
+ struct timeval now;
+
+ if (gettimeofday(&now, NULL) == -1)
+ now.tv_sec = now.tv_usec = 0;
+ fprintf(stderr, "%lu.%06lu [%lu] ",
+ (unsigned long)now.tv_sec,
+ (unsigned long)now.tv_usec,
+ (unsigned long)sys.pid);
+}
+
+static void
emit(const char *fmt, va_list ap)
{
+ timestamp();
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}
@@ -30,6 +51,7 @@
#else
snprintf(errstr, sizeof errstr, "%s", strerror(errno));
#endif
+ timestamp();
vfprintf(stderr, fmt, ap);
fprintf(stderr, ": %s\n", errstr);
}
Added: trunk/log.h
===================================================================
--- trunk/log.h 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/log.h 2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,19 @@
+/*
+ * $Id$
+ */
+
+#ifndef LOG_H_INCLUDED
+#define LOG_H_INCLUDED
+
+
+void log_info(const char *fmt, ...);
+void log_err(const char *fmt, ...);
+void log_syserr(const char *fmt, ...);
+void log_panic(const char *fmt, ...);
+void log_syspanic(const char *fmt, ...);
+
+#define LOG_UNREACHABLE() \
+ log_panic("%s(%d): %s(): unreachable code reached", \
+ __FILE__, __LINE__, __func__)
+
+#endif
Modified: trunk/request.c
===================================================================
--- trunk/request.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/request.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -5,8 +5,14 @@
#include <stdlib.h>
#include "varnish.h"
+#include "connection.h"
+#include "log.h"
#include "request.h"
+struct request {
+ connection_t *conn;
+};
+
request_t *
request_wait(connection_t *c, unsigned int timeout)
{
Modified: trunk/request.h
===================================================================
--- trunk/request.h 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/request.h 2006-02-10 16:05:32 UTC (rev 6)
@@ -5,8 +5,9 @@
#ifndef REQUEST_H_INCLUDED
#define REQUEST_H_INCLUDED
-struct request {
- struct connection *conn;
-};
+typedef struct request request_t;
+request_t *request_wait(connection_t *c, unsigned int timeout);
+void request_destroy(request_t *r);
+
#endif
Added: trunk/system-common.c
===================================================================
--- trunk/system-common.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/system-common.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#include <sys/types.h>
+
+#include <unistd.h>
+
+#include "varnish.h"
+#include "system.h"
+
+system_t sys;
+
+/*
+ * gather system information at startup
+ */
+void
+system_init(void)
+{
+ sys.pid = getpid();
+ system_init_ncpu();
+}
+
+/*
+ * fork() wrapper, updates sys.pid
+ */
+pid_t
+system_fork(void)
+{
+ pid_t pid;
+
+ if ((pid = fork()) == 0)
+ sys.pid = getpid();
+ return (pid);
+}
Property changes on: trunk/system-common.c
___________________________________________________________________
Name: svn:keywords
+ Id
Added: trunk/system-linux-gnu.c
===================================================================
--- trunk/system-linux-gnu.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/system-linux-gnu.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include "varnish.h"
+#include "log.h"
+#include "system.h"
+
+void
+system_init_ncpu(void)
+{
+ FILE *cpuinfo;
+ char line[256];
+ int n;
+
+ sys.ncpu = 0;
+ if ((cpuinfo = fopen("/proc/cpuinfo", "r")) == NULL)
+ return;
+ while (fgets(line, sizeof line, cpuinfo) != NULL) {
+ if (sscanf(line, "processor : %d", &n) == 1)
+ sys.ncpu++;
+ }
+ fclose(cpuinfo);
+ if (sys.ncpu == 0)
+ sys.ncpu = 1;
+ log_info("%d cpu(s)", sys.ncpu);
+}
Property changes on: trunk/system-linux-gnu.c
___________________________________________________________________
Name: svn:keywords
+ Id
Added: trunk/system.h
===================================================================
--- trunk/system.h 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/system.h 2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,21 @@
+/*
+ * $Id$
+ */
+
+#ifndef SYSTEM_H_INCLUDED
+#define SYSTEM_H_INCLUDED
+
+typedef struct system system_t;
+
+struct system {
+ int ncpu;
+ pid_t pid;
+};
+
+extern system_t sys;
+
+void system_init_ncpu(void);
+void system_init(void);
+pid_t system_fork(void);
+
+#endif
Property changes on: trunk/system.h
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: trunk/varnish.c
===================================================================
--- trunk/varnish.c 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/varnish.c 2006-02-10 16:05:32 UTC (rev 6)
@@ -2,29 +2,70 @@
* $Id$
*/
+#include <sys/wait.h>
+
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "varnish.h"
+#include "connection.h"
+#include "listener.h"
+#include "log.h"
+#include "request.h"
+#include "system.h"
static void
-varnish(void)
+varnish_child(listener_t *l)
{
- listener_t *l;
connection_t *c;
request_t *r;
- l = listener_create(8080);
while ((c = listener_accept(l)) != NULL) {
r = request_wait(c, 0);
/* ... */
request_destroy(r);
connection_destroy(c);
}
+ LOG_UNREACHABLE();
}
static void
+varnish(void)
+{
+ listener_t *l;
+ int i, status;
+ pid_t pid;
+
+ system_init();
+ log_info("starting Varnish");
+ l = listener_create(8080);
+ for (i = 0; i < sys.ncpu; ++i) {
+ switch ((pid = system_fork())) {
+ case -1:
+ log_panic("fork()");
+ break;
+ case 0:
+ varnish_child(l);
+ _exit(1);
+ break;
+ default:
+ log_info("forked child %lu", (unsigned long)pid);
+ break;
+ }
+ }
+ for (;;) {
+ if ((pid = wait(&status)) == -1) {
+ if (errno == ECHILD)
+ return;
+ } else {
+ log_info("child %lu exited", (unsigned long)pid);
+ }
+ }
+}
+
+static void
usage(void)
{
fprintf(stderr, "usage: varnish\n");
@@ -50,6 +91,5 @@
varnish();
- LOG_UNREACHABLE();
exit(1);
}
Modified: trunk/varnish.h
===================================================================
--- trunk/varnish.h 2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/varnish.h 2006-02-10 16:05:32 UTC (rev 6)
@@ -7,32 +7,4 @@
#include "config.h"
-/* opaque structures */
-typedef struct listener listener_t;
-typedef struct connection connection_t;
-typedef struct request request_t;
-
-/* connection.c */
-void connection_destroy(connection_t *c);
-
-/* listener.c */
-listener_t *listener_create(int port);
-void listener_destroy(listener_t *l);
-connection_t *listener_accept(listener_t *l);
-
-/* log.c */
-void log_info(const char *fmt, ...);
-void log_err(const char *fmt, ...);
-void log_syserr(const char *fmt, ...);
-void log_panic(const char *fmt, ...);
-void log_syspanic(const char *fmt, ...);
-
-#define LOG_UNREACHABLE() \
- log_panic("%s(%d): %s(): unreachable code reached", \
- __FILE__, __LINE__, __func__)
-
-/* request.c */
-request_t *request_wait(connection_t *c, unsigned int timeout);
-void request_destroy(request_t *r);
-
#endif
More information about the varnish-commit
mailing list