/* Precreate an objhead and object for later use */
static void
hsh_prealloc(struct worker *wrk)
{
	struct objhead *oh;
	struct waitinglist *wl;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

	if (wrk->nobjcore == NULL)
		wrk->nobjcore = HSH_NewObjCore(wrk);
	CHECK_OBJ_NOTNULL(wrk->nobjcore, OBJCORE_MAGIC);

	if (wrk->nobjhead == NULL) {
		ALLOC_OBJ(oh, OBJHEAD_MAGIC);
		XXXAN(oh);
		oh->refcnt = 1;
		VTAILQ_INIT(&oh->objcs);
		Lck_New(&oh->mtx, lck_objhdr);
		wrk->nobjhead = oh;
		wrk->stats.n_objecthead++;
	}
	CHECK_OBJ_NOTNULL(wrk->nobjhead, OBJHEAD_MAGIC);

	if (wrk->nwaitinglist == NULL) {
		ALLOC_OBJ(wl, WAITINGLIST_MAGIC);
		XXXAN(wl);
		VTAILQ_INIT(&wl->list);
		wrk->nwaitinglist = wl;
		wrk->stats.n_waitinglist++;
	}
	CHECK_OBJ_NOTNULL(wrk->nwaitinglist, WAITINGLIST_MAGIC);

	if (hash->prep != NULL)
		hash->prep(wrk);
}
Beispiel #2
0
static struct pool *
pool_mkpool(unsigned pool_no)
{
	struct pool *pp;

	ALLOC_OBJ(pp, POOL_MAGIC);
	if (pp == NULL)
		return (NULL);
	pp->a_stat = calloc(1, sizeof *pp->a_stat);
	AN(pp->a_stat);
	pp->b_stat = calloc(1, sizeof *pp->b_stat);
	AN(pp->b_stat);
	Lck_New(&pp->mtx, lck_wq);

	VTAILQ_INIT(&pp->idle_queue);
	VTAILQ_INIT(&pp->front_queue);
	VTAILQ_INIT(&pp->back_queue);
	AZ(pthread_cond_init(&pp->herder_cond, NULL));
	AZ(pthread_create(&pp->herder_thr, NULL, pool_herder, pp));

	while (VTAILQ_EMPTY(&pp->idle_queue))
		(void)usleep(10000);

	pp->sesspool = SES_NewPool(pp, pool_no);
	AN(pp->sesspool);

	return (pp);
}
Beispiel #3
0
static struct objhead *
hsh_newobjhead(void)
{
	struct objhead *oh;

	ALLOC_OBJ(oh, OBJHEAD_MAGIC);
	XXXAN(oh);
	oh->refcnt = 1;
	VTAILQ_INIT(&oh->objcs);
	VTAILQ_INIT(&oh->waitinglist);
	Lck_New(&oh->mtx, lck_objhdr);
	return (oh);
}
Beispiel #4
0
static struct vxp *
vxp_New(struct vsb *sb)
{
	struct vxp *vxp;

	AN(sb);

	ALLOC_OBJ(vxp, VXP_MAGIC);
	AN(vxp);
	VTAILQ_INIT(&vxp->membits);
	VTAILQ_INIT(&vxp->tokens);
	vxp->sb = sb;

	return (vxp);
}
/* Precreate an objhead and object for later use */
static void
hsh_prealloc(struct worker *wrk)
{
	struct waitinglist *wl;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

	if (wrk->nobjcore == NULL)
		wrk->nobjcore = hsh_NewObjCore(wrk);
	CHECK_OBJ_NOTNULL(wrk->nobjcore, OBJCORE_MAGIC);

	if (wrk->nobjhead == NULL) {
		wrk->nobjhead = hsh_newobjhead();
		wrk->stats->n_objecthead++;
	}
	CHECK_OBJ_NOTNULL(wrk->nobjhead, OBJHEAD_MAGIC);

	if (wrk->nwaitinglist == NULL) {
		ALLOC_OBJ(wl, WAITINGLIST_MAGIC);
		XXXAN(wl);
		VTAILQ_INIT(&wl->list);
		wrk->nwaitinglist = wl;
		wrk->stats->n_waitinglist++;
	}
	CHECK_OBJ_NOTNULL(wrk->nwaitinglist, WAITINGLIST_MAGIC);

	if (hash->prep != NULL)
		hash->prep(wrk);
}
static void *
vwe_init(void)
{
	int i;
	struct vwe *vwe;

	ALLOC_OBJ(vwe, VWE_MAGIC);
	AN(vwe);
	VTAILQ_INIT(&vwe->sesshead);
	AZ(pipe(vwe->pipes));
	AZ(pipe(vwe->timer_pipes));

	i = fcntl(vwe->pipes[0], F_GETFL);
	assert(i != -1);
	i |= O_NONBLOCK;
	i = fcntl(vwe->pipes[0], F_SETFL, i);
	assert(i != -1);

	i = fcntl(vwe->timer_pipes[0], F_GETFL);
	assert(i != -1);
	i |= O_NONBLOCK;
	i = fcntl(vwe->timer_pipes[0], F_SETFL, i);
	assert(i != -1);

	AZ(pthread_create(&vwe->timer_thread,
	    NULL, vwe_sess_timeout_ticker, vwe));
	AZ(pthread_create(&vwe->epoll_thread, NULL, vwe_thread, vwe));
	return(vwe);
}
Beispiel #7
0
struct VSL_data *
VSL_New(void)
{
	struct VSL_data *vsl;

	ALLOC_OBJ(vsl, VSL_MAGIC);
	if (vsl == NULL)
		return (NULL);

	vsl->vbm_select = vbit_init(256);
	vsl->vbm_supress = vbit_init(256);
	VTAILQ_INIT(&vsl->vslf_select);
	VTAILQ_INIT(&vsl->vslf_suppress);

	return (vsl);
}
Beispiel #8
0
struct VSL_data *
VSL_New(void)
{
	struct VSL_data *vsl;

	ALLOC_OBJ(vsl, VSL_MAGIC);
	if (vsl == NULL)
		return (NULL);

	vsl->L_opt = 1000;
	vsl->T_opt = 120.;
	vsl->vbm_select = vbit_new(SLT__MAX);
	vsl->vbm_supress = vbit_new(SLT__MAX);
	VTAILQ_INIT(&vsl->vslf_select);
	VTAILQ_INIT(&vsl->vslf_suppress);

	return (vsl);
}
Beispiel #9
0
/* Precreate an objhead and object for later use */
void
HSH_Prealloc(const struct sess *sp)
{
	struct worker *wrk;
	struct objhead *oh;
	struct objcore *oc;
	struct waitinglist *wl;

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
	wrk = sp->wrk;

	if (wrk->nobjcore == NULL) {
		ALLOC_OBJ(oc, OBJCORE_MAGIC);
		XXXAN(oc);
		wrk->nobjcore = oc;
		wrk->stats.n_objectcore++;
		oc->flags |= OC_F_BUSY;
	}
	CHECK_OBJ_NOTNULL(wrk->nobjcore, OBJCORE_MAGIC);

	if (wrk->nobjhead == NULL) {
		ALLOC_OBJ(oh, OBJHEAD_MAGIC);
		XXXAN(oh);
		oh->refcnt = 1;
		VTAILQ_INIT(&oh->objcs);
		Lck_New(&oh->mtx, lck_objhdr);
		wrk->nobjhead = oh;
		wrk->stats.n_objecthead++;
	}
	CHECK_OBJ_NOTNULL(wrk->nobjhead, OBJHEAD_MAGIC);

	if (wrk->nwaitinglist == NULL) {
		ALLOC_OBJ(wl, WAITINGLIST_MAGIC);
		XXXAN(wl);
		VTAILQ_INIT(&wl->list);
		wrk->nwaitinglist = wl;
		wrk->stats.n_waitinglist++;
	}
	CHECK_OBJ_NOTNULL(wrk->nwaitinglist, WAITINGLIST_MAGIC);

	if (hash->prep != NULL)
		hash->prep(sp);
}
static void *
vws_init(void)
{
	struct vws *vws;

	ALLOC_OBJ(vws, VWS_MAGIC);
	AN(vws);
	VTAILQ_INIT(&vws->sesshead);
	AZ(pthread_create(&vws->ports_thread, NULL, vws_thread, vws));
	return (vws);
}
Beispiel #11
0
struct sesspool *
SES_NewPool(struct pool *pp)
{
	struct sesspool *sp;

	ALLOC_OBJ(sp, SESSPOOL_MAGIC);
	AN(sp);
	sp->pool = pp;
	VTAILQ_INIT(&sp->freelist);
	Lck_New(&sp->mtx, lck_sessmem);
	return (sp);
}
Beispiel #12
0
struct mempool *
MPL_New(const char *name,
    volatile struct poolparam *pp, volatile unsigned *cur_size)
{
	struct mempool *mpl;

	ALLOC_OBJ(mpl, MEMPOOL_MAGIC);
	AN(mpl);
	bprintf(mpl->name, "%s", name);
	mpl->param = pp;
	mpl->cur_size = cur_size;
	VTAILQ_INIT(&mpl->list);
	VTAILQ_INIT(&mpl->surplus);
	Lck_New(&mpl->mtx, lck_mempool);
	/* XXX: prealloc min_pool */
	mpl->vsc = VSM_Alloc(sizeof *mpl->vsc,
	    VSC_CLASS, VSC_type_mempool, mpl->name);
	AN(mpl->vsc);
	AZ(pthread_create(&mpl->thread, NULL, mpl_guard, mpl));
	AZ(pthread_detach(mpl->thread));
	return (mpl);
}
Beispiel #13
0
void
COT_init(struct callout_block *cb)
{
	struct tms tms;
	int i;

	bzero(cb, sizeof(struct callout_block));

	cb->ncallout = 16;		/* FIXME: with proper value */
	cot_callwhell_alloc(cb);
	cb->ticks = cb->softticks = times(&tms);

	for (i = 0; i < cb->callwheelsize; i++) {
		VTAILQ_INIT(&cb->callwheel[i]);
	}
}
Beispiel #14
0
struct sesspool *
SES_NewPool(struct pool *wp, unsigned pool_no)
{
	struct sesspool *pp;
	char nb[8];

	ALLOC_OBJ(pp, SESSPOOL_MAGIC);
	AN(pp);
	pp->pool = wp;
	VTAILQ_INIT(&pp->freelist);
	Lck_New(&pp->mtx, lck_sessmem);
	bprintf(nb, "req%u", pool_no);
	pp->req_size = sizeof (struct req);
	pp->mpl_req = MPL_New(nb, &cache_param->req_pool, &pp->req_size);
	return (pp);
}
static void *
vwk_init(void)
{
	struct vwk *vwk;

	ALLOC_OBJ(vwk, VWK_MAGIC);
	AN(vwk);

	VTAILQ_INIT(&vwk->sesshead);
	AZ(pipe(vwk->pipes));

	AZ(VFIL_nonblocking(vwk->pipes[0]));
	AZ(VFIL_nonblocking(vwk->pipes[1]));

	AZ(pthread_create(&vwk->thread, NULL, vwk_thread, vwk));
	return (vwk);
}
static double
ban_lurker_work(struct worker *wrk, struct vsl_log *vsl)
{
	struct ban *b, *bd;
	struct banhead_s obans;
	double d, dt, n;

	dt = 49.62;		// Random, non-magic
	if (cache_param->ban_lurker_sleep == 0)
		return (dt);

	Lck_Lock(&ban_mtx);
	b = ban_start;
	Lck_Unlock(&ban_mtx);
	d = VTIM_real() - cache_param->ban_lurker_age;
	bd = NULL;
	VTAILQ_INIT(&obans);
	for (; b != NULL; b = VTAILQ_NEXT(b, list)) {
		if (bd != NULL)
			ban_lurker_test_ban(wrk, vsl, b, &obans, bd);
		if (b->flags & BANS_FLAG_COMPLETED)
			continue;
		if (b->flags & BANS_FLAG_REQ) {
			bd = VTAILQ_NEXT(b, list);
			continue;
		}
		n = ban_time(b->spec) - d;
		if (n < 0) {
			VTAILQ_INSERT_TAIL(&obans, b, l_list);
			if (bd == NULL)
				bd = b;
		} else if (n < dt) {
			dt = n;
		}
	}

	Lck_Lock(&ban_mtx);
	VTAILQ_FOREACH(b, &obans, l_list)
		ban_mark_completed(b);
	Lck_Unlock(&ban_mtx);
	return (dt);
}
static void *
vwe_init(void)
{
	struct vwe *vwe;

	ALLOC_OBJ(vwe, VWE_MAGIC);
	AN(vwe);
	VTAILQ_INIT(&vwe->sesshead);
	AZ(pipe(vwe->pipes));
	AZ(pipe(vwe->timer_pipes));

	AZ(VFIL_nonblocking(vwe->pipes[0]));
	AZ(VFIL_nonblocking(vwe->pipes[1]));
	AZ(VFIL_nonblocking(vwe->timer_pipes[0]));

	AZ(pthread_create(&vwe->timer_thread,
	    NULL, vwe_timeout_idle_ticker, vwe));
	AZ(pthread_create(&vwe->epoll_thread, NULL, vwe_thread, vwe));
	return(vwe);
}
Beispiel #18
0
static void *
vwk_init(void)
{
	int i;
	struct vwk *vwk;

	ALLOC_OBJ(vwk, VWK_MAGIC);
	AN(vwk);

	VTAILQ_INIT(&vwk->sesshead);
	AZ(pipe(vwk->pipes));

	i = fcntl(vwk->pipes[0], F_GETFL);
	assert(i != -1);
	i |= O_NONBLOCK;
	i = fcntl(vwk->pipes[0], F_SETFL, i);
	assert(i != -1);

	AZ(pthread_create(&vwk->thread, NULL, vwk_thread, vwk));
	return (vwk);
}
Beispiel #19
0
struct waiter *
Waiter_New(void)
{
	struct waiter *w;

	AN(waiter);
	AN(waiter->name);
	AN(waiter->init);
	AN(waiter->enter);
	AN(waiter->fini);

	w = calloc(1, sizeof (struct waiter) + waiter->size);
	AN(w);
	INIT_OBJ(w, WAITER_MAGIC);
	w->priv = (void*)(w + 1);
	w->impl = waiter;
	VTAILQ_INIT(&w->waithead);
	w->heap = binheap_new(w, waited_cmp, waited_update);

	waiter->init(w);

	return (w);
}
Beispiel #20
0
struct req *
SES_GetReq(struct worker *wrk, struct sess *sp)
{
	struct sesspool *pp;
	struct req *req;
	uint16_t nhttp;
	unsigned sz, hl;
	char *p, *e;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	pp = sp->sesspool;
	CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
	AN(pp->pool);

	req = MPL_Get(pp->mpl_req, &sz);
	AN(req);
	req->magic = REQ_MAGIC;
	req->sp = sp;

	e = (char*)req + sz;
	p = (char*)(req + 1);
	p = (void*)PRNDUP(p);
	assert(p < e);

	nhttp = (uint16_t)cache_param->http_max_hdr;
	hl = HTTP_estimate(nhttp);

	req->http = HTTP_create(p, nhttp);
	p += hl;
	p = (void*)PRNDUP(p);
	assert(p < e);

	req->http0 = HTTP_create(p, nhttp);
	p += hl;
	p = (void*)PRNDUP(p);
	assert(p < e);

	req->resp = HTTP_create(p, nhttp);
	p += hl;
	p = (void*)PRNDUP(p);
	assert(p < e);

	sz = cache_param->vsl_buffer;
	VSL_Setup(req->vsl, p, sz);
	req->vsl->wid = VXID_Get(&wrk->vxid_pool) | VSL_CLIENTMARKER;
	VSLb(req->vsl, SLT_Begin, "req %u", sp->vxid & VSL_IDENTMASK);
	VSL(SLT_Link, req->sp->vxid, "req %u", req->vsl->wid & VSL_IDENTMASK);
	p += sz;
	p = (void*)PRNDUP(p);

	assert(p < e);

	WS_Init(req->ws, "req", p, e - p);

	req->t_req = NAN;
	req->t_resp = NAN;

	VTAILQ_INIT(&req->body);

	return (req);
}
Beispiel #21
0
vmod_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e ev)
{
  struct vmod_disco *vd;

  CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);

  switch(ev) {
  case VCL_EVENT_LOAD:
    AZ(pthread_mutex_lock(&global_mtx));
    if (global_load_count == 0) {
      ALLOC_OBJ(vd, VMOD_DISCO_MAGIC);
      AN(vd);
      priv->len = sizeof(*vd);
      priv->free = free_func;
      VTAILQ_INIT(&vd->dirs);
      update_rwlock_new(&vd->mtx);
      AN(vd->mtx);
      default_mod = vd;
    } else {
      vd = priv->priv;
      CHECK_OBJ_ORNULL(vd, VMOD_DISCO_MAGIC);
      if (!vd) {
        struct vmod_disco *dvd = default_mod ? default_mod : warmed_mod;

        if (dvd) {
          update_rwlock_wrlock(dvd->mtx);
        }
        ALLOC_OBJ(vd, VMOD_DISCO_MAGIC);
        AN(vd);
        priv->len = sizeof(*vd);
        priv->free = free_func;
        VTAILQ_INIT(&vd->dirs);
        update_rwlock_new(&vd->mtx);
        AN(vd->mtx);
        default_mod = vd;
        if (dvd) {
          update_rwlock_unlock(dvd->mtx, NULL);
        }
      }
    }
    CHECK_OBJ_NOTNULL(vd, VMOD_DISCO_MAGIC);
    priv->priv = vd;
    global_load_count++;
    AZ(pthread_mutex_unlock(&global_mtx));
    break;
  case VCL_EVENT_DISCARD:
    AZ(pthread_mutex_lock(&global_mtx));
    AN(global_load_count);
    global_load_count--;
    AZ(pthread_mutex_unlock(&global_mtx));
    break;
  case VCL_EVENT_WARM:
    AZ(pthread_mutex_lock(&global_mtx));
    vd = priv->priv;
    CHECK_OBJ_NOTNULL(vd, VMOD_DISCO_MAGIC);
    AZ(vd->wrk);
    update_rwlock_wrlock(vd->mtx);
    if (default_mod == NULL && warmed_mod != NULL)
      default_mod = warmed_mod;
    warmed_mod = vd;
    vmod_disco_bgthread_start(&vd->wrk, vd, 10);
    update_rwlock_unlock(vd->mtx, NULL);
    AZ(pthread_mutex_unlock(&global_mtx));
    break;
  case VCL_EVENT_COLD:
    AZ(pthread_mutex_lock(&global_mtx));
    CAST_OBJ_NOTNULL(vd, priv->priv, VMOD_DISCO_MAGIC);
    CHECK_OBJ_NOTNULL(vd->wrk, VMOD_DISCO_BGTHREAD_MAGIC);
    vmod_disco_bgthread_delete(&vd->wrk);
    AZ(vd->wrk);
    if (vd == default_mod && warmed_mod != NULL)
      default_mod = warmed_mod;
    AZ(pthread_mutex_unlock(&global_mtx));
    break;
  case VCL_EVENT_USE:
    AZ(pthread_mutex_lock(&global_mtx));
    CAST_OBJ_NOTNULL(vd, priv->priv, VMOD_DISCO_MAGIC);
    if (vd != default_mod)
      default_mod = vd;
    AZ(pthread_mutex_unlock(&global_mtx));
  default:
    break;
  }
  return 0;
}
void
smp_mgt_init(struct stevedore *parent, int ac, char * const *av)
{
	struct smp_sc		*sc;
	struct smp_sign		sgn;
	void *target;
	int i;

	ASSERT_MGT();

	AZ(av[ac]);

	/* Necessary alignment. See also smp_object::__filler__ */
	assert(sizeof(struct smp_object) % 8 == 0);

#define SIZOF(foo)       fprintf(stderr, \
    "sizeof(%s) = %zu = 0x%zx\n", #foo, sizeof(foo), sizeof(foo));
	SIZOF(struct smp_ident);
	SIZOF(struct smp_sign);
	SIZOF(struct smp_segptr);
	SIZOF(struct smp_object);
#undef SIZOF

	/* See comments in storage_persistent.h */
	assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE);

	/* Allocate softc */
	ALLOC_OBJ(sc, SMP_SC_MAGIC);
	XXXAN(sc);
	sc->parent = parent;
	sc->fd = -1;
	VTAILQ_INIT(&sc->segments);

	/* Argument processing */
	if (ac != 2)
		ARGV_ERR("(-spersistent) wrong number of arguments\n");

	i = STV_GetFile(av[0], &sc->fd, &sc->filename, "-spersistent");
	if (i == 2)
		ARGV_ERR("(-spersistent) need filename (not directory)\n");

	sc->align = sizeof(void*) * 2;
	sc->granularity = getpagesize();
	sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity,
	    "-spersistent");

	AZ(ftruncate(sc->fd, sc->mediasize));

	/* Try to determine correct mmap address */
	i = read(sc->fd, &sgn, sizeof sgn);
	assert(i == sizeof sgn);
	if (!strcmp(sgn.ident, "SILO"))
		target = (void*)(uintptr_t)sgn.mapped;
	else
		target = NULL;

	sc->base = (void*)mmap(target, sc->mediasize, PROT_READ|PROT_WRITE,
	    MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0);

	if (sc->base == MAP_FAILED)
		ARGV_ERR("(-spersistent) failed to mmap (%s)\n",
		    strerror(errno));

	smp_def_sign(sc, &sc->idn, 0, "SILO");
	sc->ident = SIGN_DATA(&sc->idn);

	i = smp_valid_silo(sc);
	if (i) {
		printf("Warning SILO (%s) not reloaded (reason=%d)\n",
		    sc->filename, i);
		smp_newsilo(sc);
	}
	AZ(smp_valid_silo(sc));

	smp_metrics(sc);

	parent->priv = sc;

	/* XXX: only for sendfile I guess... */
	mgt_child_inherit(sc->fd, "storage_persistent");
}
const char *
BAN_Commit(struct ban_proto *bp)
{
	struct ban  *b, *bi;
	ssize_t ln;
	double t0;

	CHECK_OBJ_NOTNULL(bp, BAN_PROTO_MAGIC);
	AN(bp->vsb);

	if (ban_shutdown)
		return (ban_error(bp, "Shutting down"));

	AZ(VSB_finish(bp->vsb));
	ln = VSB_len(bp->vsb);
	assert(ln >= 0);

	ALLOC_OBJ(b, BAN_MAGIC);
	if (b == NULL)
		return (ban_error(bp, ban_build_err_no_mem));
	VTAILQ_INIT(&b->objcore);

	b->spec = malloc(ln + BANS_HEAD_LEN);
	if (b->spec == NULL) {
		free(b);
		return (ban_error(bp, ban_build_err_no_mem));
	}

	b->flags = bp->flags;

	memset(b->spec, 0, BANS_HEAD_LEN);
	t0 = VTIM_real();
	memcpy(b->spec + BANS_TIMESTAMP, &t0, sizeof t0);
	b->spec[BANS_FLAGS] = b->flags & 0xff;
	memcpy(b->spec + BANS_HEAD_LEN, VSB_data(bp->vsb), ln);
	ln += BANS_HEAD_LEN;
	vbe32enc(b->spec + BANS_LENGTH, ln);

	Lck_Lock(&ban_mtx);
	if (ban_shutdown) {
		/* We could have raced a shutdown */
		Lck_Unlock(&ban_mtx);
		BAN_Free(b);
		return (ban_error(bp, "Shutting down"));
	}
	bi = VTAILQ_FIRST(&ban_head);
	VTAILQ_INSERT_HEAD(&ban_head, b, list);
	ban_start = b;

	VSC_C_main->bans++;
	VSC_C_main->bans_added++;
	VSC_C_main->bans_persisted_bytes += ln;

	if (b->flags & BANS_FLAG_OBJ)
		VSC_C_main->bans_obj++;
	if (b->flags & BANS_FLAG_REQ)
		VSC_C_main->bans_req++;

	if (bi != NULL)
		ban_info_new(b->spec, ln);	/* Notify stevedores */

	if (cache_param->ban_dups) {
		/* Hunt down duplicates, and mark them as completed */
		for (bi = VTAILQ_NEXT(b, list); bi != NULL;
		    bi = VTAILQ_NEXT(bi, list)) {
			if (!(bi->flags & BANS_FLAG_COMPLETED) &&
			    ban_equal(b->spec, bi->spec)) {
				ban_mark_completed(bi);
				VSC_C_main->bans_dups++;
			}
		}
	}
	if (!(b->flags & BANS_FLAG_REQ))
		ban_kick_lurker();
	Lck_Unlock(&ban_mtx);

	BAN_Abandon(bp);
	return (NULL);
}
Beispiel #24
0
struct req *
Req_New(const struct worker *wrk, struct sess *sp)
{
	struct pool *pp;
	struct req *req;
	uint16_t nhttp;
	unsigned sz, hl;
	char *p, *e;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	pp = sp->pool;
	CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);

	req = MPL_Get(pp->mpl_req, &sz);
	AN(req);
	req->magic = REQ_MAGIC;
	req->sp = sp;

	e = (char*)req + sz;
	p = (char*)(req + 1);
	p = (void*)PRNDUP(p);
	assert(p < e);

	nhttp = (uint16_t)cache_param->http_max_hdr;
	hl = HTTP_estimate(nhttp);

	req->http = HTTP_create(p, nhttp, hl);
	p += hl;
	p = (void*)PRNDUP(p);
	assert(p < e);

	req->http0 = HTTP_create(p, nhttp, hl);
	p += hl;
	p = (void*)PRNDUP(p);
	assert(p < e);

	req->resp = HTTP_create(p, nhttp, hl);
	p += hl;
	p = (void*)PRNDUP(p);
	assert(p < e);

	sz = cache_param->vsl_buffer;
	VSL_Setup(req->vsl, p, sz);
	p += sz;
	p = (void*)PRNDUP(p);

	req->vfc = (void*)p;
	INIT_OBJ(req->vfc, VFP_CTX_MAGIC);
	p = (void*)PRNDUP(p + sizeof(*req->vfc));

	req->htc = (void*)p;
	p = (void*)PRNDUP(p + sizeof(*req->htc));

	req->vdc = (void*)p;
	INIT_OBJ(req->vdc, VDP_CTX_MAGIC);
	VTAILQ_INIT(&req->vdc->vdp);
	p = (void*)PRNDUP(p + sizeof(*req->vdc));

	req->htc = (void*)p;
	INIT_OBJ(req->htc, HTTP_CONN_MAGIC);
	p = (void*)PRNDUP(p + sizeof(*req->htc));

	assert(p < e);

	WS_Init(req->ws, "req", p, e - p);

	req->t_first = NAN;
	req->t_prev = NAN;
	req->t_req = NAN;

	req->topreq = req;

	return (req);
}