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:
@@ -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[]) {
|
||||
|
@@ -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],
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -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
|
||||
|
@@ -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(
|
||||
|
@@ -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 */
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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("a);
|
||||
return ((isc_threadresult_t)0);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user