]> sourceware.org Git - newlib-cygwin.git/commitdiff
cygwin: simplify pthread timedwait handling
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 3 Aug 2017 17:08:31 +0000 (19:08 +0200)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 3 Aug 2017 17:08:31 +0000 (19:08 +0200)
- 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>
winsup/cygwin/thread.cc
winsup/cygwin/thread.h

index 50760141c660324e8007cffefacb13e12a5f2b6d..c6048534bea9eb3f48d59f2480407c5f217e0524 100644 (file)
@@ -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
index 48fb6fbb93bd8a2dde2151d638e4004a334746ef..9bb8618243d596dae6a1bc7668844fd35168d7a5 100644 (file)
@@ -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 ();
This page took 0.04087 seconds and 5 git commands to generate.