OSDN Git Service

* thread.cc (pthread_cond_timedwait): Check abstime for validity
authorcorinna <corinna>
Fri, 5 Aug 2005 11:31:29 +0000 (11:31 +0000)
committercorinna <corinna>
Fri, 5 Aug 2005 11:31:29 +0000 (11:31 +0000)
according to SUSv3.  Rewrite timeout check and waitlength calculation
to avoid overflow problems.

winsup/cygwin/ChangeLog
winsup/cygwin/thread.cc

index a8eec0f..bd28a34 100644 (file)
@@ -1,3 +1,9 @@
+2005-08-05  Corinna Vinschen  <corinna@vinschen.de>
+
+       * thread.cc (pthread_cond_timedwait): Check abstime for validity
+       according to SUSv3.  Rewrite timeout check and waitlength calculation
+       to avoid overflow problems.
+
 2005-08-02  Yitzchak Scott-Thoennes  <sthoenna@efn.org>
 
        * include/sys/termios.h: Define TIOCMBIS and TIOCMBIC.
index ea4f649..03bebb1 100644 (file)
@@ -2615,7 +2615,7 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
                        const struct timespec *abstime)
 {
   struct timeval tv;
-  long waitlength;
+  DWORD waitlength;
 
   myfault efault;
   if (efault.faulted ())
@@ -2623,11 +2623,23 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
 
   pthread_testcancel ();
 
+  /* 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;
+
   gettimeofday (&tv, NULL);
-  waitlength = abstime->tv_sec * 1000 + abstime->tv_nsec / (1000 * 1000);
-  waitlength -= tv.tv_sec * 1000 + tv.tv_usec / 1000;
-  if (waitlength < 0)
+  /* Check for immediate timeout before converting to microseconds, since
+     the resulting value can easily overflow long.  This also allows to
+     evaluate microseconds directly in DWORD. */
+  if (tv.tv_sec > abstime->tv_sec
+      || (tv.tv_sec == abstime->tv_sec
+          && tv.tv_usec > abstime->tv_nsec / 1000))
     return ETIMEDOUT;
+
+  waitlength = (abstime->tv_sec - tv.tv_sec) * 1000;
+  waitlength += (abstime->tv_nsec / 1000 - tv.tv_usec) / 1000;
   return __pthread_cond_dowait (cond, mutex, waitlength);
 }