]> sjero.net Git - wget/commitdiff
[svn] New function xsleep that resumes sleeps interrupted by signals
authorhniksic <devnull@localhost>
Mon, 3 Nov 2003 21:57:04 +0000 (13:57 -0800)
committerhniksic <devnull@localhost>
Mon, 3 Nov 2003 21:57:04 +0000 (13:57 -0800)
on systems that support nanosleep.

ChangeLog
configure.in
src/ChangeLog
src/cmpt.c
src/config.h.in
src/mswindows.c
src/retr.c
src/sysdep.h
src/utils.c
src/utils.h

index 708686537baacb32861c7f22c438238ace3d6577..a49627c1a6d3b0d522e7c5b8b6a5a3eb225de3ce 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-11-03  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * configure.in: Check for nanosleep.
+
 2003-03-09  Nicolas Schodet  <contact@ni.fr.eu.org>
 
        * Makefile.in: Fixed bad configure.bat scrdir.
index dd155ec0d93c23d4994df6bd169c19d45716688b..eed67f1e669b98b32dba8c813e51586fa7750643 100644 (file)
@@ -194,7 +194,7 @@ AC_FUNC_MMAP
 AC_CHECK_FUNCS(strdup strstr strcasecmp strncasecmp strpbrk memmove)
 AC_CHECK_FUNCS(gettimeofday mktime strptime strerror snprintf vsnprintf)
 AC_CHECK_FUNCS(select sigblock sigsetjmp signal symlink access isatty)
-AC_CHECK_FUNCS(uname gethostname usleep)
+AC_CHECK_FUNCS(uname gethostname nanosleep usleep)
 
 dnl
 dnl Check if we need to compile in getopt.c.
index 2af36060a8385ff6017da787ca63dfa954d24c80..e507c588a822f2871151f5a4caa5c90a5f623a58 100644 (file)
@@ -1,3 +1,9 @@
+2003-11-03  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * utils.c (xsleep): New function.  Uses nanosleep where available,
+       resuming sleeps interrupted by signals.  Updated callers of sleep
+       and usleep to use xsleep.
+
 2003-11-03  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * ftp-basic.c (ftp_login): Remove shadowing (and bogus)
index ea1f44ae69d5bbc7c2d55a85c4ff9626085f9928..9e78b21aadbbed7b7f73adadf166cfcd5b8f4c48 100644 (file)
@@ -1431,26 +1431,6 @@ const unsigned short int __mon_yday[2][13] =
   };
 #endif
 
-#ifndef HAVE_USLEEP
-#ifndef WINDOWS
-
-/* A simple usleep implementation based on select().  For Unix and
-   Unix-like systems.  */
-
-int
-usleep (unsigned long usec)
-{
-  struct timeval tm;
-  tm.tv_sec = 0;
-  tm.tv_usec = usec;
-  select (0, NULL, NULL, NULL, &tm);
-  return 0;
-}
-
-#endif /* not WINDOWS */
-#endif /* not HAVE_USLEEP */
-
-
 /* Currently unused in Wget.  Uncomment if we start using memmove
    again. */
 #if 0
index c4da0f717811540cde00fde856bc758927355c8c..2ae45ee8d5bd9b95a6161d4fa8933c867668b850 100644 (file)
@@ -191,6 +191,9 @@ char *alloca ();
 /* Define if you have the usleep function.  */
 #undef HAVE_USLEEP
 
+/* Define if you have the nanosleep function.  */
+#undef HAVE_NANOSLEEP
+
 /* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 
index 3f36d2c5ac8118b7dccc0580ce501aeafb8f1a87..36aef00f8317fb33b12554f65bcf58ecfcb82d63 100644 (file)
@@ -74,35 +74,23 @@ static DWORD set_sleep_mode (DWORD mode);
 static DWORD pwr_mode = 0;
 static int windows_nt_p;
 
-#ifndef HAVE_SLEEP
+/* Windows version of xsleep in utils.c.  */
 
-/* Emulation of Unix sleep.  */
-
-unsigned int
-sleep (unsigned seconds)
-{
-  return SleepEx (1000 * seconds, TRUE) ? 0U : 1000 * seconds;
-}
-#endif
-
-#ifndef HAVE_USLEEP
-/* Emulation of Unix usleep().  This has a granularity of
-   milliseconds, but that's ok because:
-
-   a) Wget is only using it with milliseconds [not anymore, but b)
-      still applies];
-
-   b) You can't rely on usleep's granularity anyway.  If a caller
-   expects usleep to respect every microsecond, he's in for a
-   surprise.  */
-
-int
-usleep (unsigned long usec)
+void
+xsleep (double seconds)
 {
-  SleepEx (usec / 1000, TRUE);
-  return 0;
+#ifdef HAVE_USLEEP
+  if (seconds > 1000)
+    {
+      /* Explained in utils.c. */
+      sleep (seconds);
+      seconds -= (long) seconds;
+    }
+  usleep (seconds * 1000000L);
+#else  /* not HAVE_USLEEP */
+  SleepEx (seconds * 1000, FALSE);
+#endif /* not HAVE_USLEEP */
 }
-#endif  /* HAVE_USLEEP */
 
 void
 windows_main_junk (int *argc, char **argv, char **exec_name)
