#include "vcl_returns.h"
#include "common.h"
+#include "miniobj.h"
#define MAX_IOVS 10
typedef void http_callback_f(void *, int bad);
struct http {
+ unsigned magic;
+#define HTTP_MAGIC 0x6428b5c9
struct event ev;
http_callback_f *callback;
void *arg;
/*--------------------------------------------------------------------*/
struct worker {
+ unsigned magic;
+#define WORKER_MAGIC 0x6391adcf
struct event_base *eb;
struct sbuf *sb;
struct objhead *nobjhead;
};
struct workreq {
+ unsigned magic;
+#define WORKREQ_MAGIC 0x5ccb4eb2
TAILQ_ENTRY(workreq) list;
struct sess *sess;
};
/* Backend Connection ------------------------------------------------*/
struct vbe_conn {
+ unsigned magic;
+#define VBE_CONN_MAGIC 0x0c5e6592
TAILQ_ENTRY(vbe_conn) list;
struct vbc_mem *vbcm;
struct vbe *vbe;
/* Storage -----------------------------------------------------------*/
struct storage {
+ unsigned magic;
+#define STORAGE_MAGIC 0x1a4e51c0
TAILQ_ENTRY(storage) list;
unsigned char *ptr;
unsigned len;
/* -------------------------------------------------------------------*/
struct object {
+ unsigned magic;
+#define OBJECT_MAGIC 0x32851d42
unsigned refcnt;
unsigned xid;
struct objhead *objhead;
};
struct objhead {
+ unsigned magic;
+#define OBJHEAD_MAGIC 0x1b96615d
void *hashpriv;
pthread_mutex_t mtx;
/* -------------------------------------------------------------------*/
struct srcaddr {
+ unsigned magic;
+#define SRCADDR_MAGIC 0x375111db
TAILQ_ENTRY(srcaddr) list;
unsigned nsess;
char addr[TCP_ADDRBUFSIZE];
};
struct sess {
+ unsigned magic;
+#define SESS_MAGIC 0x2c2f9c5a
int fd;
unsigned xid;
};
struct backend {
+ unsigned magic;
+#define BACKEND_MAGIC 0x64c4c7c6
const char *vcl_name;
const char *hostname;
const char *portname;
#include "cache.h"
struct vbc_mem {
+ unsigned magic;
+#define VBC_MEM_MAGIC 0x2fd7af01
struct vbe_conn vbe;
struct http http;
char *http_hdr;
/* A backend IP */
struct vbe {
+ unsigned magic;
+#define VBE_MAGIC 0x079648f0
unsigned ip;
TAILQ_ENTRY(vbe) list;
TAILQ_HEAD(,vbe_conn) fconn;
1);
if (vbcm == NULL)
return (NULL);
+ vbcm->magic = VBC_MEM_MAGIC;
VSL_stats->n_vbe_conn++;
+ vbcm->vbe.magic = VBE_CONN_MAGIC;
vbcm->vbe.vbcm = vbcm;
vbcm->vbe.http = &vbcm->http;
http_Init(&vbcm->http, (void *)(vbcm + 1));
vbe_delete_conn(struct vbe_conn *vb)
{
+ CHECK_OBJ_NOTNULL(vb, VBE_CONN_MAGIC);
+ CHECK_OBJ_NOTNULL(vb->vbcm, VBC_MEM_MAGIC);
VSL_stats->n_vbe_conn--;
free(vb->vbcm);
}
struct vbe *vp;
struct vbe_conn *vc;
+ CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
AZ(pthread_mutex_lock(&vbemtx));
vp = bp->vbe;
if (vp == NULL) {
CNT_Session(struct sess *sp)
{
int done;
+ struct worker *w;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ w = sp->wrk;
+ CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
for (done = 0; !done; ) {
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (sp->obj != NULL)
+ CHECK_OBJ(sp->obj, OBJECT_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
switch (sp->step) {
#define STEP(l,u) \
case STP_##u: \
#undef STEP
default: INCOMPL();
}
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
}
}
#include <unistd.h>
#include <stdio.h>
+#include <string.h>
#include "libvarnish.h"
#include "shmlog.h"
t = time(NULL);
AZ(pthread_mutex_lock(&exp_mtx));
TAILQ_FOREACH(o, &exp_deathrow, deathrow) {
+ CHECK_OBJ(o, OBJECT_MAGIC);
if (o->ttl >= t) {
o = NULL;
break;
{
struct object *o;
time_t t;
- struct sess sp;
+ struct sess *sp;
(void)arg;
+ sp = SES_New(NULL, 0);
while (1) {
t = time(NULL);
AZ(pthread_mutex_lock(&exp_mtx));
o = binheap_root(exp_heap);
+ if (o != NULL)
+ CHECK_OBJ(o, OBJECT_MAGIC);
if (o == NULL || o->ttl > t + expearly) {
AZ(pthread_mutex_unlock(&exp_mtx));
AZ(sleep(1));
AZ(pthread_mutex_unlock(&exp_mtx));
VSL(SLT_ExpPick, 0, "%u", o->xid);
- sp.vcl = VCL_Get();
- sp.obj = o;
- VCL_timeout_method(&sp);
- VCL_Rel(sp.vcl);
+ sp->vcl = VCL_Get();
+ sp->obj = o;
+ VCL_timeout_method(sp);
+ VCL_Rel(sp->vcl);
- if (sp.handling == VCL_RET_DISCARD) {
+ if (sp->handling == VCL_RET_DISCARD) {
AZ(pthread_mutex_lock(&exp_mtx));
TAILQ_INSERT_TAIL(&exp_deathrow, o, deathrow);
AZ(pthread_mutex_unlock(&exp_mtx));
continue;
}
- assert(sp.handling == VCL_RET_DISCARD);
+ assert(sp->handling == VCL_RET_DISCARD);
}
}
struct object *o;
char *c;
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC);
assert(hash != NULL);
w = sp->wrk;
h = sp->http;
if (w->nobjhead == NULL) {
w->nobjhead = calloc(sizeof *w->nobjhead, 1);
assert(w->nobjhead != NULL);
+ w->nobjhead->magic = OBJHEAD_MAGIC;
TAILQ_INIT(&w->nobjhead->objects);
AZ(pthread_mutex_init(&w->nobjhead->mtx, NULL));
VSL_stats->n_objecthead++;
- }
+ } else
+ CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC);
if (w->nobj == NULL) {
w->nobj = calloc(sizeof *w->nobj, 1);
assert(w->nobj != NULL);
+ w->nobj->magic = OBJECT_MAGIC;
w->nobj->busy = 1;
w->nobj->refcnt = 1;
TAILQ_INIT(&w->nobj->store);
TAILQ_INIT(&w->nobj->waitinglist);
VSL_stats->n_object++;
- }
+ } else
+ CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
if (!http_GetHdr(h, "Host", &c))
c = h->url;
if (sp->obj != NULL) {
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
o = sp->obj;
oh = o->objhead;
+ CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
AZ(pthread_mutex_lock(&oh->mtx));
goto were_back;
}
oh = hash->lookup(h->url, c, w->nobjhead);
+ CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (oh == w->nobjhead)
w->nobjhead = NULL;
AZ(pthread_mutex_lock(&oh->mtx));
char *sp = space;
memset(hp, 0, sizeof *hp);
+ hp->magic = HTTP_MAGIC;
hp->hdr = (void *)sp;
sp += heritage.mem_http_headers * sizeof hp->hdr;
hp->s = sp;
w = &ww;
memset(w, 0, sizeof *w);
+ w->magic = WORKER_MAGIC;
AZ(pthread_cond_init(&w->cv, NULL));
}
TAILQ_INSERT_HEAD(&wrk_head, w, list);
while (1) {
+ CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
wrq = TAILQ_FIRST(&wrk_reqhead);
if (wrq != NULL) {
VSL_stats->n_wrk_busy++;
AZ(pthread_mutex_unlock(&wrk_mtx));
assert(wrq->sess != NULL);
wrq->sess->wrk = w;
+ CHECK_OBJ_NOTNULL(wrq->sess, SESS_MAGIC);
CNT_Session(wrq->sess);
AZ(pthread_mutex_lock(&wrk_mtx));
VSL_stats->n_wrk_busy--;
wrk_overflow--;
continue;
}
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
/* If we are a reserved thread we don't die */
if (priv != NULL) {
AZ(pthread_cond_wait(&w->cv, &wrk_mtx));
continue;
}
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
/* If we are a dynamic thread, time out and die */
AZ(clock_gettime(CLOCK_REALTIME, &ts));
AZ(pthread_cond_destroy(&w->cv));
return (NULL);
}
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
}
}
/*--------------------------------------------------------------------*/
struct sessmem {
+ unsigned magic;
+#define SESSMEM_MAGIC 0x555859c5
+
struct sess sess;
struct http http;
char *http_hdr;
1);
if (sm == NULL)
return (NULL);
+ sm->magic = SESSMEM_MAGIC;
VSL_stats->n_sess++;
+ sm->sess.magic = SESS_MAGIC;
sm->sess.mem = sm;
sm->sess.http = &sm->http;
http_Init(&sm->http, (void *)(sm + 1));
SES_Delete(struct sess *sp)
{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VSL_stats->n_sess--;
SES_RelSrcAddr(sp);
+ CHECK_OBJ_NOTNULL(sp->mem, SESSMEM_MAGIC);
free(sp->mem);
}
VRT_error(struct sess *sp, unsigned err, const char *str)
{
- (void)sp;
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VSL(SLT_Debug, 0, "VCL_error(%u, %s)", err, str);
}
VRT_count(struct sess *sp, unsigned u)
{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VSL(SLT_VCL_trace, sp->fd, "%u %d.%d", u,
sp->vcl->ref[u].line,
sp->vcl->ref[u].pos);
{
char *p;
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(sp != NULL);
assert(sp->http != NULL);
if (!http_GetHdr(sp->http, n, &p))
VRT_GetReq(struct sess *sp)
{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(sp != NULL);
assert(sp->http != NULL);
return (sp->http->req);
VRT_handling(struct sess *sp, unsigned hand)
{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(!(hand & (hand -1))); /* must be power of two */
sp->handling = hand;
}
int
VRT_obj_valid(struct sess *sp)
{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (sp->obj->valid);
}
int
VRT_obj_cacheable(struct sess *sp)
{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (sp->obj->cacheable);
}
void
VRT_set_backend_hostname(struct backend *be, const char *h)
{
+ CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
be->hostname = h;
}
void
VRT_set_backend_portname(struct backend *be, const char *p)
{
+ CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
be->portname = p;
}
void
VRT_set_backend_name(struct backend *be, const char *p)
{
+ CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
be->vcl_name = p;
}
for (i = 0; i < cp->nbackend; i++) {
cp->backend[i] = calloc(sizeof *cp->backend[i], 1);
assert(cp->backend[i] != NULL);
+ cp->backend[i]->magic = BACKEND_MAGIC;
}
}
/*--------------------------------------------------------------------*/
struct hcl_entry {
+ unsigned magic;
+#define HCL_ENTRY_MAGIC 0x0ba707bf
TAILQ_ENTRY(hcl_entry) list;
char *key1;
char *key2;
- struct objhead *obj;
+ struct objhead *oh;
unsigned refcnt;
unsigned hash;
unsigned mtx;
*/
static struct objhead *
-hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
+hcl_lookup(const char *key1, const char *key2, struct objhead *noh)
{
struct hcl_entry *he, *he2;
MD5_CTX c;
unsigned u1, u2;
int i;
+ CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC);
MD5Init(&c);
MD5Update(&c, key1, strlen(key1));
MD5Update(&c, "", 1);
AZ(pthread_mutex_lock(&hcl_mutex[u2]));
TAILQ_FOREACH(he, &hcl_head[u1], list) {
+ CHECK_OBJ_NOTNULL(he, HCL_ENTRY_MAGIC);
i = strcmp(key1, he->key1);
if (i < 0)
continue;
if (i > 0)
break;
he->refcnt++;
- nobj = he->obj;
- nobj->hashpriv = he;
+ noh = he->oh;
+ noh->hashpriv = he;
AZ(pthread_mutex_unlock(&hcl_mutex[u2]));
- return (nobj);
+ return (noh);
}
- if (nobj == NULL) {
+ if (noh == NULL) {
AZ(pthread_mutex_unlock(&hcl_mutex[u2]));
return (NULL);
}
he2 = calloc(sizeof *he2, 1);
assert(he2 != NULL);
- he2->obj = nobj;
+ he2->magic = HCL_ENTRY_MAGIC;
+ he2->oh = noh;
he2->refcnt = 1;
he2->hash = u1;
he2->mtx = u2;
assert(he2->key1 != NULL);
he2->key2 = strdup(key2);
assert(he2->key2 != NULL);
- nobj->hashpriv = he2;
+ noh->hashpriv = he2;
if (he != NULL)
TAILQ_INSERT_BEFORE(he, he2, list);
else
TAILQ_INSERT_TAIL(&hcl_head[u1], he2, list);
AZ(pthread_mutex_unlock(&hcl_mutex[u2]));
- return (nobj);
+ return (noh);
}
/*--------------------------------------------------------------------
*/
static int
-hcl_deref(struct objhead *obj)
+hcl_deref(struct objhead *oh)
{
struct hcl_entry *he;
int ret;
unsigned mtx;
- assert(obj->hashpriv != NULL);
- he = obj->hashpriv;
+ CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
+ CAST_OBJ_NOTNULL(he, oh->hashpriv, HCL_ENTRY_MAGIC);
mtx = he->mtx;
AZ(pthread_mutex_lock(&hcl_mutex[mtx]));
if (--he->refcnt == 0) {