Ignore:
Timestamp:
2009-05-11 09:57:00 (5 years ago)
Author:
Poul-Henning Kamp <phk@…>
Branches:
master, 3.0, 4.0, experimental-ims
Children:
5c0fe1
Parents:
ecca15
git-author:
Poul-Henning Kamp <phk@…> (2009-05-11 09:57:00)
git-committer:
Poul-Henning Kamp <phk@…> (2009-05-11 09:57:00)
Message:

Fix an inconsequential oversight in session management, and prevent it from
happening again:

We optimize session allocation, SES_New(), to minimize the amount
of locking the VCA_thread participates in with flip-flop lists of
free sessions: Allocate from one list, free to the other, flip lists
only when necessary.

This scheme only works if nobody but VCA_thread calls SES_New().

Background worker threads need dummy sessions and thus called into
SES_New() as well.

These calls all happen during startup, so they do in fact not mess
up the locking, but made mockery of a number of very stern comments.

Add SES_Alloc() for such "other uses" and enforce VCA_thread monopoly
with an assert.

git-svn-id:  http://www.varnish-cache.org/svn/trunk/varnish-cache@4069 d4fa192b-c00b-0410-8231-f00ffab90ce4

File:
1 edited

Legend:

Unmodified
Added
Removed
  • bin/varnishd/cache_session.c

    r4c351b r32038a  
    105105/*--------------------------------------------------------------------*/ 
    106106 
    107 struct sess * 
    108 SES_New(const struct sockaddr *addr, unsigned len) 
    109 { 
    110         struct sessmem *sm; 
     107static struct sess * 
     108ses_setup(struct sessmem *sm, const struct sockaddr *addr, unsigned len) 
     109{ 
    111110        struct sess *sp; 
    112111        volatile unsigned u; 
    113112 
    114         /* 
    115          * One of the two queues is unlocked because only one 
    116          * thread ever gets here to empty it. 
    117          */ 
    118         assert(ses_qp <= 1); 
    119         sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); 
    120113        if (sm == NULL) { 
    121114                /* 
    122                  * If that queue is empty, flip queues holding the lock 
    123                  * and try the new unlocked queue. 
    124                  */ 
    125                 Lck_Lock(&ses_mem_mtx); 
    126                 ses_qp = 1 - ses_qp; 
    127                 Lck_Unlock(&ses_mem_mtx); 
    128                 sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); 
    129         } 
    130         if (sm != NULL) { 
    131                 VTAILQ_REMOVE(&ses_free_mem[ses_qp], sm, list); 
    132         } else { 
    133                 /* 
    134                  * If that fails, alloc new one. 
    135                  * 
    136115                 * It is not necessary to lock mem_workspace, but we 
    137116                 * need to cache it locally, to make sure we get a 
     
    179158} 
    180159 
     160/*-------------------------------------------------------------------- 
     161 * Try to recycle an existing session. 
     162 */ 
     163 
     164struct sess * 
     165SES_New(const struct sockaddr *addr, unsigned len) 
     166{ 
     167        struct sessmem *sm; 
     168 
     169        assert(pthread_self() == VCA_thread); 
     170        assert(ses_qp <= 1); 
     171        sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); 
     172        if (sm == NULL) { 
     173                /* 
     174                 * If that queue is empty, flip queues holding the lock 
     175                 * and try the new unlocked queue. 
     176                 */ 
     177                Lck_Lock(&ses_mem_mtx); 
     178                ses_qp = 1 - ses_qp; 
     179                Lck_Unlock(&ses_mem_mtx); 
     180                sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]); 
     181        } 
     182        if (sm != NULL) 
     183                VTAILQ_REMOVE(&ses_free_mem[ses_qp], sm, list); 
     184        return (ses_setup(sm, addr, len)); 
     185} 
     186 
     187/*--------------------------------------------------------------------*/ 
     188 
     189struct sess * 
     190SES_Alloc(const struct sockaddr *addr, unsigned len) 
     191{ 
     192        return (ses_setup(NULL, addr, len)); 
     193} 
     194 
     195/*--------------------------------------------------------------------*/ 
     196 
    181197void 
    182198SES_Delete(struct sess *sp) 
Note: See TracChangeset for help on using the changeset viewer.