]> git.pond.sub.org Git - empserver/commitdiff
Fix lwp_rwlock_unlock() to wake up all readers
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 26 Apr 2009 17:44:34 +0000 (19:44 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 19 Jul 2009 18:11:52 +0000 (14:11 -0400)
It woke up just one.  Bug couldn't bite, because the update never
sleeps, and therefore no reader gets a chance to sleep.

src/lib/lwp/rwlock.c

index aa0fa4fe8f4b06731b624f58561cf07487fe54e1..38c099bd851520326f926e0ec818d56a78bde5a9 100644 (file)
@@ -109,6 +109,7 @@ void
 lwp_rwlock_unlock(struct lwp_rwlock *rwlock)
 {
     struct lwpProc *p;
+    int maxpri;
 
     lwpStatus(LwpCurrent, "unlocking rwlock %s", rwlock->name);
     if (CANT_HAPPEN(rwlock->count == 0))
@@ -121,14 +122,19 @@ lwp_rwlock_unlock(struct lwp_rwlock *rwlock)
     if (rwlock->count == 0 && rwlock->wq.head) {
        p = lwpGetFirst(&rwlock->wq);
        lwpStatus(p, "wake up next writer of rwlock %s", rwlock->name);
+       maxpri = p->pri;
+       lwpReady(p);
     } else if (rwlock->count >= 0 && rwlock->rq.head && !rwlock->wq.head) {
-       p = lwpGetFirst(&rwlock->rq);
-       lwpStatus(p, "wake up next reader of rwlock %s", rwlock->name);
+       maxpri = 0;
+       while ((p = lwpGetFirst(&rwlock->rq))) {
+           lwpStatus(p, "wake up next reader of rwlock %s", rwlock->name);
+           maxpri = MAX(maxpri, p->pri);
+           lwpReady(p);
+       }
     } else
        return;
 
-    lwpReady(p);
-    if (LwpCurrent->pri < p->pri) {
+    if (LwpCurrent->pri < maxpri) {
        lwpStatus(LwpCurrent, "yielding to thread with higher priority");
        lwpYield();
     }