static void * wrk_thread_real(void *priv, unsigned thread_workspace) { struct worker *w, ww; unsigned char ws[thread_workspace]; THR_SetName("cache-worker"); w = &ww; memset(w, 0, sizeof *w); w->magic = WORKER_MAGIC; w->lastused = NAN; AZ(pthread_cond_init(&w->cond, NULL)); WS_Init(w->aws, "wrk", ws, thread_workspace); VSL(SLT_WorkThread, 0, "%p start", w); Pool_Work_Thread(priv, w); AZ(w->pool); VSL(SLT_WorkThread, 0, "%p end", w); if (w->vcl != NULL) VCL_Rel(&w->vcl); AZ(pthread_cond_destroy(&w->cond)); if (w->nvbo != NULL) VBO_Free(&w->nvbo); HSH_Cleanup(w); WRK_SumStat(w); return (NULL); }
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); } }
static void * wrk_thread_real(void *priv, unsigned shm_workspace, unsigned sess_workspace, uint16_t nhttp, unsigned http_space, unsigned siov) { struct worker *w, ww; uint32_t wlog[shm_workspace / 4]; /* XXX: can we trust these to be properly aligned ? */ unsigned char ws[sess_workspace]; unsigned char http0[http_space]; unsigned char http1[http_space]; unsigned char http2[http_space]; struct iovec iov[siov]; struct SHA256Context sha256; THR_SetName("cache-worker"); w = &ww; memset(w, 0, sizeof *w); w->magic = WORKER_MAGIC; w->lastused = NAN; w->wlb = w->wlp = wlog; w->wle = wlog + (sizeof wlog) / 4; w->sha256ctx = &sha256; w->bereq = HTTP_create(http0, nhttp); w->beresp = HTTP_create(http1, nhttp); w->resp = HTTP_create(http2, nhttp); w->wrw.iov = iov; w->wrw.siov = siov; w->wrw.ciov = siov; AZ(pthread_cond_init(&w->cond, NULL)); WS_Init(w->ws, "wrk", ws, sess_workspace); VSL(SLT_WorkThread, 0, "%p start", w); Pool_Work_Thread(priv, w); AZ(w->pool); VSL(SLT_WorkThread, 0, "%p end", w); if (w->vcl != NULL) VCL_Rel(&w->vcl); AZ(pthread_cond_destroy(&w->cond)); HSH_Cleanup(w); WRK_SumStat(w); return (NULL); }
static int cnt_done(struct sess *sp) { double dh, dp, da; int i; struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk = sp->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC); AZ(wrk->obj); AZ(wrk->busyobj); sp->director = NULL; sp->restarts = 0; wrk->busyobj = NULL; SES_Charge(sp); /* If we did an ESI include, don't mess up our state */ if (sp->esi_level > 0) return (1); if (sp->vcl != NULL) { if (wrk->vcl != NULL) VCL_Rel(&wrk->vcl); wrk->vcl = sp->vcl; sp->vcl = NULL; } sp->t_end = W_TIM_real(wrk); WSP(sp, SLT_Debug, "PHK req %.9f resp %.9f end %.9f open %.9f", sp->t_req, sp->t_resp, sp->t_end, sp->t_open); if (sp->xid == 0) { // sp->t_req = sp->t_end; sp->t_resp = sp->t_end; } else { dp = sp->t_resp - sp->t_req; da = sp->t_end - sp->t_resp; dh = sp->t_req - sp->t_open; /* XXX: Add StatReq == StatSess */ /* XXX: Workaround for pipe */ if (sp->fd >= 0) { WSP(sp, SLT_Length, "%ju", (uintmax_t)sp->req_bodybytes); } WSP(sp, SLT_ReqEnd, "%u %.9f %.9f %.9f %.9f %.9f", sp->xid, sp->t_req, sp->t_end, dh, dp, da); } sp->xid = 0; WSL_Flush(wrk, 0); sp->t_open = sp->t_end; sp->t_resp = NAN; sp->req_bodybytes = 0; sp->t_req = NAN; sp->hash_always_miss = 0; sp->hash_ignore_busy = 0; if (sp->fd >= 0 && sp->doclose != NULL) { /* * This is an orderly close of the connection; ditch nolinger * before we close, to get queued data transmitted. */ // XXX: not yet (void)VTCP_linger(sp->fd, 0); SES_Close(sp, sp->doclose); } if (sp->fd < 0) { wrk->stats.sess_closed++; SES_Delete(sp, NULL); return (1); } if (wrk->stats.client_req >= cache_param->wthread_stats_rate) WRK_SumStat(wrk); /* Reset the workspace to the session-watermark */ WS_Reset(sp->ws, sp->ws_ses); WS_Reset(wrk->ws, NULL); i = HTC_Reinit(sp->htc); if (i == 1) { wrk->stats.sess_pipeline++; sp->step = STP_START; return (0); } if (Tlen(sp->htc->rxbuf)) { wrk->stats.sess_readahead++; sp->step = STP_WAIT; return (0); } if (cache_param->session_linger > 0) { wrk->stats.sess_linger++; sp->step = STP_WAIT; return (0); } wrk->stats.sess_herd++; Pool_Wait(sp); return (1); }