summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/libc/9sys/qlock.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/sys/src/libc/9sys/qlock.c b/sys/src/libc/9sys/qlock.c
index fb2d80238..4f03cd38c 100644
--- a/sys/src/libc/9sys/qlock.c
+++ b/sys/src/libc/9sys/qlock.c
@@ -58,7 +58,6 @@ qlock(QLock *q)
return;
}
-
/* chain into waiting list */
mp = getqlp();
p = q->tail;
@@ -259,17 +258,19 @@ wunlock(RWLock *q)
if(p->state != QueuingR)
abort();
- /* wake waiting readers */
- while(q->head != nil && q->head->state == QueuingR){
- p = q->head;
+ q->writer = 0;
+ do {
+ /* wake waiting readers */
q->head = p->next;
+ if(q->head == nil)
+ q->tail = nil;
q->readers++;
+ unlock(&q->lock);
while((*_rendezvousp)(p, 0) == (void*)~0)
;
- }
- if(q->head == nil)
- q->tail = nil;
- q->writer = 0;
+ lock(&q->lock);
+ p = q->head;
+ } while(p != nil && p->state == QueuingR && q->writer == 0);
unlock(&q->lock);
}