summaryrefslogtreecommitdiff
path: root/pthread_mutex_timedlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'pthread_mutex_timedlock.c')
-rw-r--r--pthread_mutex_timedlock.c147
1 files changed, 34 insertions, 113 deletions
diff --git a/pthread_mutex_timedlock.c b/pthread_mutex_timedlock.c
index cf929bc..97a625c 100644
--- a/pthread_mutex_timedlock.c
+++ b/pthread_mutex_timedlock.c
@@ -45,15 +45,12 @@
static INLINE int
-ptw32_timed_semwait (sem_t * sem, const struct timespec *abstime)
+ptw32_timed_eventwait (HANDLE event, const struct timespec *abstime)
/*
* ------------------------------------------------------
* DESCRIPTION
- * This function waits on a POSIX semaphore. If the
- * semaphore value is greater than zero, it decreases
- * its value by one. If the semaphore value is zero, then
- * the calling thread (or process) is blocked until it can
- * successfully decrease the value or until abstime.
+ * This function waits on an event until signaled or until
+ * abstime passes.
* If abstime has passed when this routine is called then
* it returns a result to indicate this.
*
@@ -61,25 +58,16 @@ ptw32_timed_semwait (sem_t * sem, const struct timespec *abstime)
* block until it can successfully decrease the value or
* until interrupted by a signal.
*
- * Unlike sem_timedwait(), this routine is not a cancelation point.
- *
- * Unlike sem_timedwait(), this routine is non-cancelable.
+ * This routine is not a cancelation point.
*
* RESULTS
- * 2 abstime has passed already
- * 1 abstime timed out while waiting
- * 0 successfully decreased semaphore,
- * -1 failed, error in errno.
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSYS semaphores are not supported,
- * EINTR the function was interrupted by a signal,
- * EDEADLK a deadlock condition was detected.
+ * 0 successfully signaled,
+ * ETIMEDOUT abstime passed
+ * EINVAL 'event' is not a valid event,
*
* ------------------------------------------------------
*/
{
- int result = 0;
#ifdef NEED_FTIME
@@ -96,9 +84,9 @@ ptw32_timed_semwait (sem_t * sem, const struct timespec *abstime)
DWORD milliseconds;
DWORD status;
- if (sem == NULL)
+ if (event == NULL)
{
- result = EINVAL;
+ return EINVAL;
}
else
{
@@ -156,47 +144,26 @@ ptw32_timed_semwait (sem_t * sem, const struct timespec *abstime)
if (((int) milliseconds) < 0)
{
- return 2;
+ return ETIMEDOUT;
}
}
-#ifdef NEED_SEM
-
- status = WaitForSingleObject ((*sem)->event, milliseconds);
-
-#else /* NEED_SEM */
-
- status = WaitForSingleObject ((*sem)->sem, milliseconds);
-
-#endif
+ status = WaitForSingleObject (event, milliseconds);
if (status == WAIT_OBJECT_0)
{
-
-#ifdef NEED_SEM
-
- ptw32_decrease_semaphore (sem);
-
-#endif /* NEED_SEM */
-
return 0;
}
else if (status == WAIT_TIMEOUT)
{
- return 1;
+ return ETIMEDOUT;
}
else
{
- result = EINVAL;
+ return EINVAL;
}
}
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
return 0;
} /* ptw32_timed_semwait */
@@ -206,7 +173,7 @@ int
pthread_mutex_timedlock (pthread_mutex_t * mutex,
const struct timespec *abstime)
{
- LONG c;
+ int result;
pthread_mutex_t mx;
#ifdef NEED_SEM
@@ -226,8 +193,6 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
*/
if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
{
- int result;
-
if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
{
return (result);
@@ -238,51 +203,28 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
if (mx->kind == PTHREAD_MUTEX_NORMAL)
{
- if ((c = (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 0,
- (PTW32_INTERLOCKED_LONG) -1)) != -1)
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) 1) != 0)
{
- do
+ while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) -1) != 0)
{
- if (c == 1 ||
- (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 1,
- (PTW32_INTERLOCKED_LONG) 0) != -1)
- {
- switch (ptw32_timed_semwait (&mx->wait_sema, abstime))
- {
- case 0: /* We got woken up so try get the lock again. */
- {
- break;
- }
- case 1: /* Timed out. */
- case 2: /* abstime passed before we started to wait. */
- {
- return ETIMEDOUT;
- }
- default:
- {
- return errno;
- }
- }
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
}
- }
- while ((c = (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 1,
- (PTW32_INTERLOCKED_LONG) -1)) != -1);
+ }
}
}
else
{
pthread_t self = pthread_self();
- if ((c = (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 0,
- (PTW32_INTERLOCKED_LONG) -1)) == -1)
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) 1) == 0)
{
mx->recursive_count = 1;
mx->ownerThread = self;
@@ -302,36 +244,15 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
}
else
{
- do
+ while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) -1) != 0)
{
- if (c == 1 ||
- (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 1,
- (PTW32_INTERLOCKED_LONG) 0) != -1)
- {
- switch (ptw32_timed_semwait (&mx->wait_sema, abstime))
- {
- case 0: /* We got woken up so try get the lock again. */
- {
- break;
- }
- case 1: /* Timed out. */
- case 2: /* abstime passed before we started to wait. */
- {
- return ETIMEDOUT;
- }
- default:
- {
- return errno;
- }
- }
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
}
- }
- while ((c = (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 1,
- (PTW32_INTERLOCKED_LONG) -1)) != -1);
+ }
mx->recursive_count = 1;
mx->ownerThread = self;