2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Merge branch 'ondrej/add-nanosleep-and-usleep-windows-shims' into 'main'

Add nanosleep and usleep Windows shims

See merge request isc-projects/bind9!4981
This commit is contained in:
Ondřej Surý
2021-05-03 18:25:55 +00:00
13 changed files with 139 additions and 86 deletions

View File

@@ -2060,21 +2060,6 @@ parse_args(bool is_batchfile, int argc, char **argv) {
}
}
#ifdef WIN32
static void
usleep(unsigned int usec) {
HANDLE timer;
LARGE_INTEGER ft;
ft.QuadPart = -(10 * (__int64)usec);
timer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
}
#endif
/*% Main processing routine for mdig */
int
main(int argc, char *argv[]) {

View File

@@ -600,7 +600,7 @@ LIBS="$LIBS $LIBUV_LIBS"
# Those functions are only provided in newer versions of libuv, we'll be emulating them
# for now
AC_CHECK_FUNCS([uv_handle_get_data uv_handle_set_data uv_import uv_udp_connect uv_translate_sys_error])
AC_CHECK_FUNCS([uv_handle_get_data uv_handle_set_data uv_import uv_udp_connect uv_translate_sys_error uv_sleep])
AX_RESTORE_FLAGS([libuv])
# libnghttp2
@@ -1149,8 +1149,6 @@ AC_COMPILE_IFELSE(
#
AC_CHECK_FUNCS([if_nametoindex])
AC_CHECK_FUNCS(nanosleep usleep explicit_bzero)
ISC_ATOMIC_LIBS=""
AC_CHECK_HEADERS(
[stdatomic.h],

View File

@@ -340,21 +340,11 @@ dns_test_closezonemgr(void) {
*/
void
dns_test_nap(uint32_t usec) {
#ifdef HAVE_NANOSLEEP
struct timespec ts;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
nanosleep(&ts, NULL);
#elif HAVE_USLEEP
usleep(usec);
#else /* ifdef HAVE_NANOSLEEP */
/*
* No fractional-second sleep function is available, so we
* round up to the nearest second and sleep instead
*/
sleep((usec / 1000000) + 1);
#endif /* ifdef HAVE_NANOSLEEP */
}
isc_result_t

View File

@@ -512,11 +512,7 @@ isc_nm_destroy(isc_nm_t **mgr0) {
* Wait for the manager to be dereferenced elsewhere.
*/
while (isc_refcount_current(&mgr->references) > 1 && counter++ < 1000) {
#ifdef WIN32
_sleep(10);
#else /* ifdef WIN32 */
usleep(10000);
#endif /* ifdef WIN32 */
uv_sleep(10);
}
#ifdef NETMGR_TRACE
@@ -531,11 +527,7 @@ isc_nm_destroy(isc_nm_t **mgr0) {
* Now just patiently wait
*/
while (isc_refcount_current(&mgr->references) > 1) {
#ifdef WIN32
_sleep(10);
#else /* ifdef WIN32 */
usleep(10000);
#endif /* ifdef WIN32 */
uv_sleep(10);
}
/*

View File

@@ -33,6 +33,10 @@ uv_handle_set_data(uv_handle_t *handle, void *data) {
}
#endif /* ifndef HAVE_UV_HANDLE_SET_DATA */
#ifndef HAVE_UV_SLEEP
#define uv_sleep(msec) usleep(msec * 1000)
#endif
#ifdef HAVE_UV_UDP_CONNECT
#define isc_uv_udp_connect uv_udp_connect
#else

View File

@@ -653,7 +653,7 @@ doh_timeout_recovery(void **state) {
if (atomic_load(&ctimeouts) == 5) {
break;
}
usleep(1000);
isc_test_nap(1000);
}
assert_true(atomic_load(&ctimeouts) == 5);
@@ -717,7 +717,7 @@ doh_connect_thread(isc_threadarg_t arg) {
* errors, to prevent a thundering herd problem.
*/
if (atomic_load(&slowdown)) {
usleep(1000 * workers);
isc_test_nap(1000 * workers);
atomic_store(&slowdown, false);
}
connect_send_request(

View File

@@ -171,19 +171,9 @@ isc_test_end(void) {
*/
void
isc_test_nap(uint32_t usec) {
#ifdef HAVE_NANOSLEEP
struct timespec ts;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
nanosleep(&ts, NULL);
#elif HAVE_USLEEP
usleep(usec);
#else /* ifdef HAVE_NANOSLEEP */
/*
* No fractional-second sleep function is available, so we
* round up to the nearest second and sleep instead
*/
sleep((usec / 1000000) + 1);
#endif /* ifdef HAVE_NANOSLEEP */
}

View File

@@ -137,7 +137,7 @@ static isc_nm_recv_cb_t connect_readcb = NULL;
__r = WAIT_REPEATS; \
} \
__o = __l; \
usleep(T_WAIT); \
isc_test_nap(T_WAIT); \
} while (__r > 0); \
X(v); \
P(__r); \
@@ -606,7 +606,7 @@ connect_thread(isc_threadarg_t arg) {
* start slowing down the connections to prevent the
* thundering herd problem.
*/
usleep((active - workers) * 1000);
isc_test_nap((active - workers) * 1000);
}
connect(connect_nm);
}
@@ -1071,7 +1071,7 @@ udp_half_recv_send(void **state __attribute__((unused))) {
assert_null(listen_sock);
/* Try to send a little while longer */
usleep((esends / 2) * 10000);
isc_test_nap((esends / 2) * 10000);
isc_nm_closedown(connect_nm);
@@ -1519,7 +1519,7 @@ stream_half_recv_send(void **state __attribute__((unused))) {
assert_null(listen_sock);
/* Try to send a little while longer */
usleep((esends / 2) * 10000);
isc_test_nap((esends / 2) * 10000);
isc_nm_closedown(connect_nm);
@@ -1787,7 +1787,7 @@ tcpdns_noresponse(void **state __attribute__((unused))) {
NULL, noop_accept_cb, NULL, 0, 0, NULL, &listen_sock);
if (result != ISC_R_SUCCESS) {
isc_refcount_decrement(&active_cconnects);
usleep(1000);
isc_test_nap(1000);
}
assert_int_equal(result, ISC_R_SUCCESS);
@@ -2073,7 +2073,7 @@ tcpdns_half_recv_send(void **state __attribute__((unused))) {
assert_null(listen_sock);
/* Try to send a little while longer */
usleep((esends / 2) * 10000);
isc_test_nap((esends / 2) * 10000);
isc_nm_closedown(connect_nm);
@@ -2675,7 +2675,7 @@ tlsdns_half_recv_send(void **state __attribute__((unused))) {
assert_null(listen_sock);
/* Try to send a little while longer */
usleep((esends / 2) * 10000);
isc_test_nap((esends / 2) * 10000);
isc_nm_closedown(connect_nm);

View File

@@ -28,6 +28,8 @@
#include <isc/thread.h>
#include <isc/util.h>
#include "isctest.h"
static void
isc_quota_get_set_test(void **state) {
UNUSED(state);
@@ -256,7 +258,7 @@ isc_thread_t g_threads[10 * 100];
static void *
quota_detach(void *quotap) {
isc_quota_t *quota = (isc_quota_t *)quotap;
usleep(10000);
isc_test_nap(10000);
isc_quota_detach(&quota);
return ((isc_threadresult_t)0);
}

View File

@@ -25,25 +25,19 @@
*** POSIX Shims
***/
inline struct tm *
gmtime_r(const time_t *clock, struct tm *result) {
errno_t ret = gmtime_s(result, clock);
if (ret != 0) {
errno = ret;
return (NULL);
}
return (result);
}
struct tm *
gmtime_r(const time_t *clock, struct tm *result);
inline struct tm *
localtime_r(const time_t *clock, struct tm *result) {
errno_t ret = localtime_s(result, clock);
if (ret != 0) {
errno = ret;
return (NULL);
}
return (result);
}
struct tm *
localtime_r(const time_t *clock, struct tm *result);
int
nanosleep(const struct timespec *req, struct timespec *rem);
typedef uint32_t useconds_t;
int
usleep(useconds_t usec);
/***
*** Intervals

View File

@@ -671,6 +671,10 @@ isc_thread_join
isc_thread_setaffinity
isc_thread_setconcurrency
isc_thread_setname
gmtime_r
localtime_r
nanosleep
usleep
isc_time_add
isc_time_compare
isc_time_formatISO8601

View File

@@ -20,6 +20,7 @@
#include <windows.h>
#include <isc/assertions.h>
#include <isc/once.h>
#include <isc/string.h>
#include <isc/time.h>
#include <isc/tm.h>
@@ -543,3 +544,106 @@ isc_time_formatshorttimestamp(const isc_time_t *t, char *buf,
buf[0] = 0;
}
}
/*
* POSIX Shims
*/
struct tm *
gmtime_r(const time_t *clock, struct tm *result) {
errno_t ret = gmtime_s(result, clock);
if (ret != 0) {
errno = ret;
return (NULL);
}
return (result);
}
struct tm *
localtime_r(const time_t *clock, struct tm *result) {
errno_t ret = localtime_s(result, clock);
if (ret != 0) {
errno = ret;
return (NULL);
}
return (result);
}
#define BILLION 1000000000
static isc_once_t nsec_ticks_once = ISC_ONCE_INIT;
static double nsec_ticks = 0;
static void
nsec_ticks_init(void) {
LARGE_INTEGER ticks;
RUNTIME_CHECK(QueryPerformanceFrequency(&ticks) != 0);
nsec_ticks = (double)ticks.QuadPart / 1000000000.0;
RUNTIME_CHECK(nsec_ticks != 0.0);
}
int
nanosleep(const struct timespec *req, struct timespec *rem) {
int_fast64_t sleep_msec;
uint_fast64_t ticks, until;
LARGE_INTEGER before, after;
RUNTIME_CHECK(isc_once_do(&nsec_ticks_once, nsec_ticks_init) ==
ISC_R_SUCCESS);
if (req->tv_nsec < 0 || BILLION <= req->tv_nsec) {
errno = EINVAL;
return (-1);
}
/* Sleep() is not interruptible; there is no remaining delay ever */
if (rem != NULL) {
rem->tv_sec = 0;
rem->tv_nsec = 0;
}
if (req->tv_sec >= 0) {
/*
* For requested delays of one second or more, 15ms resolution
* granularity is sufficient.
*/
Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
return (0);
}
/* Sleep has <-8,8> ms precision, so substract 10 milliseconds */
sleep_msec = (int64_t)req->tv_nsec / 1000000 - 10;
ticks = req->tv_nsec * nsec_ticks;
RUNTIME_CHECK(QueryPerformanceCounter(&before) != 0);
until = before.QuadPart + ticks;
if (sleep_msec > 0) {
Sleep(sleep_msec);
}
while (true) {
LARGE_INTEGER after;
RUNTIME_CHECK(QueryPerformanceCounter(&after) != 0);
if (after.QuadPart >= until) {
break;
}
}
done:
return (0);
}
int
usleep(useconds_t useconds) {
struct timespec req;
req.tv_sec = useconds / 1000000;
req.tv_nsec = (useconds * 1000) % 1000000000;
nanosleep(&req, NULL);
return (0);
}

View File

@@ -893,21 +893,11 @@ ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp) {
*/
void
ns_test_nap(uint32_t usec) {
#ifdef HAVE_NANOSLEEP
struct timespec ts;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
nanosleep(&ts, NULL);
#elif HAVE_USLEEP
usleep(usec);
#else /* ifdef HAVE_NANOSLEEP */
/*
* No fractional-second sleep function is available, so we
* round up to the nearest second and sleep instead
*/
sleep((usec / 1000000) + 1);
#endif /* ifdef HAVE_NANOSLEEP */
}
isc_result_t