index 637f9316f618a9ab04f6bb7122a7ec2f1133abe7..c3da16417072f1400268443d126fe4428feb9fdb 100644 (file)
@@ -114,7 +114,7 @@ limit_bandwidth (long bytes, double *dltime, struct wget_timer *timer)
               slp, limit_data.chunk_bytes, limit_data.sleep_adjust));
 
       t0 = *dltime;
-      usleep ((unsigned long) (1000 * slp));
+      xsleep (slp / 1000);
       t1 = wtimer_elapsed (timer);
 
       /* Due to scheduling, we probably slept slightly longer (or
@@ -642,9 +642,9 @@ sleep_between_retrievals (int count)
       /* If opt.waitretry is specified and this is a retry, wait for
         COUNT-1 number of seconds, or for opt.waitretry seconds.  */
       if (count <= opt.waitretry)
-       sleep (count - 1);
+       xsleep (count - 1);
       else
-       usleep (1000000L * opt.waitretry);
+       xsleep (opt.waitretry);
     }
   else if (opt.wait)
     {
@@ -652,7 +652,7 @@ sleep_between_retrievals (int count)
        /* If random-wait is not specified, or if we are sleeping
           between retries of the same download, sleep the fixed
           interval.  */
-       usleep (1000000L * opt.wait);
+       xsleep (opt.wait);
       else
        {
          /* Sleep a random amount of time averaging in opt.wait
@@ -661,7 +661,7 @@ sleep_between_retrievals (int count)
          double waitsecs = 2 * opt.wait * random_float ();
          DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
                   opt.wait, waitsecs));
-         usleep (1000000L * waitsecs);
+         xsleep (waitsecs);
        }
     }
 }
index 96c061b99fe9c7ccf03a144af519c498b063b0e4..2c94579501ebb83edcacbca747693f56ca9ed138 100644 (file)
@@ -183,9 +183,6 @@ int snprintf ();
 #ifndef HAVE_VSNPRINTF
 int vsnprintf ();
 #endif
-#ifndef HAVE_USLEEP
-int usleep PARAMS ((unsigned long));
-#endif
 #ifndef HAVE_MEMMOVE
 void *memmove ();
 #endif
index a427e7367706d1c043844e749f85f26c9fe2059a..5b577587f22bb6668d4c8ff596c4d0008284dc41 100644 (file)
@@ -1851,3 +1851,55 @@ run_with_timeout (double timeout, void (*fun) (void *), void *arg)
 }
 #endif /* not WINDOWS */
 #endif /* not USE_SIGNAL_TIMEOUT */
+\f
+#ifndef WINDOWS
+
+/* Sleep the specified amount of seconds.  On machines without
+   nanosleep(), this may sleep shorter if interrupted by signals.  */
+
+void
+xsleep (double seconds)
+{
+#ifdef HAVE_NANOSLEEP
+  /* nanosleep is the preferred interface because it offers high
+     accuracy and, more importantly, because it allows us to reliably
+     restart after having been interrupted by a signal such as
+     SIGWINCH.  */
+  struct timespec sleep, remaining;
+  sleep.tv_sec = (long) seconds;
+  sleep.tv_nsec = 1000000000L * (seconds - (long) seconds);
+  while (nanosleep (&sleep, &remaining) < 0 && errno == EINTR)
+    /* If nanosleep has been interrupted by a signal, adjust the
+       sleeping period and return to sleep.  */
+    sleep = remaining;
+#else  /* not HAVE_NANOSLEEP */
+#ifdef HAVE_USLEEP
+  /* If usleep is available, use it in preference to select.  */
+  if (seconds > 1000)
+    {
+      /* usleep apparently accepts unsigned long, which means it can't
+        sleep longer than ~70 min (35min if signed).  If the period
+        is larger than what usleep can safely handle, use sleep
+        first, then add usleep for subsecond accuracy.  */
+      sleep (seconds);
+      seconds -= (long) seconds;
+    }
+  usleep (seconds * 1000000L);
+#else  /* not HAVE_USLEEP */
+#ifdef HAVE_SELECT
+  struct timeval sleep;
+  sleep.tv_sec = (long) seconds;
+  sleep.tv_usec = 1000000L * (seconds - (long) seconds);
+  select (0, NULL, NULL, NULL, &sleep);
+  /* If select returns -1 and errno is EINTR, it means we were
+     interrupted by a signal.  But without knowing how long we've
+     actually slept, we can't return to sleep.  Using gettimeofday to
+     track sleeps is slow and unreliable due to clock skew.  */
+#else  /* not HAVE_SELECT */
+  sleep (seconds);
+#endif /* not HAVE_SELECT */
+#endif /* not HAVE_USLEEP */
+#endif /* not HAVE_NANOSLEEP */
+}
+
+#endif /* not WINDOWS */
index 3e35e3339cf0a786351c7449f6ad6baf1e1d865d..972d5502debaa68c7c3809ce98b09a53dc8e5c7e 100644 (file)
@@ -121,5 +121,6 @@ int random_number PARAMS ((int));
 double random_float PARAMS ((void));
 
 int run_with_timeout PARAMS ((double, void (*) (void *), void *));
+void xsleep PARAMS ((double));
 
 #endif /* UTILS_H */