void SES_Delete(struct sess *sp) { struct acct *b = &sp->acct_ses; struct sessmem *sm; static char noaddr[] = "-"; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); sm = sp->mem; CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC); AZ(sp->obj); AZ(sp->vcl); assert(!isnan(b->first)); assert(!isnan(sp->t_end)); if (sp->addr == NULL) sp->addr = noaddr; if (sp->port == NULL) sp->port = noaddr; VSL(SLT_StatSess, sp->id, "%s %s %.0f %ju %ju %ju %ju %ju %ju %ju", sp->addr, sp->port, sp->t_end - b->first, b->sess, b->req, b->pipe, b->pass, b->fetch, b->hdrbytes, b->bodybytes); if (sm->workspace != params->sess_workspace) { free(sm); sm = NULL; } else { /* Clean and prepare for reuse */ ses_setup(sm); Lck_Lock(&ses_mem_mtx); VTAILQ_INSERT_HEAD(&ses_free_mem[1 - ses_qp], sm, list); Lck_Unlock(&ses_mem_mtx); } SES_ClearReqBodyCache(sp); /* Update statistics */ Lck_Lock(&stat_mtx); if (sm == NULL) VSC_C_main->n_sess_mem--; n_sess_rel++; VSC_C_main->n_sess = n_sess_grab - n_sess_rel; Lck_Unlock(&stat_mtx); /* Try to precreate some ses-mem so the acceptor will not have to */ if (VSC_C_main->n_sess_mem < VSC_C_main->n_sess + 10) { sm = ses_sm_alloc(); if (sm != NULL) { ses_setup(sm); Lck_Lock(&ses_mem_mtx); VTAILQ_INSERT_HEAD(&ses_free_mem[1 - ses_qp], sm, list); Lck_Unlock(&ses_mem_mtx); } } }
struct sess * SES_Alloc(void) { struct sess *sp; struct sessmem *sm; sm = ses_sm_alloc(); AN(sm); ses_setup(sm); sp = &sm->sess; sp->sockaddrlen = 0; return (sp); }
struct sess * SES_New(struct worker *wrk, struct sesspool *pp) { struct sessmem *sm; struct sess *sp; int do_alloc; CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC); do_alloc = 0; Lck_Lock(&pp->mtx); sm = VTAILQ_FIRST(&pp->freelist); if (sm != NULL) { VTAILQ_REMOVE(&pp->freelist, sm, list); } else if (pp->nsess < cache_param->max_sess) { pp->nsess++; do_alloc = 1; } wrk->stats.sessmem_free += pp->dly_free_cnt; pp->dly_free_cnt = 0; Lck_Unlock(&pp->mtx); if (do_alloc) { sm = ses_sm_alloc(); if (sm != NULL) { wrk->stats.sessmem_alloc++; sm->pool = pp; ses_setup(sm); } else { wrk->stats.sessmem_fail++; } } else if (sm == NULL) { wrk->stats.sessmem_limit++; } if (sm == NULL) return (NULL); sp = &sm->sess; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); return (sp); }
struct sess * SES_New(void) { struct sessmem *sm; struct sess *sp; assert(pthread_self() == VCA_thread); assert(ses_qp <= 1); sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); if (sm == NULL) { /* * If that queue is empty, flip queues holding the lock * and try the new unlocked queue. */ Lck_Lock(&ses_mem_mtx); ses_qp = 1 - ses_qp; Lck_Unlock(&ses_mem_mtx); sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); } if (sm != NULL) { VTAILQ_REMOVE(&ses_free_mem[ses_qp], sm, list); sp = &sm->sess; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); } else { sm = ses_sm_alloc(); if (sm == NULL) return (NULL); ses_setup(sm); sp = &sm->sess; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); } /* Only updated from the cache acceptor - no lock needed */ n_sess_grab++; SES_ClearReqBodyCache(sp); return (sp); }
struct sess * SES_New(void) { struct sessmem *sm; struct sess *sp; assert(pthread_self() == VCA_thread); assert(ses_qp <= 1); sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); if (sm == NULL) { /* * If that queue is empty, flip queues holding the lock * and try the new unlocked queue. */ Lck_Lock(&ses_mem_mtx); ses_qp = 1 - ses_qp; Lck_Unlock(&ses_mem_mtx); sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); } if (sm != NULL) { VTAILQ_REMOVE(&ses_free_mem[ses_qp], sm, list); sp = &sm->sess; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); } else { sm = ses_sm_alloc(); if (sm == NULL) return (NULL); ses_setup(sm); sp = &sm->sess; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); } VSC_C_main->n_sess++; /* XXX: locking ? */ return (sp); }