summaryrefslogtreecommitdiff
path: root/sem_timedwait.c
diff options
context:
space:
mode:
Diffstat (limited to 'sem_timedwait.c')
-rw-r--r--sem_timedwait.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/sem_timedwait.c b/sem_timedwait.c
index d1d9d37..59fcc18 100644
--- a/sem_timedwait.c
+++ b/sem_timedwait.c
@@ -52,15 +52,18 @@
#include "semaphore.h"
#include "implement.h"
-static inline void
+static void PTW32_CDECL
ptw32_sem_timedwait_cleanup (void * sem)
{
sem_t s = (sem_t) sem;
if (pthread_mutex_lock (&s->lock) == 0)
{
- s->value++;
- ReleaseSemaphore(s->sem, 1, 0);
+ ++s->value;
+ /*
+ * Don't release the W32 sema, it doesn't need adjustment
+ * because it doesn't record the number of waiters.
+ */
(void) pthread_mutex_unlock (&s->lock);
}
}
@@ -202,6 +205,8 @@ sem_timedwait (sem_t * sem, const struct timespec *abstime)
#else /* NEED_SEM */
+ pthread_testcancel();
+
if ((result = pthread_mutex_lock (&s->lock)) == 0)
{
int v = --s->value;
@@ -210,15 +215,21 @@ sem_timedwait (sem_t * sem, const struct timespec *abstime)
if (v < 0)
{
/* Must wait */
- pthread_cleanup_push(ptw32_sem_timedwait_cleanup, s);
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) s);
result = pthreadCancelableTimedWait (s->sem, milliseconds);
/*
- * Restore the semaphore counters if no longer waiting
+ * Restore the semaphore counter 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);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
}
}