From cccaf0c2c82e78a72d69a4a50c872f308bed2f65 Mon Sep 17 00:00:00 2001
From: rpj <rpj>
Date: Sat, 23 Oct 2004 09:15:53 +0000
Subject: Mutex and Semaphore changes - considered alpha for now

---
 ChangeLog       |  6 ++++++
 sem_timedwait.c | 17 +++++++++--------
 sem_wait.c      | 11 +++++++++--
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a933330..303cb65 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-10-23  Ross Johnson  <ross@localhost.localdomain>
+
+	* sem_timedwait.c (ptw32_sem_timedwait_cleanup): Release
+	Win32 semaphore.
+	sem_wait.c (ptw32_sem_wait_cleanup): Likewise.
+
 2004-10-22  Ross Johnson  <rpj at callisto.canberra.edu.au>
 
 	* sem_init.c (sem_init): Introduce a 'lock' element in order to
diff --git a/sem_timedwait.c b/sem_timedwait.c
index 7282a97..d1d9d37 100644
--- a/sem_timedwait.c
+++ b/sem_timedwait.c
@@ -52,7 +52,7 @@
 #include "semaphore.h"
 #include "implement.h"
 
-static void
+static inline void
 ptw32_sem_timedwait_cleanup (void * sem)
 {
   sem_t s = (sem_t) sem;
@@ -60,6 +60,7 @@ ptw32_sem_timedwait_cleanup (void * sem)
   if (pthread_mutex_lock (&s->lock) == 0)
     {
       s->value++;
+      ReleaseSemaphore(s->sem, 1, 0);
       (void) pthread_mutex_unlock (&s->lock);
     }
 }
@@ -211,13 +212,13 @@ sem_timedwait (sem_t * sem, const struct timespec *abstime)
 	      /* Must wait */
               pthread_cleanup_push(ptw32_sem_timedwait_cleanup, s);
 	      result = pthreadCancelableTimedWait (s->sem, milliseconds);
-              pthread_cleanup_pop(0);
-	      if (result != 0
-		  && pthread_mutex_lock (&s->lock) == 0)
-		{
-		  s->value++;
-		  (void) pthread_mutex_unlock (&s->lock);
-		}
+	      /*
+	       * Restore the semaphore counters if no longer waiting
+	       * and not taking the semaphore. This will occur if the
+	       * thread is cancelled while waiting, or the wake was
+	       * not the result of a post event given to us, e.g. a timeout.
+	       */
+              pthread_cleanup_pop(result);
 	    }
 	}
 
diff --git a/sem_wait.c b/sem_wait.c
index 5142172..cead2cd 100644
--- a/sem_wait.c
+++ b/sem_wait.c
@@ -45,7 +45,7 @@
 #include "semaphore.h"
 #include "implement.h"
 
-static void
+static inline void
 ptw32_sem_wait_cleanup(void * sem)
 {
   sem_t s = (sem_t) sem;
@@ -53,6 +53,7 @@ ptw32_sem_wait_cleanup(void * sem)
   if (pthread_mutex_lock (&s->lock) == 0)
     {
       s->value++;
+      ReleaseSemaphore(s->sem, 1, 0);
       (void) pthread_mutex_unlock (&s->lock);
     }
 }
@@ -115,7 +116,13 @@ sem_wait (sem_t * sem)
 	      /* Must wait */
 	      pthread_cleanup_push(ptw32_sem_wait_cleanup, s);
 	      result = pthreadCancelableWait (s->sem);
-	      pthread_cleanup_pop(0);
+	      /*
+	       * Restore the semaphore counters if no longer waiting
+	       * and not taking the semaphore. This will occur if the
+	       * thread is cancelled while waiting, or the wake was
+	       * not the result of a post event given to us.
+	       */
+	      pthread_cleanup_pop(result);
 	    }
 	}
      
-- 
cgit v1.2.3