Commit d558d26e authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move session management to new file (cache_session, SES prefix) in

preparation of adding client tracking.

Move the iovec's from the session to the worker and give the session
a pointer to the worker so we can avoid passing it around as argument.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@467 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 9764cb28
......@@ -27,6 +27,7 @@ varnishd_SOURCES = \
cache_pass.c \
cache_pipe.c \
cache_response.c \
cache_session.c \
cache_vcl.c \
cache_vrt.c \
cli_event.c \
......
......@@ -4,6 +4,7 @@
#include <assert.h>
#include <pthread.h>
#include <sys/uio.h>
#include <sys/time.h>
#include "queue.h"
......@@ -13,6 +14,8 @@
#include "vcl_returns.h"
#include "common.h"
#define MAX_IOVS 10
struct event_base;
struct cli;
struct sbuf;
......@@ -66,6 +69,10 @@ struct worker {
unsigned nbr;
pthread_cond_t cv;
TAILQ_ENTRY(worker) list;
struct iovec iov[MAX_IOVS];
unsigned niov;
size_t liov;
};
struct workreq {
......@@ -147,12 +154,24 @@ struct objhead {
TAILQ_HEAD(,object) objects;
};
/* -------------------------------------------------------------------*/
struct client {
TAILQ_ENTRY(client) list;
unsigned nsess;
char addr[TCP_ADDRBUFFSIZE];
uint64_t bytes;
};
struct sess {
int fd;
unsigned xid;
struct worker *wrk;
/* formatted ascii client address */
char addr[TCP_ADDRBUFFSIZE];
struct client *client;
/* HTTP request */
struct http *http;
......@@ -270,6 +289,12 @@ void PipeSession(struct worker *w, struct sess *sp);
void WRK_Init(void);
void WRK_QueueSession(struct sess *sp);
/* cache_session.c [SES] */
void SES_Init(void);
struct sess *SES_New(struct sockaddr *addr, unsigned len);
void SES_Delete(const struct sess *sp);
/* cache_shmlog.c */
void VSL_Init(void);
......
......@@ -32,50 +32,9 @@ static struct timeval tick_rate;
static pthread_t vca_thread;
#define SESS_IOVS 10
static struct event accept_e[2 * HERITAGE_NSOCKS];
static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead);
struct sessmem {
struct sess sess;
struct iovec iov[SESS_IOVS];
int niov;
size_t liov;
struct http http;
char *http_hdr;
};
/*--------------------------------------------------------------------*/
static struct sess *
vca_new_sess(void)
{
struct sessmem *sm;
sm = calloc(
sizeof *sm +
heritage.mem_http_headers * sizeof sm->http_hdr +
heritage.mem_http_headerspace +
heritage.mem_workspace,
1);
if (sm == NULL)
return (NULL);
VSL_stats->n_sess++;
sm->sess.mem = sm;
sm->sess.http = &sm->http;
http_Init(&sm->http, (void *)(sm + 1));
return (&sm->sess);
}
static void
vca_delete_sess(const struct sess *sp)
{
VSL_stats->n_sess--;
free(sp->mem);
}
/*--------------------------------------------------------------------
* Write data to client
......@@ -89,13 +48,13 @@ vca_flush(struct sess *sp)
{
int i;
if (sp->fd < 0 || sp->mem->niov == 0)
if (sp->fd < 0 || sp->wrk->niov == 0)
return;
i = writev(sp->fd, sp->mem->iov, sp->mem->niov);
if (i != sp->mem->liov)
i = writev(sp->fd, sp->wrk->iov, sp->wrk->niov);
if (i != sp->wrk->liov)
vca_close_session(sp, "remote closed");
sp->mem->liov = 0;
sp->mem->niov = 0;
sp->wrk->liov = 0;
sp->wrk->niov = 0;
}
void
......@@ -104,13 +63,13 @@ vca_write(struct sess *sp, void *ptr, size_t len)
if (sp->fd < 0 || len == 0)
return;
if (sp->mem->niov == SESS_IOVS)
if (sp->wrk->niov == MAX_IOVS)
vca_flush(sp);
if (sp->fd < 0)
return;
sp->mem->iov[sp->mem->niov].iov_base = ptr;
sp->mem->iov[sp->mem->niov++].iov_len = len;
sp->mem->liov += len;
sp->wrk->iov[sp->wrk->niov].iov_base = ptr;
sp->wrk->iov[sp->wrk->niov++].iov_len = len;
sp->wrk->liov += len;
}
void
......@@ -145,9 +104,9 @@ vca_write_obj(struct worker *w, struct sess *sp)
continue;
}
st->stevedore->send(st, sp,
sp->mem->iov, sp->mem->niov, sp->mem->liov);
sp->mem->niov = 0;
sp->mem->liov = 0;
sp->wrk->iov, sp->wrk->niov, sp->wrk->liov);
sp->wrk->niov = 0;
sp->wrk->liov = 0;
}
assert(u == sp->obj->len);
}
......@@ -221,16 +180,17 @@ accept_f(int fd, short event, void *arg)
(void)arg;
VSL_stats->client_conn++;
sp = vca_new_sess();
assert(sp != NULL); /* XXX handle */
l = sizeof addr;
sp->fd = accept(fd, addr, &l);
if (sp->fd < 0) {
vca_delete_sess(sp);
i = accept(fd, addr, &l);
if (i < 0) {
return;
}
sp = SES_New(addr, l);
assert(sp != NULL); /* XXX handle */
sp->fd = i;
#ifdef SO_NOSIGPIPE /* XXX Linux */
i = 1;
AZ(setsockopt(sp->fd, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i));
......@@ -315,7 +275,7 @@ vca_return_session(struct sess *sp)
VSL(SLT_SessionReuse, sp->fd, "%s", sp->addr);
assert(sizeof sp == write(pipes[1], &sp, sizeof sp));
} else {
vca_delete_sess(sp);
SES_Delete(sp);
}
}
......
......@@ -521,6 +521,8 @@ CNT_Session(struct worker *w, struct sess *sp)
sp->t0 = time(NULL);
sp->vcl = VCL_Get();
sp->wrk = w;
for (sp->step = STP_RECV; sp->step != STP_DONE; ) {
switch (sp->step) {
#define STEP(l,u) \
......
......@@ -105,6 +105,8 @@ child_main(void)
VCL_Init();
VCL_Load(heritage.vcl_file, "boot", NULL);
SES_Init();
VBE_Init();
VSL_Init();
WRK_Init();
......
/*
* $Id$
*
* Session and Client management.
*
* The client structures are kept around only as a convenience feature to
* make it possible to track down offenders and misconfigured caches.
* As such it is pure overhead and we do not want to spend too much time
* on maintaining it.
*
* We identify clients by their address only and disregard the port number,
* because the desired level of granularity is "whois is abuse@ or tech-c@
* in the RIPE database.
*/
#include <stdlib.h>
#include <sys/uio.h>
#include "heritage.h"
#include "cache.h"
#include "shmlog.h"
#define CLIENT_HASH 256
/*--------------------------------------------------------------------*/
struct sessmem {
struct sess sess;
struct http http;
char *http_hdr;
};
/*--------------------------------------------------------------------*/
TAILQ_HEAD(clienthead ,client);
static struct clienthead client_hash[CLIENT_HASH];
/*--------------------------------------------------------------------*/
struct sess *
SES_New(struct sockaddr *addr, unsigned len)
{
struct sessmem *sm;
(void)addr; /* XXX */
(void)len; /* XXX */
sm = calloc(
sizeof *sm +
heritage.mem_http_headers * sizeof sm->http_hdr +
heritage.mem_http_headerspace +
heritage.mem_workspace,
1);
if (sm == NULL)
return (NULL);
VSL_stats->n_sess++;
sm->sess.mem = sm;
sm->sess.http = &sm->http;
http_Init(&sm->http, (void *)(sm + 1));
return (&sm->sess);
}
void
SES_Delete(const struct sess *sp)
{
VSL_stats->n_sess--;
free(sp->mem);
}
/*--------------------------------------------------------------------*/
void
SES_Init()
{
int i;
for (i = 0; i < CLIENT_HASH; i++)
TAILQ_INIT(&client_hash[i]);
}
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