summaryrefslogtreecommitdiffstats
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2017-08-03 19:08:31 +0200
committerCorinna Vinschen <corinna@vinschen.de>2017-08-03 19:08:31 +0200
commit68217c3178dc897a6fce97ff99c3c3b07e638c65 (patch)
tree03a694429b631ad7bf68defadf81cf77ad259beb /winsup
parenta346a26790d005f68c21e0b6fffcbf81ea2181da (diff)
downloadcygnal-68217c3178dc897a6fce97ff99c3c3b07e638c65.tar.gz
cygnal-68217c3178dc897a6fce97ff99c3c3b07e638c65.tar.bz2
cygnal-68217c3178dc897a6fce97ff99c3c3b07e638c65.zip
cygwin: simplify pthread timedwait handling
- Introduce inline helper pthread_convert_abstime. It converts an absolute timespec to a Windows LARGE_INTEGER timestamp, depending on the used clock. - Use this function from pthread_cond_timedwait and semaphore::timedwait - Merge semaphore::_wait and semaphore::_timedwait into single _wait method, taking a LARGER_INTEGER timestamp. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/thread.cc123
-rw-r--r--winsup/cygwin/thread.h3
2 files changed, 60 insertions, 66 deletions
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 50760141c..c6048534b 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -2515,6 +2515,41 @@ pthread::resume (pthread_t *thread)
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)
{
@@ -2841,7 +2876,6 @@ extern "C" int
pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{
- struct timespec tp;
LARGE_INTEGER timeout;
pthread_testcancel ();
@@ -2852,34 +2886,10 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
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) {}
@@ -3597,16 +3607,11 @@ semaphore::_trywait ()
}
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:
@@ -3623,38 +3628,11 @@ semaphore::_timedwait (const struct timespec *abstime)
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 ()
{
@@ -3840,13 +3818,30 @@ semaphore::trywait (sem_t *sem)
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
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 48fb6fbb9..9bb861824 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -693,11 +693,10 @@ public:
}
private:
- int _wait ();
void _post ();
int _getvalue (int *sval);
int _trywait ();
- int _timedwait (const struct timespec *abstime);
+ int _wait (PLARGE_INTEGER timeout = NULL);
void _fixup_before_fork ();
void _fixup_after_fork ();