bin_PROGRAMS = varnishd
varnishd_SOURCES = \
+ cache_acceptor.c \
cache_main.c \
cli_event.c \
mgt_child.c \
varnishd_LDADD = \
$(top_builddir)/lib/libvarnish/libvarnish.la \
$(top_builddir)/lib/libsbuf/libsbuf.la \
- $(top_builddir)/contrib/libevent/libevent.la
+ $(top_builddir)/contrib/libevent/libevent.la \
+ -lpthread
--- /dev/null
+/*
+ * $Id$
+ */
+
+#define VCA_RXBUFSIZE 1024
+struct sess {
+ int fd;
+ char rcv[VCA_RXBUFSIZE + 1];
+ unsigned rcv_len;
+ struct event rd_e;
+};
+
+/* cache_acceptor.c */
+void *vca_main(void *arg);
--- /dev/null
+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <sbuf.h>
+#include <event.h>
+
+#include "heritage.h"
+#include "cache.h"
+
+static struct event_base *evb;
+
+static struct event accept_e[2 * HERITAGE_NSOCKS];
+
+static void
+http_read_f(int fd, short event, void *arg)
+{
+ struct sess *sp = arg;
+ const char *p;
+ int i;
+
+ printf("%s(%d, %d, ...)\n", __func__, fd, event);
+ assert(VCA_RXBUFSIZE - sp->rcv_len > 0);
+ i = read(fd, sp->rcv + sp->rcv_len, VCA_RXBUFSIZE - sp->rcv_len);
+ assert(i > 0);
+ sp->rcv_len += i;
+ sp->rcv[sp->rcv_len] = '\0';
+
+ p = sp->rcv;
+ while (1) {
+ /* XXX: we could save location of all linebreaks for later */
+ p = strchr(p, '\n');
+ if (p == NULL)
+ return;
+ p++;
+ if (*p == '\r')
+ p++;
+ if (*p != '\n')
+ continue;
+ break;
+ }
+ printf("full <%s>\n", sp->rcv);
+ event_del(&sp->rd_e);
+}
+
+static void
+accept_f(int fd, short event, void *arg __unused)
+{
+ socklen_t l;
+ struct sockaddr addr;
+ struct sess *sp;
+
+ sp = calloc(sizeof *sp, 1);
+ assert(sp != NULL);
+
+ printf("%s(%d, %d, ...)\n", __func__, fd, event);
+
+ l = sizeof addr;
+ sp->fd = accept(fd, &addr, &l);
+ if (sp->fd < 0) {
+ free(sp);
+ return;
+ }
+
+ event_set(&sp->rd_e, sp->fd, EV_READ | EV_PERSIST,
+ http_read_f, sp);
+ event_base_set(evb, &sp->rd_e);
+ event_add(&sp->rd_e, NULL); /* XXX: timeout */
+}
+
+void *
+vca_main(void *arg)
+{
+ unsigned u;
+ struct event *ep;
+
+ evb = event_init();
+
+ ep = accept_e;
+ for (u = 0; u < HERITAGE_NSOCKS; u++) {
+ if (heritage.sock_local[u] >= 0) {
+ event_set(ep, heritage.sock_local[u],
+ EV_READ | EV_PERSIST,
+ accept_f, NULL);
+ event_base_set(evb, ep);
+ event_add(ep, NULL);
+ ep++;
+ }
+ if (heritage.sock_remote[u] >= 0) {
+ event_set(ep, heritage.sock_remote[u],
+ EV_READ | EV_PERSIST,
+ accept_f, NULL);
+ event_base_set(evb, ep);
+ event_add(ep, NULL);
+ ep++;
+ }
+ }
+
+ event_base_loop(evb, 0);
+
+ return ("FOOBAR");
+}
#include <stdlib.h>
#include <sys/time.h>
+#include <pthread.h>
+
#include <event.h>
#include <cli.h>
#include <cli_priv.h>
+#include "libvarnish.h"
#include "heritage.h"
+#include "cache.h"
#include "cli_event.h"
static struct event ev_keepalive;
{
cli_out(cli, "url <%s>", av[2]);
- sleep(1);
cli_result(cli, CLIS_UNIMPL);
}
{ NULL }
};
+static pthread_t vca_thread;
+
void
child_main(void)
{
setbuf(stderr, NULL);
printf("Child starts\n");
+ AZ(pthread_create(&vca_thread, NULL, vca_main, NULL));
+
eb = event_init();
assert(eb != NULL);
{
const char *p;
- p = evbuffer_readline(bev->input);
- if (p == NULL)
- return;
- printf("Child said <%s>\n", p);
+ while (1) {
+ p = evbuffer_readline(bev->input);
+ if (p == NULL)
+ return;
+ printf("Child said <%s>\n", p);
+ }
}
static void
#include <netdb.h>
#include "heritage.h"
+#include "libvarnish.h"
static void
create_listen_socket(const char *addr, const char *port, int *sp, int nsp)
i = getaddrinfo(addr, port, &ai, &r0);
if (i) {
- fprintf("getaddrinfo failed: %s\n", gai_strerror(i));
+ fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(i));
return;
}
create_listen_socket(NULL, port,
&heritage.sock_remote[0], HERITAGE_NSOCKS);
+ for (u = 0; u < HERITAGE_NSOCKS; u++) {
+ if (heritage.sock_local[u] >= 0)
+ AZ(listen(heritage.sock_local[u], 16));
+ if (heritage.sock_remote[u] >= 0)
+ AZ(listen(heritage.sock_remote[u], 16));
+ }
return (0);
}
main(int argc, char *argv[])
{
int o;
- unsigned portnumber = 8080;
+ const char *portnumber = "8080";
unsigned dflag = 1; /* XXX: debug=on for now */
register_printf_render_std((const unsigned char *)"HVQ");
- open_tcp("8080");
-
while ((o = getopt(argc, argv, "dp:")) != -1)
switch (o) {
case 'd':
dflag++;
break;
case 'p':
- portnumber = strtoul(optarg, NULL, 0);
+ portnumber = optarg;
break;
default:
usage();
if (argc != 0)
usage();
+ /*
+ * XXX: Lacking the suspend/resume facility (due to the socket API
+ * missing an unlisten(2) facility) we may want to push this into
+ * the child to limit the amount of time where the socket(s) exists
+ * but do not answer. That, on the other hand, would eliminate the
+ * possibility of doing a "no-glitch" restart of the child process.
+ */
+ open_tcp(portnumber);
+
testme();