From 7e2e924362df5556ff55ee7e1b8738a05d067ec4 Mon Sep 17 00:00:00 2001 From: rpj Date: Tue, 4 Jun 2002 07:14:57 +0000 Subject: Another attempt to get sem_getvalue working. --- ChangeLog | 9 +++++++++ sem_getvalue.c | 28 ++++++++++------------------ sem_post.c | 4 ++-- 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 + + * 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 * 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) -- cgit v1.2.3