static void *
exp_timer(struct sess *sp, void *priv)
{
	struct objcore *oc;
	struct object *o;
	double t;
	struct objcore_head *lru;

	(void)priv;
	AZ(sleep(10));		/* XXX: Takes time for VCL to arrive */
	VCL_Get(&sp->vcl);
	t = TIM_real();
	while (1) {
		Lck_Lock(&exp_mtx);
		oc = binheap_root(exp_heap);
		CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
		if (oc == NULL || oc->timer_when > t) { /* XXX: > or >= ? */
			Lck_Unlock(&exp_mtx);
			WSL_Flush(sp->wrk, 0);
			WRK_SumStat(sp->wrk);
			AZ(sleep(1));
			VCL_Refresh(&sp->vcl);
			t = TIM_real();
			continue;
		}

		o = oc->obj;
		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
		CHECK_OBJ_NOTNULL(o->objhead, OBJHEAD_MAGIC);
		assert(oc->flags & OC_F_ONLRU);
		assert(oc->timer_idx != BINHEAP_NOIDX);
		binheap_delete(exp_heap, oc->timer_idx);
		assert(oc->timer_idx == BINHEAP_NOIDX);
		lru = STV_lru(o->objstore);
		AN(lru);
		VTAILQ_REMOVE(lru, o->objcore, lru_list);
		oc->flags &= ~OC_F_ONLRU;

		{	/* Sanity checking */
			struct objcore *oc2 = binheap_root(exp_heap);
			if (oc2 != NULL) {
				assert(oc2->timer_idx != BINHEAP_NOIDX);
				assert(oc2->timer_when >= oc->timer_when);
			}
		}

		VSL_stats->n_expired++;
		Lck_Unlock(&exp_mtx);
		WSL(sp->wrk, SLT_ExpKill, 0, "%u %d",
		    o->xid, (int)(o->ttl - t));
		HSH_Deref(sp->wrk, &o);
	}
}
vbp_thread(struct worker *wrk, void *priv)
{
	vtim_real now, nxt;
	struct vbp_target *vt;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	AZ(priv);
	Lck_Lock(&vbp_mtx);
	while (1) {
		now = VTIM_real();
		vt = binheap_root(vbp_heap);
		if (vt == NULL) {
			nxt = 8.192 + now;
			(void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
		} else if (vt->due > now) {
			nxt = vt->due;
			vt = NULL;
			(void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
		} else {
			binheap_delete(vbp_heap, vt->heap_idx);
			vt->due = now + vt->interval;
			if (!vt->running) {
				vt->running = 1;
				vt->task.func = vbp_task;
				vt->task.priv = vt;
				if (Pool_Task_Any(&vt->task, TASK_QUEUE_REQ))
					vt->running = 0;
			}
			binheap_insert(vbp_heap, vt);
		}
	}
	NEEDLESS(Lck_Unlock(&vbp_mtx));
	NEEDLESS(return NULL);
}
Beispiel #3
0
void
Waiter_Destroy(struct waiter **wp)
{
	struct waiter *w;

	TAKE_OBJ_NOTNULL(w, wp, WAITER_MAGIC);

	AZ(binheap_root(w->heap));
	AN(w->impl->fini);
	w->impl->fini(w);
	FREE_OBJ(w);
}
Beispiel #4
0
double
Wait_HeapDue(const struct waiter *w, struct waited **wpp)
{
	struct waited *wp;

	wp = binheap_root(w->heap);
	CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
	if (wp == NULL) {
		if (wpp != NULL)
			*wpp = NULL;
		return (0);
	}
	if (wpp != NULL)
		*wpp = wp;
	return(Wait_When(wp));
}
static double
exp_expire(struct exp_priv *ep, double now)
{
	struct objcore *oc;

	CHECK_OBJ_NOTNULL(ep, EXP_PRIV_MAGIC);

	oc = binheap_root(ep->heap);
	if (oc == NULL)
		return (now + 355./113.);
	VSLb(&ep->vsl, SLT_ExpKill, "EXP_expire p=%p e=%.9f f=0x%x", oc,
	    oc->timer_when - now, oc->flags);

	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);

	/* Ready ? */
	if (oc->timer_when > now)
		return (oc->timer_when);

	VSC_C_main->n_expired++;

	Lck_Lock(&ep->mtx);
	if (oc->exp_flags & OC_EF_POSTED) {
		oc->exp_flags |= OC_EF_REMOVE;
		oc = NULL;
	} else {
		oc->exp_flags &= ~OC_EF_REFD;
	}
	Lck_Unlock(&ep->mtx);
	if (oc != NULL) {
		if (!(oc->flags & OC_F_DYING))
			HSH_Kill(oc);

		/* Remove from binheap */
		assert(oc->timer_idx != BINHEAP_NOIDX);
		binheap_delete(ep->heap, oc->timer_idx);
		assert(oc->timer_idx == BINHEAP_NOIDX);

		CHECK_OBJ_NOTNULL(oc->objhead, OBJHEAD_MAGIC);
		VSLb(&ep->vsl, SLT_ExpKill, "EXP_Expired x=%u t=%.0f",
		    ObjGetXID(ep->wrk, oc), EXP_Ttl(NULL, oc) - now);
		ObjSendEvent(ep->wrk, oc, OEV_EXPIRE);
		(void)HSH_DerefObjCore(ep->wrk, &oc, 0);
	}
	return (0);
}