retry on cas failures in sem_trywait
authorRich Felker <dalias@aerifal.cx>
Tue, 24 Jul 2012 04:51:36 +0000 (00:51 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 24 Jul 2012 04:51:36 +0000 (00:51 -0400)
this seems counter-intuitive since sem_trywait is supposed to just try
once, not wait for the semaphore. however, the retry loop is not a
wait. instead, it's to handle the case where the value changes due to
a simultaneous post or wait from another thread while the semaphore
value remains positive. in such a case, it's absolutely wrong for
sem_trywait to fail with EAGAIN because the semaphore is not busy.

src/thread/sem_trywait.c

index 55d9007..04edf46 100644 (file)
@@ -3,8 +3,8 @@
 
 int sem_trywait(sem_t *sem)
 {
-       int val = sem->__val[0];
-       if (val>0) {
+       int val;
+       while ((val=sem->__val[0]) > 0) {
                int new = val-1-(val==1 && sem->__val[1]);
                if (a_cas(sem->__val, val, new)==val) return 0;
        }