summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--sem_getvalue.c28
-rw-r--r--sem_post.c4
3 files changed, 21 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 693e04d..8a36181 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2002-06-04 Rob Fanner <rfanner@stonethree.com>
+
+ * sem_getvalue.c (sem_getvalue): The Johnson M. Hart
+ approach didn't work - we are forced to take an
+ intrusive approach. We try to decrement the sema
+ and then immediately release it again to get the
+ value. There is a small probability that this may
+ block other threads, but only momentarily.
+
2002-06-03 Ross Johnson <rpj@digit.ise.canberra.edu.au>
* sem_init.c (sem_init): Initialise Win32 semaphores
diff --git a/sem_getvalue.c b/sem_getvalue.c
index b3033d3..297bc6c 100644
--- a/sem_getvalue.c
+++ b/sem_getvalue.c
@@ -76,6 +76,7 @@ sem_getvalue(sem_t * sem, int * sval)
*/
{
int result = 0;
+ long value;
if ( sem == NULL || *sem == NULL || sval == NULL )
{
@@ -89,27 +90,17 @@ sem_getvalue(sem_t * sem, int * sval)
result = ENOSYS;
#else
- long value = *sval;
-
- /* From "Win32 System Programming - Second Edition"
- * by Johnson M Hart, chapter 9, page 256 :
- *
- * "The release count must be greater than zero, but if it
- * would cause the semaphore count to exceed the maximum,
- * the call will fail, returning FALSE, and the count will
- * remain unchanged. Releasing a semaphore with a large count
- * is a method used to obtain the current count atomically
- * (of course, another thread might change the value immediately)."
- */
-
- if ( ! ReleaseSemaphore( (*sem)->sem, _POSIX_SEM_VALUE_MAX + 1, &value) )
+
+ if ( WaitForSingleObject( (*sem)->sem, 0 ) == WAIT_TIMEOUT )
{
- *sval = value;
+ /* Failed - must be zero. */
+ value = 0;
}
else
{
- /* This should NEVER occur. */
- result = ENOSYS;
+ /* Decremented sema - release it and note the value. */
+ (void) ReleaseSemaphore( (*sem)->sem, 1L, &value );
+ value++;
}
#endif
@@ -121,7 +112,8 @@ sem_getvalue(sem_t * sem, int * sval)
errno = result;
return -1;
}
-
+
+ *sval = value;
return 0;
} /* sem_getvalue */
diff --git a/sem_post.c b/sem_post.c
index afa7533..d055d93 100644
--- a/sem_post.c
+++ b/sem_post.c
@@ -76,7 +76,7 @@ sem_post (sem_t * sem)
if (sem == NULL || *sem == NULL)
{
- result = EINVAL;
+ result = EINVAL;
}
#ifdef NEED_SEM
@@ -90,7 +90,7 @@ sem_post (sem_t * sem)
#endif /* NEED_SEM */
{
- result = EINVAL;
+ result = EINVAL;
}
if (result != 0)