return 0;
}
+static inline int
+pthread_convert_abstime (clockid_t clock_id, const struct timespec *abstime,
+ PLARGE_INTEGER timeout)
+{
+ struct timespec tp;
+
+ /* According to SUSv3, the abstime value must be checked for validity. */
+ if (abstime->tv_sec < 0
+ || abstime->tv_nsec < 0
+ || abstime->tv_nsec > 999999999)
+ return EINVAL;
+
+ /* Check for immediate timeout before converting */
+ clock_gettime (clock_id, &tp);
+ if (tp.tv_sec > abstime->tv_sec
+ || (tp.tv_sec == abstime->tv_sec
+ && tp.tv_nsec > abstime->tv_nsec))
+ return ETIMEDOUT;
+
+ timeout->QuadPart = abstime->tv_sec * NSPERSEC
+ + (abstime->tv_nsec + 99LL) / 100LL;
+ switch (clock_id)
+ {
+ case CLOCK_REALTIME:
+ timeout->QuadPart += FACTOR;
+ break;
+ default:
+ /* other clocks must be handled as relative timeout */
+ timeout->QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
+ timeout->QuadPart *= -1LL;
+ break;
+ }
+ return 0;
+}
+
extern "C" int
pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
{
pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{
- struct timespec tp;
LARGE_INTEGER timeout;
pthread_testcancel ();
if (err)
return err;
- /* According to SUSv3, the abstime value must be checked for validity. */
- if (abstime->tv_sec < 0
- || abstime->tv_nsec < 0
- || abstime->tv_nsec > 999999999)
- __leave;
-
- clock_gettime ((*cond)->clock_id, &tp);
-
- /* Check for immediate timeout before converting */
- if (tp.tv_sec > abstime->tv_sec
- || (tp.tv_sec == abstime->tv_sec
- && tp.tv_nsec > abstime->tv_nsec))
- return ETIMEDOUT;
-
- timeout.QuadPart = abstime->tv_sec * NSPERSEC
- + (abstime->tv_nsec + 99LL) / 100LL;
+ err = pthread_convert_abstime ((*cond)->clock_id, abstime, &timeout);
+ if (err)
+ return err;
- switch ((*cond)->clock_id)
- {
- case CLOCK_REALTIME:
- timeout.QuadPart += FACTOR;
- break;
- default:
- /* other clocks must be handled as relative timeout */
- timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
- timeout.QuadPart *= -1LL;
- break;
- }
return (*cond)->wait (*mutex, &timeout);
}
__except (NO_ERROR) {}
}
int
-semaphore::_timedwait (const struct timespec *abstime)
+semaphore::_wait (PLARGE_INTEGER timeout)
{
- LARGE_INTEGER timeout;
-
__try
{
- timeout.QuadPart = abstime->tv_sec * NSPERSEC
- + (abstime->tv_nsec + 99) / 100 + FACTOR;
-
- switch (cygwait (win32_obj_id, &timeout,
+ switch (cygwait (win32_obj_id, timeout,
cw_cancel | cw_cancel_self | cw_sig_eintr))
{
case WAIT_OBJECT_0:
return -1;
}
}
- __except (NO_ERROR)
- {
- /* According to SUSv3, abstime need not be checked for validity,
- if the semaphore can be locked immediately. */
- if (_trywait ())
- {
- set_errno (EINVAL);
- return -1;
- }
- }
+ __except (NO_ERROR) {}
__endtry
return 0;
}
-int
-semaphore::_wait ()
-{
- switch (cygwait (win32_obj_id, cw_infinite,
- cw_cancel | cw_cancel_self | cw_sig_eintr))
- {
- case WAIT_OBJECT_0:
- break;
- case WAIT_SIGNALED:
- set_errno (EINTR);
- return -1;
- default:
- pthread_printf ("cygwait failed. %E");
- break;
- }
- return 0;
-}
-
void
semaphore::_fixup_before_fork ()
{
int
semaphore::timedwait (sem_t *sem, const struct timespec *abstime)
{
+ LARGE_INTEGER timeout;
+
if (!is_good_object (sem))
{
set_errno (EINVAL);
return -1;
}
- return (*sem)->_timedwait (abstime);
+ /* According to SUSv3, abstime need not be checked for validity,
+ if the semaphore can be locked immediately. */
+ if (!(*sem)->_trywait ())
+ return 0;
+
+ __try
+ {
+ int err = pthread_convert_abstime (CLOCK_REALTIME, abstime, &timeout);
+ if (err)
+ return err;
+
+ return (*sem)->_wait (&timeout);
+ }
+ __except (NO_ERROR) {}
+ __endtry
+ return EINVAL;
}
int