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); }
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); }
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); }