eqlock(): use separate lock to protect eql, fix missing unlock
This commit is contained in:
parent
4b506cd0ae
commit
e9d441fccf
3 changed files with 10 additions and 9 deletions
|
@ -735,7 +735,8 @@ struct Proc
|
|||
int trace; /* process being traced? */
|
||||
|
||||
ulong qpc; /* pc calling last blocking qlock */
|
||||
QLock *eql; /* interruptable eqlock, protected by rlock */
|
||||
QLock *eql; /* interruptable eqlock */
|
||||
Lock eqlock;
|
||||
|
||||
int setargs;
|
||||
|
||||
|
|
|
@ -952,17 +952,18 @@ Pullout:
|
|||
switch(p->state){
|
||||
case Queueing:
|
||||
/* Try and pull out of a eqlock */
|
||||
lock(&p->rlock);
|
||||
lock(&p->eqlock);
|
||||
if(p->state == Queueing && p->eql && p->notepending){
|
||||
Proc *d, *l;
|
||||
QLock *q;
|
||||
|
||||
q = p->eql;
|
||||
if(!canlock(&q->use)){
|
||||
unlock(&p->rlock);
|
||||
unlock(&p->eqlock);
|
||||
sched();
|
||||
goto Pullout;
|
||||
}
|
||||
|
||||
for(l = nil, d = q->head; d; l = d, d = d->qnext)
|
||||
if(d == p){
|
||||
if(l)
|
||||
|
@ -977,9 +978,8 @@ Pullout:
|
|||
break;
|
||||
}
|
||||
unlock(&q->use);
|
||||
break;
|
||||
}
|
||||
unlock(&p->rlock);
|
||||
unlock(&p->eqlock);
|
||||
break;
|
||||
case Rendezvous:
|
||||
/* Try and pull out of a rendezvous */
|
||||
|
|
|
@ -54,9 +54,9 @@ eqlock(QLock *q)
|
|||
up->qpc = getcallerpc(&q);
|
||||
up->state = Queueing;
|
||||
|
||||
lock(&up->rlock);
|
||||
lock(&up->eqlock);
|
||||
up->eql = q;
|
||||
unlock(&up->rlock);
|
||||
unlock(&up->eqlock);
|
||||
|
||||
unlock(&q->use);
|
||||
|
||||
|
@ -129,10 +129,10 @@ qunlock(QLock *q)
|
|||
p = q->head;
|
||||
if(p){
|
||||
if(p->eql){
|
||||
lock(&p->rlock);
|
||||
lock(&p->eqlock);
|
||||
if(p->eql == q)
|
||||
p->eql = 0;
|
||||
unlock(&p->rlock);
|
||||
unlock(&p->eqlock);
|
||||
}
|
||||
q->head = p->qnext;
|
||||
if(q->head == 0)
|
||||
|
|
Loading…
Reference in a new issue