diff options
| author | Lars Ingebrigtsen | 2022-03-04 16:27:10 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-03-04 16:27:10 +0100 |
| commit | cdbc2f9d274a23bcf6cb03046b1e5b4bdcedafb1 (patch) | |
| tree | aef3f6a300ddbfe0a55364f0dc310e27a391dbdc | |
| parent | 345c4c6532d3784eed5acbaea8a78ce3aad071e4 (diff) | |
| download | emacs-cdbc2f9d274a23bcf6cb03046b1e5b4bdcedafb1.tar.gz emacs-cdbc2f9d274a23bcf6cb03046b1e5b4bdcedafb1.zip | |
Add some sleeps to gnutls_try_handshake
* admin/merge-gnulib (GNULIB_MODULES): Add the nanosleep module.
* m4/gnulib-comp.m4 (gl_EARLY):
* lib/gnulib.mk.in: Automatic update.
* m4/nanosleep.m4:
* lib/nanosleep.c: New module.
* nt/mingw-cfg.site (gl_cv_func_free_preserves_errno):
* nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_nanosleep): Omit nanosleep,
since mingw has it.
* src/gnutls.c (gnutls_try_handshake): Add some sleeping to the
busy-wait loop so that we don't use 100% CPU here (bug#32452).
| -rwxr-xr-x | admin/merge-gnulib | 2 | ||||
| -rw-r--r-- | lib/gnulib.mk.in | 13 | ||||
| -rw-r--r-- | lib/nanosleep.c | 195 | ||||
| -rw-r--r-- | m4/gnulib-comp.m4 | 7 | ||||
| -rw-r--r-- | m4/nanosleep.m4 | 139 | ||||
| -rw-r--r-- | nt/gnulib-cfg.mk | 1 | ||||
| -rw-r--r-- | nt/mingw-cfg.site | 3 | ||||
| -rw-r--r-- | src/gnutls.c | 4 |
8 files changed, 363 insertions, 1 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib index fec469c0179..ea3d23686f4 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib | |||
| @@ -40,7 +40,7 @@ GNULIB_MODULES=' | |||
| 40 | getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog | 40 | getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog |
| 41 | ieee754-h ignore-value intprops largefile libgmp lstat | 41 | ieee754-h ignore-value intprops largefile libgmp lstat |
| 42 | manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime | 42 | manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime |
| 43 | nproc nstrftime | 43 | nanosleep nproc nstrftime |
| 44 | pathmax pipe2 pselect pthread_sigmask | 44 | pathmax pipe2 pselect pthread_sigmask |
| 45 | qcopy-acl readlink readlinkat regex | 45 | qcopy-acl readlink readlinkat regex |
| 46 | sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio | 46 | sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio |
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 3a9f5b9818e..3deeca98bef 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in | |||
| @@ -129,6 +129,7 @@ | |||
| 129 | # minmax \ | 129 | # minmax \ |
| 130 | # mkostemp \ | 130 | # mkostemp \ |
| 131 | # mktime \ | 131 | # mktime \ |
| 132 | # nanosleep \ | ||
| 132 | # nproc \ | 133 | # nproc \ |
| 133 | # nstrftime \ | 134 | # nstrftime \ |
| 134 | # pathmax \ | 135 | # pathmax \ |
| @@ -207,6 +208,7 @@ CPP = @CPP@ | |||
| 207 | CPPFLAGS = @CPPFLAGS@ | 208 | CPPFLAGS = @CPPFLAGS@ |
| 208 | CRYPTOLIB = @CRYPTOLIB@ | 209 | CRYPTOLIB = @CRYPTOLIB@ |
| 209 | CXX = @CXX@ | 210 | CXX = @CXX@ |
| 211 | CXXCPP = @CXXCPP@ | ||
| 210 | CXXFLAGS = @CXXFLAGS@ | 212 | CXXFLAGS = @CXXFLAGS@ |
| 211 | CYGWIN_OBJ = @CYGWIN_OBJ@ | 213 | CYGWIN_OBJ = @CYGWIN_OBJ@ |
| 212 | C_SWITCH_MACHINE = @C_SWITCH_MACHINE@ | 214 | C_SWITCH_MACHINE = @C_SWITCH_MACHINE@ |
| @@ -283,6 +285,7 @@ GL_COND_OBJ_MEMPCPY_CONDITION = @GL_COND_OBJ_MEMPCPY_CONDITION@ | |||
| 283 | GL_COND_OBJ_MEMRCHR_CONDITION = @GL_COND_OBJ_MEMRCHR_CONDITION@ | 285 | GL_COND_OBJ_MEMRCHR_CONDITION = @GL_COND_OBJ_MEMRCHR_CONDITION@ |
| 284 | GL_COND_OBJ_MINI_GMP_GNULIB_CONDITION = @GL_COND_OBJ_MINI_GMP_GNULIB_CONDITION@ | 286 | GL_COND_OBJ_MINI_GMP_GNULIB_CONDITION = @GL_COND_OBJ_MINI_GMP_GNULIB_CONDITION@ |
| 285 | GL_COND_OBJ_MKOSTEMP_CONDITION = @GL_COND_OBJ_MKOSTEMP_CONDITION@ | 287 | GL_COND_OBJ_MKOSTEMP_CONDITION = @GL_COND_OBJ_MKOSTEMP_CONDITION@ |
| 288 | GL_COND_OBJ_NANOSLEEP_CONDITION = @GL_COND_OBJ_NANOSLEEP_CONDITION@ | ||
| 286 | GL_COND_OBJ_OPEN_CONDITION = @GL_COND_OBJ_OPEN_CONDITION@ | 289 | GL_COND_OBJ_OPEN_CONDITION = @GL_COND_OBJ_OPEN_CONDITION@ |
| 287 | GL_COND_OBJ_PSELECT_CONDITION = @GL_COND_OBJ_PSELECT_CONDITION@ | 290 | GL_COND_OBJ_PSELECT_CONDITION = @GL_COND_OBJ_PSELECT_CONDITION@ |
| 288 | GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION = @GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION@ | 291 | GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION = @GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION@ |
| @@ -2497,6 +2500,16 @@ EXTRA_libgnu_a_SOURCES += mktime.c | |||
| 2497 | endif | 2500 | endif |
| 2498 | ## end gnulib module mktime-internal | 2501 | ## end gnulib module mktime-internal |
| 2499 | 2502 | ||
| 2503 | ## begin gnulib module nanosleep | ||
| 2504 | ifeq (,$(OMIT_GNULIB_MODULE_nanosleep)) | ||
| 2505 | |||
| 2506 | ifneq (,$(GL_COND_OBJ_NANOSLEEP_CONDITION)) | ||
| 2507 | libgnu_a_SOURCES += nanosleep.c | ||
| 2508 | endif | ||
| 2509 | |||
| 2510 | endif | ||
| 2511 | ## end gnulib module nanosleep | ||
| 2512 | |||
| 2500 | ## begin gnulib module nproc | 2513 | ## begin gnulib module nproc |
| 2501 | ifeq (,$(OMIT_GNULIB_MODULE_nproc)) | 2514 | ifeq (,$(OMIT_GNULIB_MODULE_nproc)) |
| 2502 | 2515 | ||
diff --git a/lib/nanosleep.c b/lib/nanosleep.c new file mode 100644 index 00000000000..446794edc0b --- /dev/null +++ b/lib/nanosleep.c | |||
| @@ -0,0 +1,195 @@ | |||
| 1 | /* Provide a replacement for the POSIX nanosleep function. | ||
| 2 | |||
| 3 | Copyright (C) 1999-2000, 2002, 2004-2022 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* written by Jim Meyering | ||
| 19 | and Bruno Haible for the native Windows part */ | ||
| 20 | |||
| 21 | #include <config.h> | ||
| 22 | |||
| 23 | #include <time.h> | ||
| 24 | |||
| 25 | #include "intprops.h" | ||
| 26 | #include "verify.h" | ||
| 27 | |||
| 28 | #include <stdbool.h> | ||
| 29 | #include <stdio.h> | ||
| 30 | #include <sys/types.h> | ||
| 31 | #include <sys/select.h> | ||
| 32 | #include <signal.h> | ||
| 33 | |||
| 34 | #include <errno.h> | ||
| 35 | |||
| 36 | #include <unistd.h> | ||
| 37 | |||
| 38 | |||
| 39 | enum { BILLION = 1000 * 1000 * 1000 }; | ||
| 40 | |||
| 41 | #if HAVE_BUG_BIG_NANOSLEEP | ||
| 42 | |||
| 43 | int | ||
| 44 | nanosleep (const struct timespec *requested_delay, | ||
| 45 | struct timespec *remaining_delay) | ||
| 46 | # undef nanosleep | ||
| 47 | { | ||
| 48 | /* nanosleep mishandles large sleeps due to internal overflow problems. | ||
| 49 | The worst known case of this is Linux 2.6.9 with glibc 2.3.4, which | ||
| 50 | can't sleep more than 24.85 days (2^31 milliseconds). Similarly, | ||
| 51 | cygwin 1.5.x, which can't sleep more than 49.7 days (2^32 milliseconds). | ||
| 52 | Solve this by breaking the sleep up into smaller chunks. */ | ||
| 53 | |||
| 54 | if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) | ||
| 55 | { | ||
| 56 | errno = EINVAL; | ||
| 57 | return -1; | ||
| 58 | } | ||
| 59 | |||
| 60 | { | ||
| 61 | /* Verify that time_t is large enough. */ | ||
| 62 | verify (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60); | ||
| 63 | const time_t limit = 24 * 24 * 60 * 60; | ||
| 64 | time_t seconds = requested_delay->tv_sec; | ||
| 65 | struct timespec intermediate; | ||
| 66 | intermediate.tv_nsec = requested_delay->tv_nsec; | ||
| 67 | |||
| 68 | while (limit < seconds) | ||
| 69 | { | ||
| 70 | int result; | ||
| 71 | intermediate.tv_sec = limit; | ||
| 72 | result = nanosleep (&intermediate, remaining_delay); | ||
| 73 | seconds -= limit; | ||
| 74 | if (result) | ||
| 75 | { | ||
| 76 | if (remaining_delay) | ||
| 77 | remaining_delay->tv_sec += seconds; | ||
| 78 | return result; | ||
| 79 | } | ||
| 80 | intermediate.tv_nsec = 0; | ||
| 81 | } | ||
| 82 | intermediate.tv_sec = seconds; | ||
| 83 | return nanosleep (&intermediate, remaining_delay); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | #elif defined _WIN32 && ! defined __CYGWIN__ | ||
| 88 | /* Native Windows platforms. */ | ||
| 89 | |||
| 90 | # define WIN32_LEAN_AND_MEAN | ||
| 91 | # include <windows.h> | ||
| 92 | |||
| 93 | /* The Windows API function Sleep() has a resolution of about 15 ms and takes | ||
| 94 | at least 5 ms to execute. We use this function for longer time periods. | ||
| 95 | Additionally, we use busy-looping over short time periods, to get a | ||
| 96 | resolution of about 0.01 ms. In order to measure such short timespans, | ||
| 97 | we use the QueryPerformanceCounter() function. */ | ||
| 98 | |||
| 99 | int | ||
| 100 | nanosleep (const struct timespec *requested_delay, | ||
| 101 | struct timespec *remaining_delay) | ||
| 102 | { | ||
| 103 | static bool initialized; | ||
| 104 | /* Number of performance counter increments per nanosecond, | ||
| 105 | or zero if it could not be determined. */ | ||
| 106 | static double ticks_per_nanosecond; | ||
| 107 | |||
| 108 | if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) | ||
| 109 | { | ||
| 110 | errno = EINVAL; | ||
| 111 | return -1; | ||
| 112 | } | ||
| 113 | |||
| 114 | /* For requested delays of one second or more, 15ms resolution is | ||
| 115 | sufficient. */ | ||
| 116 | if (requested_delay->tv_sec == 0) | ||
| 117 | { | ||
| 118 | if (!initialized) | ||
| 119 | { | ||
| 120 | /* Initialize ticks_per_nanosecond. */ | ||
| 121 | LARGE_INTEGER ticks_per_second; | ||
| 122 | |||
| 123 | if (QueryPerformanceFrequency (&ticks_per_second)) | ||
| 124 | ticks_per_nanosecond = | ||
| 125 | (double) ticks_per_second.QuadPart / 1000000000.0; | ||
| 126 | |||
| 127 | initialized = true; | ||
| 128 | } | ||
| 129 | if (ticks_per_nanosecond) | ||
| 130 | { | ||
| 131 | /* QueryPerformanceFrequency worked. We can use | ||
| 132 | QueryPerformanceCounter. Use a combination of Sleep and | ||
| 133 | busy-looping. */ | ||
| 134 | /* Number of milliseconds to pass to the Sleep function. | ||
| 135 | Since Sleep can take up to 8 ms less or 8 ms more than requested | ||
| 136 | (or maybe more if the system is loaded), we subtract 10 ms. */ | ||
| 137 | int sleep_millis = (int) requested_delay->tv_nsec / 1000000 - 10; | ||
| 138 | /* Determine how many ticks to delay. */ | ||
| 139 | LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond; | ||
| 140 | /* Start. */ | ||
| 141 | LARGE_INTEGER counter_before; | ||
| 142 | if (QueryPerformanceCounter (&counter_before)) | ||
| 143 | { | ||
| 144 | /* Wait until the performance counter has reached this value. | ||
| 145 | We don't need to worry about overflow, because the performance | ||
| 146 | counter is reset at reboot, and with a frequency of 3.6E6 | ||
| 147 | ticks per second 63 bits suffice for over 80000 years. */ | ||
| 148 | LONGLONG wait_until = counter_before.QuadPart + wait_ticks; | ||
| 149 | /* Use Sleep for the longest part. */ | ||
| 150 | if (sleep_millis > 0) | ||
| 151 | Sleep (sleep_millis); | ||
| 152 | /* Busy-loop for the rest. */ | ||
| 153 | for (;;) | ||
| 154 | { | ||
| 155 | LARGE_INTEGER counter_after; | ||
| 156 | if (!QueryPerformanceCounter (&counter_after)) | ||
| 157 | /* QueryPerformanceCounter failed, but succeeded earlier. | ||
| 158 | Should not happen. */ | ||
| 159 | break; | ||
| 160 | if (counter_after.QuadPart >= wait_until) | ||
| 161 | /* The requested time has elapsed. */ | ||
| 162 | break; | ||
| 163 | } | ||
| 164 | goto done; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | } | ||
| 168 | /* Implementation for long delays and as fallback. */ | ||
| 169 | Sleep (requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000); | ||
| 170 | |||
| 171 | done: | ||
| 172 | /* Sleep is not interruptible. So there is no remaining delay. */ | ||
| 173 | if (remaining_delay != NULL) | ||
| 174 | { | ||
| 175 | remaining_delay->tv_sec = 0; | ||
| 176 | remaining_delay->tv_nsec = 0; | ||
| 177 | } | ||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | #else | ||
| 182 | /* Other platforms lacking nanosleep. | ||
| 183 | It's not clear whether these are still practical porting targets. | ||
| 184 | For now, just fall back on pselect. */ | ||
| 185 | |||
| 186 | /* Suspend execution for at least *REQUESTED_DELAY seconds. The | ||
| 187 | *REMAINING_DELAY part isn't implemented yet. */ | ||
| 188 | |||
| 189 | int | ||
| 190 | nanosleep (const struct timespec *requested_delay, | ||
| 191 | struct timespec *remaining_delay) | ||
| 192 | { | ||
| 193 | return pselect (0, NULL, NULL, NULL, requested_delay, NULL); | ||
| 194 | } | ||
| 195 | #endif | ||
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 1d31239d2db..fb5f1b52a43 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 | |||
| @@ -140,6 +140,7 @@ AC_DEFUN([gl_EARLY], | |||
| 140 | # Code from module mktime: | 140 | # Code from module mktime: |
| 141 | # Code from module mktime-internal: | 141 | # Code from module mktime-internal: |
| 142 | # Code from module multiarch: | 142 | # Code from module multiarch: |
| 143 | # Code from module nanosleep: | ||
| 143 | # Code from module nocrash: | 144 | # Code from module nocrash: |
| 144 | # Code from module nproc: | 145 | # Code from module nproc: |
| 145 | # Code from module nstrftime: | 146 | # Code from module nstrftime: |
| @@ -430,6 +431,10 @@ AC_DEFUN([gl_INIT], | |||
| 430 | fi | 431 | fi |
| 431 | gl_TIME_MODULE_INDICATOR([mktime]) | 432 | gl_TIME_MODULE_INDICATOR([mktime]) |
| 432 | gl_MULTIARCH | 433 | gl_MULTIARCH |
| 434 | gl_FUNC_NANOSLEEP | ||
| 435 | gl_CONDITIONAL([GL_COND_OBJ_NANOSLEEP], | ||
| 436 | [test $HAVE_NANOSLEEP = 0 || test $REPLACE_NANOSLEEP = 1]) | ||
| 437 | gl_TIME_MODULE_INDICATOR([nanosleep]) | ||
| 433 | gl_NPROC | 438 | gl_NPROC |
| 434 | gl_FUNC_GNU_STRFTIME | 439 | gl_FUNC_GNU_STRFTIME |
| 435 | gl_PATHMAX | 440 | gl_PATHMAX |
| @@ -1304,6 +1309,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1304 | lib/mkostemp.c | 1309 | lib/mkostemp.c |
| 1305 | lib/mktime-internal.h | 1310 | lib/mktime-internal.h |
| 1306 | lib/mktime.c | 1311 | lib/mktime.c |
| 1312 | lib/nanosleep.c | ||
| 1307 | lib/nproc.c | 1313 | lib/nproc.c |
| 1308 | lib/nproc.h | 1314 | lib/nproc.h |
| 1309 | lib/nstrftime.c | 1315 | lib/nstrftime.c |
| @@ -1456,6 +1462,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1456 | m4/mktime.m4 | 1462 | m4/mktime.m4 |
| 1457 | m4/mode_t.m4 | 1463 | m4/mode_t.m4 |
| 1458 | m4/multiarch.m4 | 1464 | m4/multiarch.m4 |
| 1465 | m4/nanosleep.m4 | ||
| 1459 | m4/nocrash.m4 | 1466 | m4/nocrash.m4 |
| 1460 | m4/nproc.m4 | 1467 | m4/nproc.m4 |
| 1461 | m4/nstrftime.m4 | 1468 | m4/nstrftime.m4 |
diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4 new file mode 100644 index 00000000000..1964b1ea47d --- /dev/null +++ b/m4/nanosleep.m4 | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | # serial 41 | ||
| 2 | |||
| 3 | dnl From Jim Meyering. | ||
| 4 | dnl Check for the nanosleep function. | ||
| 5 | dnl If not found, use the supplied replacement. | ||
| 6 | dnl | ||
| 7 | |||
| 8 | # Copyright (C) 1999-2001, 2003-2022 Free Software Foundation, Inc. | ||
| 9 | |||
| 10 | # This file is free software; the Free Software Foundation | ||
| 11 | # gives unlimited permission to copy and/or distribute it, | ||
| 12 | # with or without modifications, as long as this notice is preserved. | ||
| 13 | |||
| 14 | AC_DEFUN([gl_FUNC_NANOSLEEP], | ||
| 15 | [ | ||
| 16 | AC_REQUIRE([gl_TIME_H_DEFAULTS]) | ||
| 17 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 18 | |||
| 19 | dnl Persuade glibc and Solaris <time.h> to declare nanosleep. | ||
| 20 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 21 | |||
| 22 | AC_CHECK_DECLS_ONCE([alarm]) | ||
| 23 | |||
| 24 | nanosleep_save_libs=$LIBS | ||
| 25 | |||
| 26 | # Solaris 2.5.1 needs -lposix4 to get the nanosleep function. | ||
| 27 | # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4. | ||
| 28 | LIB_NANOSLEEP= | ||
| 29 | AC_SUBST([LIB_NANOSLEEP]) | ||
| 30 | AC_SEARCH_LIBS([nanosleep], [rt posix4], | ||
| 31 | [test "$ac_cv_search_nanosleep" = "none required" || | ||
| 32 | LIB_NANOSLEEP=$ac_cv_search_nanosleep]) | ||
| 33 | if test "x$ac_cv_search_nanosleep" != xno; then | ||
| 34 | dnl The system has a nanosleep function. | ||
| 35 | |||
| 36 | AC_REQUIRE([gl_MULTIARCH]) | ||
| 37 | if test $APPLE_UNIVERSAL_BUILD = 1; then | ||
| 38 | # A universal build on Apple Mac OS X platforms. | ||
| 39 | # The test result would be 'no (mishandles large arguments)' in 64-bit | ||
| 40 | # mode but 'yes' in 32-bit mode. But we need a configuration result that | ||
| 41 | # is valid in both modes. | ||
| 42 | gl_cv_func_nanosleep='no (mishandles large arguments)' | ||
| 43 | fi | ||
| 44 | |||
| 45 | AC_CACHE_CHECK([for working nanosleep], | ||
| 46 | [gl_cv_func_nanosleep], | ||
| 47 | [ | ||
| 48 | AC_RUN_IFELSE( | ||
| 49 | [AC_LANG_SOURCE([[ | ||
| 50 | #include <errno.h> | ||
| 51 | #include <limits.h> | ||
| 52 | #include <signal.h> | ||
| 53 | #include <time.h> | ||
| 54 | #include <unistd.h> | ||
| 55 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) | ||
| 56 | #define TYPE_MAXIMUM(t) \ | ||
| 57 | ((t) (! TYPE_SIGNED (t) \ | ||
| 58 | ? (t) -1 \ | ||
| 59 | : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) | ||
| 60 | |||
| 61 | #if HAVE_DECL_ALARM | ||
| 62 | static void | ||
| 63 | check_for_SIGALRM (int sig) | ||
| 64 | { | ||
| 65 | if (sig != SIGALRM) | ||
| 66 | _exit (1); | ||
| 67 | } | ||
| 68 | #endif | ||
| 69 | |||
| 70 | int | ||
| 71 | main () | ||
| 72 | { | ||
| 73 | static struct timespec ts_sleep; | ||
| 74 | static struct timespec ts_remaining; | ||
| 75 | /* Test for major problems first. */ | ||
| 76 | if (! nanosleep) | ||
| 77 | return 2; | ||
| 78 | ts_sleep.tv_sec = 0; | ||
| 79 | ts_sleep.tv_nsec = 1; | ||
| 80 | #if HAVE_DECL_ALARM | ||
| 81 | { | ||
| 82 | static struct sigaction act; | ||
| 83 | act.sa_handler = check_for_SIGALRM; | ||
| 84 | sigemptyset (&act.sa_mask); | ||
| 85 | sigaction (SIGALRM, &act, NULL); | ||
| 86 | alarm (1); | ||
| 87 | if (nanosleep (&ts_sleep, NULL) != 0) | ||
| 88 | return 3; | ||
| 89 | /* Test for a minor problem: the handling of large arguments. */ | ||
| 90 | ts_sleep.tv_sec = TYPE_MAXIMUM (time_t); | ||
| 91 | ts_sleep.tv_nsec = 999999999; | ||
| 92 | alarm (1); | ||
| 93 | if (nanosleep (&ts_sleep, &ts_remaining) != -1) | ||
| 94 | return 4; | ||
| 95 | if (errno != EINTR) | ||
| 96 | return 5; | ||
| 97 | if (ts_remaining.tv_sec <= TYPE_MAXIMUM (time_t) - 10) | ||
| 98 | return 6; | ||
| 99 | } | ||
| 100 | #else /* A simpler test for native Windows. */ | ||
| 101 | if (nanosleep (&ts_sleep, &ts_remaining) < 0) | ||
| 102 | return 3; | ||
| 103 | #endif | ||
| 104 | return 0; | ||
| 105 | }]])], | ||
| 106 | [gl_cv_func_nanosleep=yes], | ||
| 107 | [case $? in dnl ( | ||
| 108 | 4|5|6) gl_cv_func_nanosleep='no (mishandles large arguments)';; dnl ( | ||
| 109 | *) gl_cv_func_nanosleep=no;; | ||
| 110 | esac], | ||
| 111 | [case "$host_os" in dnl (( | ||
| 112 | linux*) # Guess it halfway works when the kernel is Linux. | ||
| 113 | gl_cv_func_nanosleep='guessing no (mishandles large arguments)' ;; | ||
| 114 | mingw*) # Guess no on native Windows. | ||
| 115 | gl_cv_func_nanosleep='guessing no' ;; | ||
| 116 | *) # If we don't know, obey --enable-cross-guesses. | ||
| 117 | gl_cv_func_nanosleep="$gl_cross_guess_normal" ;; | ||
| 118 | esac | ||
| 119 | ]) | ||
| 120 | ]) | ||
| 121 | case "$gl_cv_func_nanosleep" in | ||
| 122 | *yes) | ||
| 123 | REPLACE_NANOSLEEP=0 | ||
| 124 | ;; | ||
| 125 | *) | ||
| 126 | REPLACE_NANOSLEEP=1 | ||
| 127 | case "$gl_cv_func_nanosleep" in | ||
| 128 | *"mishandles large arguments"*) | ||
| 129 | AC_DEFINE([HAVE_BUG_BIG_NANOSLEEP], [1], | ||
| 130 | [Define to 1 if nanosleep mishandles large arguments.]) | ||
| 131 | ;; | ||
| 132 | esac | ||
| 133 | ;; | ||
| 134 | esac | ||
| 135 | else | ||
| 136 | HAVE_NANOSLEEP=0 | ||
| 137 | fi | ||
| 138 | LIBS=$nanosleep_save_libs | ||
| 139 | ]) | ||
diff --git a/nt/gnulib-cfg.mk b/nt/gnulib-cfg.mk index 4748474f1dc..69119b135e2 100644 --- a/nt/gnulib-cfg.mk +++ b/nt/gnulib-cfg.mk | |||
| @@ -74,3 +74,4 @@ OMIT_GNULIB_MODULE_futimens = true | |||
| 74 | OMIT_GNULIB_MODULE_utimensat = true | 74 | OMIT_GNULIB_MODULE_utimensat = true |
| 75 | OMIT_GNULIB_MODULE_file-has-acl = true | 75 | OMIT_GNULIB_MODULE_file-has-acl = true |
| 76 | OMIT_GNULIB_MODULE_nproc = true | 76 | OMIT_GNULIB_MODULE_nproc = true |
| 77 | OMIT_GNULIB_MODULE_nanosleep = true | ||
diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site index 6ab81e943f1..7ca19cbad06 100644 --- a/nt/mingw-cfg.site +++ b/nt/mingw-cfg.site | |||
| @@ -167,3 +167,6 @@ ac_cv_func_strsignal=no | |||
| 167 | # implementation of 'free' doesn't touch errno, and it emits a | 167 | # implementation of 'free' doesn't touch errno, and it emits a |
| 168 | # compilation warning. | 168 | # compilation warning. |
| 169 | gl_cv_func_free_preserves_errno=yes | 169 | gl_cv_func_free_preserves_errno=yes |
| 170 | # Don't build the Gnulib nanosleep module: it requires W2K or later, | ||
| 171 | # and MinGW does have nanosleep. | ||
| 172 | gl_cv_func_nanosleep=yes | ||
diff --git a/src/gnutls.c b/src/gnutls.c index 3ec38370679..09590ca005c 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -616,6 +616,9 @@ gnutls_try_handshake (struct Lisp_Process *proc) | |||
| 616 | gnutls_session_t state = proc->gnutls_state; | 616 | gnutls_session_t state = proc->gnutls_state; |
| 617 | int ret; | 617 | int ret; |
| 618 | bool non_blocking = proc->is_non_blocking_client; | 618 | bool non_blocking = proc->is_non_blocking_client; |
| 619 | /* Sleep for ten milliseconds when busy-looping in | ||
| 620 | gnutls_handshake. */ | ||
| 621 | struct timespec delay = { 0, 1000 * 1000 * 10 }; | ||
| 619 | 622 | ||
| 620 | if (proc->gnutls_complete_negotiation_p) | 623 | if (proc->gnutls_complete_negotiation_p) |
| 621 | non_blocking = false; | 624 | non_blocking = false; |
| @@ -630,6 +633,7 @@ gnutls_try_handshake (struct Lisp_Process *proc) | |||
| 630 | maybe_quit (); | 633 | maybe_quit (); |
| 631 | if (non_blocking && ret != GNUTLS_E_INTERRUPTED) | 634 | if (non_blocking && ret != GNUTLS_E_INTERRUPTED) |
| 632 | break; | 635 | break; |
| 636 | nanosleep (&delay, NULL); | ||
| 633 | } | 637 | } |
| 634 | 638 | ||
| 635 | proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED; | 639 | proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED; |