[svn] New function xsleep that resumes sleeps interrupted by signals

on systems that support nanosleep.
This commit is contained in:
hniksic 2003-11-03 13:57:04 -08:00
parent 2f2939d23e
commit 8cd9b4cd8a
10 changed files with 86 additions and 55 deletions

View File

@ -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.

View 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.

View 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)

View 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

View 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

View 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)
void
xsleep (double seconds)
{
return SleepEx (1000 * seconds, TRUE) ? 0U : 1000 * seconds;
#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
#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)
{
SleepEx (usec / 1000, TRUE);
return 0;
}
#endif /* HAVE_USLEEP */
void
windows_main_junk (int *argc, char **argv, char **exec_name)

View 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);
}
}
}

View 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

View File

@ -1851,3 +1851,55 @@ run_with_timeout (double timeout, void (*fun) (void *), void *arg)
}
#endif /* not WINDOWS */
#endif /* not USE_SIGNAL_TIMEOUT */
#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 */

View 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 */