getservbyport_r: fix wrong result if getnameinfo fails with EAI_OVERFLOW
[musl] / src / thread / sem_post.c
index 31e3293..5c2517f 100644 (file)
@@ -1,17 +1,21 @@
 #include <semaphore.h>
+#include <limits.h>
 #include "pthread_impl.h"
 
 int sem_post(sem_t *sem)
 {
-       int val, waiters, priv = sem->__val[2];
+       int val, new, waiters, priv = sem->__val[2];
        do {
                val = sem->__val[0];
                waiters = sem->__val[1];
-               if (val == SEM_VALUE_MAX) {
+               if ((val & SEM_VALUE_MAX) == SEM_VALUE_MAX) {
                        errno = EOVERFLOW;
                        return -1;
                }
-       } while (a_cas(sem->__val, val, val+1+(val<0)) != val);
-       if (val<0 || waiters) __wake(sem->__val, 1, priv);
+               new = val + 1;
+               if (waiters <= 1)
+                       new &= ~0x80000000;
+       } while (a_cas(sem->__val, val, new) != val);
+       if (val<0) __wake(sem->__val, waiters>1 ? 1 : -1, priv);
        return 0;
 }