Compare commits

...

4 Commits

Author SHA1 Message Date
Ondřej Surý
5c2eece940 fixup! Add unix/ vs win32/ files to libisc 2020-05-18 14:05:51 +02:00
Ondřej Surý
99a5e99a56 Add unix/ vs win32/ files to libisc 2020-05-18 13:55:08 +02:00
Ondřej Surý
fd39969b51 Extend the IPv6 structure detection to support Windows 2020-05-18 13:47:34 +02:00
Ondřej Surý
ef764b81a8 Unify the pthread, win32 and c11 thread support
Previously, only pthread and Windows thread implementations were
supported.  This commit:

* adds C11 Thread Support library implementation to be used on platforms
  where pthread is not available (the pthread API is superset of C11
  Thread Support library)
* Merges the pthread, C11 and Windows Thread Support into the main
  directory for easier msys2 support
* Fixes the Win32 isc_once implementation to use InitOnceExecuteOnce
  function instead of the custom code
2020-05-18 13:41:15 +02:00
21 changed files with 661 additions and 652 deletions

View File

@@ -85,6 +85,11 @@ AX_BIND9_LIB_VERSION([ns])
AC_USE_SYSTEM_EXTENSIONS
AC_CANONICAL_HOST
build_windows=no
AS_CASE([$host_os],
[mingw*],[build_windows=yes])
AM_CONDITIONAL([WIN32],[test "$build_windows" = "yes"])
#
# Compiler compatibility flags
#
@@ -321,6 +326,7 @@ AC_CHECK_HEADERS([fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sy
# Check for thread local storage
#
AC_CHECK_HEADERS([threads.h])
AC_CHECK_FUNCS([thrd_create mtx_init cnd_init], [AC_DEFINE([HAVE_C11_THREAD_SUPPORT], [1], [Defined if the compiler provides C11 Thread Support library])])
AX_TLS([AS_IF([test "$ac_cv_tls" != "thread_local"],
[AC_DEFINE_UNQUOTED([thread_local], [$ac_cv_tls], [Define if the compiler uses a different keyword than thread_local for TLS variables])])],
[AC_MSG_ERROR([Thread Local Storage support required, update your toolchain to build BIND 9])])
@@ -939,24 +945,40 @@ AM_CONDITIONAL([HAVE_BACKTRACE], [test "$ac_cv_func_backtrace" = "yes"])
#
AC_MSG_CHECKING([for IPv6 structures])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]],
[[
struct sockaddr_in6 sin6;
struct in6_addr in6;
struct in6_pktinfo in6_pi;
struct sockaddr_storage storage;
in6 = in6addr_any;
in6 = in6addr_loopback;
sin6.sin6_scope_id = 0;
return (0);
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_FAILURE([IPv6 support is mandatory])])
[AC_LANG_PROGRAM(
[[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]],
[[
struct sockaddr_in6 sin6;
struct in6_addr in6;
struct in6_pktinfo in6_pi;
struct sockaddr_storage storage;
in6 = in6addr_any;
in6 = in6addr_loopback;
sin6.sin6_scope_id = 0;
return (0);
]])],
[AC_MSG_RESULT([yes])],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <winsock2.h>
]],
[[
struct sockaddr_in6 sin6;
struct in6_addr in6;
struct in6_pktinfo in6_pi;
struct sockaddr_storage storage;
in6 = in6addr_any;
in6 = in6addr_loopback;
sin6.sin6_scope_id = 0;
return (0);
]])],
[AC_MSG_RESULT([winsock2.h])],
[AC_MSG_FAILURE([IPv6 support is mandatory])])])
#
# Allow forcibly disabling TCP Fast Open support as autodetection might yield

View File

@@ -17,6 +17,7 @@ libisc_la_HEADERS = \
include/isc/buffer.h \
include/isc/bufferlist.h \
include/isc/commandline.h \
include/isc/condition.h \
include/isc/counter.h \
include/isc/crc64.h \
include/isc/deprecated.h \
@@ -49,12 +50,14 @@ libisc_la_HEADERS = \
include/isc/md.h \
include/isc/mem.h \
include/isc/meminfo.h \
include/isc/mutex.h \
include/isc/mutexatomic.h \
include/isc/mutexblock.h \
include/isc/netaddr.h \
include/isc/netmgr.h \
include/isc/netscope.h \
include/isc/nonce.h \
include/isc/once.h \
include/isc/os.h \
include/isc/parseint.h \
include/isc/pool.h \
@@ -85,15 +88,33 @@ libisc_la_HEADERS = \
include/isc/symtab.h \
include/isc/task.h \
include/isc/taskpool.h \
include/isc/thread.h \
include/isc/timer.h \
include/isc/tm.h \
include/isc/types.h \
include/isc/utf8.h \
include/isc/util.h \
pthreads/include/isc/condition.h\
pthreads/include/isc/mutex.h \
pthreads/include/isc/once.h \
pthreads/include/isc/thread.h \
include/isc/util.h
if WIN32
libisc_la_HEADERS += \
win32/include/isc/align.h \
win32/include/isc/bind_registry.h \
win32/include/isc/bindevt.h \
win32/include/isc/dir.h \
win32/include/isc/ipv6.h \
win32/include/isc/net.h \
win32/include/isc/netdb.h \
win32/include/isc/ntgroups.h \
win32/include/isc/ntpaths.h \
win32/include/isc/offset.h \
win32/include/isc/stat.h \
win32/include/isc/stdatomic.h \
win32/include/isc/stdtime.h \
win32/include/isc/syslog.h \
win32/include/isc/time.h \
win32/include/isc/win32os.h
else WIN32
libisc_la_HEADERS += \
unix/include/isc/align.h \
unix/include/isc/dir.h \
unix/include/isc/netdb.h \
@@ -104,6 +125,7 @@ libisc_la_HEADERS = \
unix/include/isc/stdtime.h \
unix/include/isc/syslog.h \
unix/include/isc/time.h
endif WIN32
pk11dir = $(includedir)/pk11
pk11_HEADERS = \
@@ -129,22 +151,6 @@ libisc_la_SOURCES = \
netmgr/uv-compat.c \
netmgr/uv-compat.h \
netmgr/uverr2result.c \
unix/pk11_api.c \
unix/dir.c \
unix/errno.c \
unix/errno2result.c \
unix/file.c \
unix/fsaccess.c \
unix/interfaceiter.c \
unix/meminfo.c \
unix/net.c \
unix/os.c \
unix/resource.c \
unix/socket.c \
unix/stdio.c \
unix/stdtime.c \
unix/syslog.c \
unix/time.c \
pk11.c \
pk11_result.c \
aes.c \
@@ -158,6 +164,7 @@ libisc_la_SOURCES = \
buffer.c \
bufferlist.c \
commandline.c \
condition.c \
counter.c \
crc64.c \
entropy.c \
@@ -177,6 +184,7 @@ libisc_la_SOURCES = \
log.c \
md.c \
mem.c \
mutex.c \
mutexblock.c \
netaddr.c \
netscope.c \
@@ -204,17 +212,58 @@ libisc_la_SOURCES = \
symtab.c \
task.c \
taskpool.c \
thread.c \
timer.c \
tm.c \
utf8.c \
pthreads/condition.c \
pthreads/mutex.c \
pthreads/thread.c \
entropy_private.h \
mem_p.h \
task_p.h \
timer_p.h
if WIN32
libisc_la_SOURCES += \
win32/DLLMain.c \
win32/dir.c \
win32/errno.c \
win32/errno2result.c \
win32/file.c \
win32/fsaccess.c \
win32/interfaceiter.c \
win32/ipv6.c \
win32/meminfo.c \
win32/net.c \
win32/ntgroups.c \
win32/ntpaths.c \
win32/os.c \
win32/pk11_api.c \
win32/resource.c \
win32/socket.c \
win32/stdio.c \
win32/stdtime.c \
win32/syslog.c \
win32/time.c \
win32/win32os.c
else WIN32
libisc_la_SOURCES += \
unix/pk11_api.c \
unix/dir.c \
unix/errno.c \
unix/errno2result.c \
unix/file.c \
unix/fsaccess.c \
unix/interfaceiter.c \
unix/meminfo.c \
unix/net.c \
unix/os.c \
unix/resource.c \
unix/socket.c \
unix/stdio.c \
unix/stdtime.c \
unix/syslog.c \
unix/time.c
endif WIN32
libisc_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(LIBISC_CFLAGS) \

View File

@@ -18,11 +18,11 @@
#include <sys/types.h>
#include <unistd.h>
#ifndef WIN32
#ifndef _WIN32
#include <inttypes.h>
#include <signal.h>
#include <sys/time.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include <isc/app.h>
#include <isc/atomic.h>
@@ -38,11 +38,11 @@
#include <isc/time.h>
#include <isc/util.h>
#ifdef WIN32
#ifdef _WIN32
#include <process.h>
#else /* WIN32 */
#else /* _WIN32 */
#include <pthread.h>
#endif /* WIN32 */
#endif /* _WIN32 */
/*%
* For BIND9 internal applications built with threads, we use a single app
@@ -52,12 +52,12 @@
static isc_thread_t blockedthread;
static atomic_bool is_running;
#ifdef WIN32
#ifdef _WIN32
/*
* We need to remember which thread is the main thread...
*/
static isc_thread_t main_thread;
#endif /* ifdef WIN32 */
#endif /* ifdef _WIN32 */
/*
* The application context of this module.
@@ -65,11 +65,11 @@ static isc_thread_t main_thread;
#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x')
#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC)
#ifdef WIN32
#ifdef _WIN32
#define NUM_EVENTS 2
enum { RELOAD_EVENT, SHUTDOWN_EVENT };
#endif /* WIN32 */
#endif /* _WIN32 */
struct isc_appctx {
unsigned int magic;
@@ -81,17 +81,53 @@ struct isc_appctx {
atomic_bool want_shutdown;
atomic_bool want_reload;
atomic_bool blocked;
#ifdef WIN32
#ifdef _WIN32
HANDLE hEvents[NUM_EVENTS];
#else /* WIN32 */
#else /* _WIN32 */
isc_mutex_t readylock;
isc_condition_t ready;
#endif /* WIN32 */
#endif /* _WIN32 */
};
static isc_appctx_t isc_g_appctx;
#ifndef WIN32
#ifdef _WIN32
/* validate wait return codes... */
inline BOOL
WaitSucceeded(DWORD dwWaitResult, DWORD dwHandleCount) {
return ((dwWaitResult >= WAIT_OBJECT_0) &&
(dwWaitResult < WAIT_OBJECT_0 + dwHandleCount));
}
inline BOOL
WaitAbandoned(DWORD dwWaitResult, DWORD dwHandleCount) {
return ((dwWaitResult >= WAIT_ABANDONED_0) &&
(dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount));
}
inline BOOL
WaitTimeout(DWORD dwWaitResult) {
return (dwWaitResult == WAIT_TIMEOUT);
}
inline BOOL
WaitFailed(DWORD dwWaitResult) {
return (dwWaitResult == WAIT_FAILED);
}
/* compute object indices for waits... */
inline DWORD
WaitSucceededIndex(DWORD dwWaitResult) {
return (dwWaitResult - WAIT_OBJECT_0);
}
inline DWORD
WaitAbandonedIndex(DWORD dwWaitResult) {
return (dwWaitResult - WAIT_ABANDONED_0);
}
#else
static void
handle_signal(int sig, void (*handler)(int)) {
struct sigaction sa;
@@ -106,7 +142,7 @@ handle_signal(int sig, void (*handler)(int)) {
"handle_signal() %d setup: %s", sig, strbuf);
}
}
#endif /* ifndef WIN32 */
#endif /* ifndef _WIN32 */
isc_result_t
isc_app_ctxstart(isc_appctx_t *ctx) {
@@ -118,10 +154,10 @@ isc_app_ctxstart(isc_appctx_t *ctx) {
isc_mutex_init(&ctx->lock);
#ifndef WIN32
#ifndef _WIN32
isc_mutex_init(&ctx->readylock);
isc_condition_init(&ctx->ready);
#endif /* WIN32 */
#endif /* _WIN32 */
ISC_LIST_INIT(ctx->on_run);
@@ -131,7 +167,7 @@ isc_app_ctxstart(isc_appctx_t *ctx) {
atomic_init(&ctx->want_reload, false);
atomic_init(&ctx->blocked, false);
#ifdef WIN32
#ifdef _WIN32
main_thread = GetCurrentThread();
/* Create the reload event in a non-signaled state */
@@ -139,7 +175,7 @@ isc_app_ctxstart(isc_appctx_t *ctx) {
/* Create the shutdown event in a non-signaled state */
ctx->hEvents[SHUTDOWN_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL);
#else /* WIN32 */
#else /* _WIN32 */
int presult;
sigset_t sset;
char strbuf[ISC_STRERRORSIZE];
@@ -176,7 +212,7 @@ isc_app_ctxstart(isc_appctx_t *ctx) {
"isc_app_start() pthread_sigmask: %s", strbuf);
}
#endif /* WIN32 */
#endif /* _WIN32 */
return (ISC_R_SUCCESS);
}
@@ -229,9 +265,9 @@ isc_app_ctxrun(isc_appctx_t *ctx) {
REQUIRE(VALID_APPCTX(ctx));
#ifdef WIN32
#ifdef _WIN32
REQUIRE(main_thread == GetCurrentThread());
#endif /* ifdef WIN32 */
#endif /* ifdef _WIN32 */
if (atomic_compare_exchange_strong_acq_rel(
&ctx->running, &(bool){ false }, true) == true)
@@ -251,14 +287,14 @@ isc_app_ctxrun(isc_appctx_t *ctx) {
UNLOCK(&ctx->lock);
}
#ifndef WIN32
#ifndef _WIN32
/*
* BIND9 internal tools using multiple contexts do not
* rely on signal. */
if (isc_bind9 && ctx != &isc_g_appctx) {
return (ISC_R_SUCCESS);
}
#endif /* WIN32 */
#endif /* _WIN32 */
/*
* There is no danger if isc_app_shutdown() is called before we
@@ -267,7 +303,7 @@ isc_app_ctxrun(isc_appctx_t *ctx) {
* sigwait().
*/
while (atomic_load_acquire(&ctx->want_shutdown) == false) {
#ifdef WIN32
#ifdef _WIN32
DWORD dwWaitResult = WaitForMultipleObjects(
NUM_EVENTS, ctx->hEvents, FALSE, INFINITE);
@@ -289,7 +325,7 @@ isc_app_ctxrun(isc_appctx_t *ctx) {
break;
}
}
#else /* WIN32 */
#else /* _WIN32 */
if (isc_bind9) {
sigset_t sset;
int sig;
@@ -339,7 +375,7 @@ isc_app_ctxrun(isc_appctx_t *ctx) {
UNLOCK(&ctx->readylock);
}
}
#endif /* WIN32 */
#endif /* _WIN32 */
if (atomic_compare_exchange_strong_acq_rel(
&ctx->want_reload, &(bool){ true }, false))
{
@@ -385,9 +421,9 @@ isc_app_ctxshutdown(isc_appctx_t *ctx) {
if (atomic_compare_exchange_strong_acq_rel(&ctx->shutdown_requested,
&(bool){ false }, true))
{
#ifdef WIN32
#ifdef _WIN32
SetEvent(ctx->hEvents[SHUTDOWN_EVENT]);
#else /* WIN32 */
#else /* _WIN32 */
if (isc_bind9 && ctx != &isc_g_appctx) {
/* BIND9 internal, but using multiple contexts */
atomic_store_release(&ctx->want_shutdown, true);
@@ -406,7 +442,7 @@ isc_app_ctxshutdown(isc_appctx_t *ctx) {
atomic_store_release(&ctx->want_shutdown, true);
SIGNAL(&ctx->ready);
}
#endif /* WIN32 */
#endif /* _WIN32 */
}
}
@@ -425,9 +461,9 @@ isc_app_ctxsuspend(isc_appctx_t *ctx) {
* Don't send the reload signal if we're shutting down.
*/
if (atomic_load_acquire(&ctx->shutdown_requested) == false) {
#ifdef WIN32
#ifdef _WIN32
SetEvent(ctx->hEvents[RELOAD_EVENT]);
#else /* WIN32 */
#else /* _WIN32 */
if (isc_bind9 && ctx != &isc_g_appctx) {
/* BIND9 internal, but using multiple contexts */
atomic_store_release(&ctx->want_reload, true);
@@ -446,7 +482,7 @@ isc_app_ctxsuspend(isc_appctx_t *ctx) {
atomic_store_release(&ctx->want_reload, true);
SIGNAL(&ctx->ready);
}
#endif /* WIN32 */
#endif /* _WIN32 */
}
}
@@ -460,10 +496,10 @@ isc_app_ctxfinish(isc_appctx_t *ctx) {
REQUIRE(VALID_APPCTX(ctx));
isc_mutex_destroy(&ctx->lock);
#ifndef WIN32
#ifndef _WIN32
isc_mutex_destroy(&ctx->readylock);
isc_condition_destroy(&ctx->ready);
#endif /* WIN32 */
#endif /* _WIN32 */
}
void
@@ -477,16 +513,16 @@ isc_app_block(void) {
REQUIRE(atomic_compare_exchange_strong_acq_rel(&isc_g_appctx.blocked,
&(bool){ false }, true));
#ifdef WIN32
#ifdef _WIN32
blockedthread = GetCurrentThread();
#else /* WIN32 */
#else /* _WIN32 */
sigset_t sset;
blockedthread = pthread_self();
RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
sigaddset(&sset, SIGINT) == 0 &&
sigaddset(&sset, SIGTERM) == 0);
RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0);
#endif /* WIN32 */
#endif /* _WIN32 */
}
void
@@ -495,9 +531,9 @@ isc_app_unblock(void) {
REQUIRE(atomic_compare_exchange_strong_acq_rel(&isc_g_appctx.blocked,
&(bool){ true }, false));
#ifdef WIN32
#ifdef _WIN32
REQUIRE(blockedthread == GetCurrentThread());
#else /* WIN32 */
#else /* _WIN32 */
REQUIRE(blockedthread == pthread_self());
sigset_t sset;
@@ -505,7 +541,7 @@ isc_app_unblock(void) {
sigaddset(&sset, SIGINT) == 0 &&
sigaddset(&sset, SIGTERM) == 0);
RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0);
#endif /* WIN32 */
#endif /* _WIN32 */
}
isc_result_t

View File

@@ -9,17 +9,116 @@
* information regarding copyright ownership.
*/
#include <inttypes.h>
#include <stdbool.h>
/*! \file */
#include <errno.h>
#include <isc/assertions.h>
#include <isc/condition.h>
#include <isc/error.h>
#include <isc/strerr.h>
#include <isc/thread.h>
#include <isc/string.h>
#include <isc/time.h>
#include <isc/util.h>
#if HAVE_PTHREAD
isc_result_t
isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
int presult;
isc_result_t result;
struct timespec ts;
char strbuf[ISC_STRERRORSIZE];
REQUIRE(c != NULL && m != NULL && t != NULL);
/*
* POSIX defines a timespec's tv_sec as time_t.
*/
result = isc_time_secondsastimet(t, &ts.tv_sec);
/*
* If we have a range error ts.tv_sec is most probably a signed
* 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge.
*/
if (result == ISC_R_RANGE) {
ts.tv_sec = INT_MAX;
} else if (result != ISC_R_SUCCESS) {
return (result);
}
/*!
* POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds
* ensures its return value is < 1 billion, which will fit in a long.
*/
ts.tv_nsec = (long)isc_time_nanoseconds(t);
do {
#if ISC_MUTEX_PROFILE
presult = pthread_cond_timedwait(c, &m->mutex, &ts);
#else /* if ISC_MUTEX_PROFILE */
presult = pthread_cond_timedwait(c, m, &ts);
#endif /* if ISC_MUTEX_PROFILE */
if (presult == 0) {
return (ISC_R_SUCCESS);
}
if (presult == ETIMEDOUT) {
return (ISC_R_TIMEDOUT);
}
} while (presult == EINTR);
strerror_r(presult, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"pthread_cond_timedwait() returned %s", strbuf);
return (ISC_R_UNEXPECTED);
}
#elif HAVE_C11_THREAD_SUPPORT
isc_result_t
isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
int presult;
isc_result_t result;
struct timespec ts;
REQUIRE(c != NULL && m != NULL && t != NULL);
/*
* POSIX defines a timespec's tv_sec as time_t.
*/
result = isc_time_secondsastimet(t, &ts.tv_sec);
/*
* If we have a range error ts.tv_sec is most probably a signed
* 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge.
*/
if (result == ISC_R_RANGE) {
ts.tv_sec = INT_MAX;
} else if (result != ISC_R_SUCCESS) {
return (result);
}
/*!
* POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds
* ensures its return value is < 1 billion, which will fit in a long.
*/
ts.tv_nsec = (long)isc_time_nanoseconds(t);
presult = cnd_timedwait(c, m, &ts);
switch (presult) {
case thrd_success:
return (ISC_R_SUCCESS);
case thrd_timedout:
return (ISC_R_TIMEDOUT);
default:
char strbuf[ISC_STRERRORSIZE];
strerror_r(presult, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"cnd_timedwait() returned %s", strbuf);
return (ISC_R_UNEXPECTED);
}
}
#elif _WIN32
#define LSIGNAL 0
#define LBROADCAST 1
@@ -251,3 +350,5 @@ isc_condition_waituntil(isc_condition_t *cond, isc_mutex_t *mutex,
return (wait(cond, mutex, milliseconds));
}
#endif

View File

@@ -23,6 +23,8 @@
#include <isc/string.h>
#include <isc/types.h>
#if HAVE_PTHREAD
typedef pthread_cond_t isc_condition_t;
#define isc_condition_init(cond) \
@@ -60,3 +62,43 @@ isc_result_t
isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *);
ISC_LANG_ENDDECLS
#elif HAVE_C11_THREAD_SUPPORT
#include <threads.h>
typedef cnd_t isc_condition_t;
#define isc_condition_init(cond) \
switch (cnd_init(cond)) { \
case thrd_success: \
break; \
case thrd_nomem: \
isc_error_fatal(__FILE__, __LINE__, \
"cnd_init failed: Out of memory"); \
default: \
isc_error_fatal(__FILE__, __LINE__, \
"cnd_init failed: Unknown error"); \
}
#define isc_condition_wait(cond, mutex) \
((cnd_wait(cond, mutex) == thrd_success) ? ISC_R_SUCCESS \
: ISC_R_UNEXPECTED)
#define isc_condition_signal(cond) \
((cnd_signal(cond) == thrd_success) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#define isc_condition_broadcast(cond) \
((cnd_broadcast(cond) == thrd_success) ? ISC_R_SUCCESS \
: ISC_R_UNEXPECTED)
#define isc_condition_destroy(cond) cnd_destroy((cond))
ISC_LANG_BEGINDECLS
isc_result_t
isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *);
ISC_LANG_ENDDECLS
#endif

View File

@@ -9,16 +9,28 @@
* information regarding copyright ownership.
*/
#ifndef ISC_MUTEX_H
#define ISC_MUTEX_H 1
#pragma once
/*! \file */
#include <pthread.h>
#include <stdio.h>
#include <isc/lang.h>
#include <isc/result.h> /* for ISC_R_ codes */
#include <isc/result.h>
/*!
* Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When
* enabled, isc_mutex_stats() can be used to print a table showing the
* number of times each type of mutex was locked and the amount of time
* waiting to obtain the lock.
*/
#ifndef ISC_MUTEX_PROFILE
#define ISC_MUTEX_PROFILE 0
#endif /* ifndef ISC_MUTEX_PROFILE */
#if HAVE_PTHREAD
#include <pthread.h>
ISC_LANG_BEGINDECLS
@@ -36,18 +48,6 @@ extern pthread_mutexattr_t isc__mutex_attrs;
#endif /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \
* defined(PTHREAD_MUTEX_ERRORCHECK) */
/* XXX We could do fancier error handling... */
/*!
* Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When
* enabled, isc_mutex_stats() can be used to print a table showing the
* number of times each type of mutex was locked and the amount of time
* waiting to obtain the lock.
*/
#ifndef ISC_MUTEX_PROFILE
#define ISC_MUTEX_PROFILE 0
#endif /* ifndef ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
typedef struct isc_mutexstats isc_mutexstats_t;
@@ -55,59 +55,17 @@ typedef struct {
pthread_mutex_t mutex; /*%< The actual mutex. */
isc_mutexstats_t *stats; /*%< Mutex statistics. */
} isc_mutex_t;
#else /* if ISC_MUTEX_PROFILE */
typedef pthread_mutex_t isc_mutex_t;
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
#define isc_mutex_init(mp) isc_mutex_init_profile((mp), __FILE__, __LINE__)
#else /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
#define isc_mutex_init(mp) isc_mutex_init_errcheck((mp))
#else /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
#define isc_mutex_init(mp) isc__mutex_init((mp), __FILE__, __LINE__)
void
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
#endif /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
#define isc_mutex_lock(mp) isc_mutex_lock_profile((mp), __FILE__, __LINE__)
#else /* if ISC_MUTEX_PROFILE */
#define isc_mutex_lock(mp) \
((pthread_mutex_lock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
#define isc_mutex_init(mp) isc_mutex_init_profile((mp), __FILE__, __LINE__)
#define isc_mutex_lock(mp) isc_mutex_lock_profile((mp), __FILE__, __LINE__)
#define isc_mutex_unlock(mp) isc_mutex_unlock_profile((mp), __FILE__, __LINE__)
#else /* if ISC_MUTEX_PROFILE */
#define isc_mutex_unlock(mp) \
((pthread_mutex_unlock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
#define isc_mutex_trylock(mp) \
((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? ISC_R_SUCCESS \
: ISC_R_LOCKBUSY)
#else /* if ISC_MUTEX_PROFILE */
#define isc_mutex_trylock(mp) \
((pthread_mutex_trylock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
#define isc_mutex_destroy(mp) \
RUNTIME_CHECK(pthread_mutex_destroy((&(mp)->mutex)) == 0)
#else /* if ISC_MUTEX_PROFILE */
#define isc_mutex_destroy(mp) RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
#define isc_mutex_stats(fp) isc_mutex_statsprofile(fp);
#else /* if ISC_MUTEX_PROFILE */
#define isc_mutex_stats(fp)
#endif /* if ISC_MUTEX_PROFILE */
#if ISC_MUTEX_PROFILE
void
isc_mutex_init_profile(isc_mutex_t *mp, const char *_file, int _line);
@@ -122,7 +80,75 @@ isc_mutex_statsprofile(FILE *fp);
void
isc_mutex_init_errcheck(isc_mutex_t *mp);
#endif /* ISC_MUTEX_PROFILE */
#else /* if ISC_MUTEX_PROFILE */
typedef pthread_mutex_t isc_mutex_t;
#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
#define isc_mutex_init(mp) isc_mutex_init_errcheck((mp))
#else /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
#define isc_mutex_init(mp) isc__mutex_init((mp), __FILE__, __LINE__)
void
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
#endif /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
#define isc_mutex_lock(mp) \
((pthread_mutex_lock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#define isc_mutex_unlock(mp) \
((pthread_mutex_unlock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#define isc_mutex_trylock(mp) \
((pthread_mutex_trylock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
#define isc_mutex_destroy(mp) RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)
#define isc_mutex_stats(fp)
#endif /* if ISC_MUTEX_PROFILE */
ISC_LANG_ENDDECLS
#endif /* ISC_MUTEX_H */
#elif HAVE_C11_THREAD_SUPPORT
#include <threads.h>
ISC_LANG_BEGINDECLS
typedef mtx_t isc_mutex_t;
#define isc_mutex_init(mutex) \
switch (mtx_init(mutex, mtx_plain)) { \
case thrd_success: \
break; \
default: \
isc_error_fatal(__FILE__, __LINE__, \
"mtx_init failed: Unexpected error"); \
}
#define isc_mutex_lock(mutex) \
((mtx_lock(mutex) == thrd_success) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#define isc_mutex_unlock(mp) \
((mtx_unlock((mp)) == thrd_success) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#define isc_mutex_trylock(mutex) \
({ \
isc_result_t __ret; \
switch (mtx_trylock(mutex)) { \
case thrd_success: \
__ret = ISC_R_SUCCESS; \
break; \
case thrd_busy: \
__ret = ISC_R_LOCKBUSY; \
break; \
default: \
isc_error_fatal( \
__FILE__, __LINE__, \
"mtx_trylock failed: Unexpected error"); \
} \
__ret; \
})
#define isc_mutex_destroy(mutex) mtx_destroy(mutex)
#define isc_mutex_stats(fp)
ISC_LANG_ENDDECLS
#endif

View File

@@ -9,23 +9,43 @@
* information regarding copyright ownership.
*/
#ifndef ISC_ONCE_H
#define ISC_ONCE_H 1
#pragma once
/*! \file */
#include <pthread.h>
#include <isc/platform.h>
#include <isc/result.h>
#if HAVE_PTHREAD
#include <pthread.h>
typedef pthread_once_t isc_once_t;
#define ISC_ONCE_INIT PTHREAD_ONCE_INIT
/* XXX We could do fancier error handling... */
#define isc_once_do(op, f) \
((pthread_once((op), (f)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
#elif HAVE_C11_THREAD_SUPPORT
#include <threads.h>
typedef once_flag isc_once_t;
#define ISC_ONCE_INIT ONCE_FLAG_INIT
#define isc_once_do(flag, func) (call_once((flag), (func)), ISC_R_SUCCESS)
#elif _WIN32
#include <synchapi.h>
typedef PINIT_ONCE isc_once_t;
#define isc_once_do(flag, func) \
((InitOnceExecuteOnce(flag, func, NULL, NULL) != 0) \
? ISC_R_SUCCESS \
: ISC_R_UNEXPECTED)
#endif /* ISC_ONCE_H */

View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*! \file */
#if HAVE_THREADS_H
#include <threads.h>
#endif
#include <isc/lang.h>
#include <isc/result.h>
#if HAVE_PTHREAD
#include <pthread.h>
#if defined(HAVE_PTHREAD_NP_H)
#include <pthread_np.h>
#endif /* if defined(HAVE_PTHREAD_NP_H) */
ISC_LANG_BEGINDECLS
typedef pthread_t isc_thread_t;
typedef void * isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t);
void
isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
void
isc_thread_join(isc_thread_t thread, isc_threadresult_t *result);
void
isc_thread_setconcurrency(unsigned int level);
void
isc_thread_yield(void);
void
isc_thread_setname(isc_thread_t thread, const char *name);
isc_result_t
isc_thread_setaffinity(int cpu);
#define isc_thread_self (unsigned long)pthread_self
ISC_LANG_ENDDECLS
#elif HAVE_C11_THREAD_SUPPORT
ISC_LANG_BEGINDECLS
typedef thrd_t isc_thread_t;
typedef int isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t);
#define isc_thread_create(func, arg, thr) \
{ \
switch (thrd_create(thr, func, arg)) { \
case thrd_success: \
break; \
case thrd_nomem: \
isc_error_fatal(__FILE__, __LINE__, \
"mtx_init failed: Out of memory"); \
default: \
isc_error_fatal(__FILE__, __LINE__, \
"mtx_init failed: Unexpected error"); \
} \
}
#define isc_thread_join(thr, res) \
{ \
switch (thrd_join(thr, res)) { \
case thrd_success: \
break; \
default: \
isc_error_fatal(__FILE__, __LINE__, \
"mtx_init failed: Unexpected error"); \
} \
}
#define isc_thread_setconcurrency(level)
#define isc_thread_yield(void) thrd_yield()
#define isc_thread_setname(thread, name)
#define isc_thread_setaffinity(cpu)
#define isc_thread_self (uintptr_t) thrd_current
ISC_LANG_ENDDECLS
#elif _WIN32
typedef HANDLE isc_thread_t;
typedef DWORD isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t(WINAPI *isc_threadfunc_t)(isc_threadarg_t);
ISC_LANG_BEGINDECLS
void
isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
void
isc_thread_join(isc_thread_t, isc_threadresult_t *);
#define isc_thread_setconcurrency(level)
#define isc_thread_yield() Sleep(0)
#define isc_thread_setname(thread, name)
#define isc_thread_setaffinity(cpu)
#define isc_thread_self (unsigned long)GetCurrentThreadId
#endif

View File

@@ -24,6 +24,8 @@
#include <isc/string.h>
#include <isc/util.h>
#if HAVE_PTHREAD
#if ISC_MUTEX_PROFILE
/*@{*/
@@ -298,3 +300,9 @@ isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
}
#endif /* if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && \
* !ISC_MUTEX_PROFILE */
#elif HAVE_C11_THREAD_SUPPORT
EMPTY_TRANSLATION_UNIT
#endif

View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <errno.h>
#include <isc/condition.h>
#include <isc/strerr.h>
#include <isc/string.h>
#include <isc/time.h>
#include <isc/util.h>
isc_result_t
isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
int presult;
isc_result_t result;
struct timespec ts;
char strbuf[ISC_STRERRORSIZE];
REQUIRE(c != NULL && m != NULL && t != NULL);
/*
* POSIX defines a timespec's tv_sec as time_t.
*/
result = isc_time_secondsastimet(t, &ts.tv_sec);
/*
* If we have a range error ts.tv_sec is most probably a signed
* 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge.
*/
if (result == ISC_R_RANGE) {
ts.tv_sec = INT_MAX;
} else if (result != ISC_R_SUCCESS) {
return (result);
}
/*!
* POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds
* ensures its return value is < 1 billion, which will fit in a long.
*/
ts.tv_nsec = (long)isc_time_nanoseconds(t);
do {
#if ISC_MUTEX_PROFILE
presult = pthread_cond_timedwait(c, &m->mutex, &ts);
#else /* if ISC_MUTEX_PROFILE */
presult = pthread_cond_timedwait(c, m, &ts);
#endif /* if ISC_MUTEX_PROFILE */
if (presult == 0) {
return (ISC_R_SUCCESS);
}
if (presult == ETIMEDOUT) {
return (ISC_R_TIMEDOUT);
}
} while (presult == EINTR);
strerror_r(presult, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"pthread_cond_timedwait() returned %s", strbuf);
return (ISC_R_UNEXPECTED);
}

View File

@@ -1 +0,0 @@
../../../../.clang-format.headers

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*! \file */
#include <pthread.h>
#if HAVE_THREADS_H
#include <threads.h>
#endif
#if defined(HAVE_PTHREAD_NP_H)
#include <pthread_np.h>
#endif /* if defined(HAVE_PTHREAD_NP_H) */
#include <isc/lang.h>
#include <isc/result.h>
ISC_LANG_BEGINDECLS
typedef pthread_t isc_thread_t;
typedef void * isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t);
void
isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
void
isc_thread_join(isc_thread_t thread, isc_threadresult_t *result);
void
isc_thread_setconcurrency(unsigned int level);
void
isc_thread_yield(void);
void
isc_thread_setname(isc_thread_t thread, const char *name);
isc_result_t
isc_thread_setaffinity(int cpu);
#define isc_thread_self (unsigned long)pthread_self
ISC_LANG_ENDDECLS

View File

@@ -11,6 +11,12 @@
/*! \file */
#include <isc/strerr.h>
#include <isc/thread.h>
#include <isc/util.h>
#if HAVE_PTHREAD
#if defined(HAVE_SCHED_H)
#include <sched.h>
#endif /* if defined(HAVE_SCHED_H) */
@@ -26,10 +32,6 @@
#include <sys/types.h>
#endif /* if defined(HAVE_SYS_PROCSET_H) */
#include <isc/strerr.h>
#include <isc/thread.h>
#include <isc/util.h>
#ifndef THREAD_MINSTACKSIZE
#define THREAD_MINSTACKSIZE (1024U * 1024)
#endif /* ifndef THREAD_MINSTACKSIZE */
@@ -171,3 +173,49 @@ isc_thread_setaffinity(int cpu) {
#endif /* if defined(HAVE_CPUSET_SETAFFINITY) */
return (ISC_R_SUCCESS);
}
#elif HAVE_C11_THREAD_SUPPORT
EMPTY_TRANSLATION_UNIT
#elif _WIN32
#include <process.h>
void
isc_thread_create(isc_threadfunc_t start, isc_threadarg_t arg,
isc_thread_t *threadp) {
isc_thread_t thread;
unsigned int id;
thread = (isc_thread_t)_beginthreadex(NULL, 0, start, arg, 0, &id);
if (thread == NULL) {
char strbuf[ISC_STRERRORSIZE];
strerror_r(errno, strbuf, sizeof(strbuf));
isc_error_fatal(__FILE__, __LINE__, "_beginthreadex failed: %s",
strbuf);
}
*threadp = thread;
return;
}
void
isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) {
DWORD result;
result = WaitForSingleObject(thread, INFINITE);
if (result != WAIT_OBJECT_0) {
isc_error_fatal(__FILE__, __LINE__,
"WaitForSingleObject() != WAIT_OBJECT_0");
}
if (rp != NULL && !GetExitCodeThread(thread, rp)) {
isc_error_fatal(__FILE__, __LINE__,
"GetExitCodeThread() failed: %d",
GetLastError());
}
(void)CloseHandle(thread);
}
#endif

View File

@@ -1,58 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef ISC_CONDITION_H
#define ISC_CONDITION_H 1
#include <windows.h>
#include <isc/lang.h>
#include <isc/mutex.h>
#include <isc/thread.h>
#include <isc/types.h>
typedef struct isc_condition_thread isc_condition_thread_t;
struct isc_condition_thread {
unsigned long th;
HANDLE handle[2];
ISC_LINK(isc_condition_thread_t) link;
};
typedef struct isc_condition {
HANDLE events[2];
unsigned int waiters;
ISC_LIST(isc_condition_thread_t) threadlist;
} isc_condition_t;
ISC_LANG_BEGINDECLS
void
isc_condition_init(isc_condition_t *);
isc_result_t
isc_condition_wait(isc_condition_t *, isc_mutex_t *);
isc_result_t
isc_condition_signal(isc_condition_t *);
isc_result_t
isc_condition_broadcast(isc_condition_t *);
isc_result_t
isc_condition_destroy(isc_condition_t *);
isc_result_t
isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *);
ISC_LANG_ENDDECLS
#endif /* ISC_CONDITION_H */

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef ISC_MUTEX_H
#define ISC_MUTEX_H 1
#include <windows.h>
#include <isc/net.h>
#include <isc/result.h>
typedef CRITICAL_SECTION isc_mutex_t;
/*
* This definition is here since some versions of WINBASE.H
* omits it for some reason.
*/
#if (_WIN32_WINNT < 0x0400)
WINBASEAPI BOOL WINAPI
TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
#endif /* _WIN32_WINNT < 0x0400 */
#define isc_mutex_init(mp) InitializeCriticalSection((mp))
#define isc_mutex_lock(mp) (EnterCriticalSection((mp)), ISC_R_SUCCESS)
#define isc_mutex_unlock(mp) (LeaveCriticalSection((mp)), ISC_R_SUCCESS)
#define isc_mutex_trylock(mp) \
(TryEnterCriticalSection((mp)) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
#define isc_mutex_destroy(mp) (DeleteCriticalSection((mp)))
/*
* This is a placeholder for now since we are not keeping any mutex stats
*/
#define isc_mutex_stats(fp) \
do { \
} while (0)
#endif /* ISC_MUTEX_H */

View File

@@ -1,38 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef ISC_ONCE_H
#define ISC_ONCE_H 1
#include <isc/lang.h>
#include <isc/result.h>
ISC_LANG_BEGINDECLS
typedef struct {
int status;
int counter;
} isc_once_t;
#define ISC_ONCE_INIT_NEEDED 0
#define ISC_ONCE_INIT_DONE 1
#define ISC_ONCE_INIT \
{ \
ISC_ONCE_INIT_NEEDED, 1 \
}
isc_result_t
isc_once_do(isc_once_t *controller, void (*function)(void));
ISC_LANG_ENDDECLS
#endif /* ISC_ONCE_H */

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef ISC_THREAD_H
#define ISC_THREAD_H 1
#include <windows.h>
#include <isc/lang.h>
#include <isc/result.h>
/*
* Inlines to help with wait return checking
*/
/* check handle for NULL and INVALID_HANDLE */
inline BOOL
IsValidHandle(HANDLE hHandle) {
return ((hHandle != NULL) && (hHandle != INVALID_HANDLE_VALUE));
}
/* validate wait return codes... */
inline BOOL
WaitSucceeded(DWORD dwWaitResult, DWORD dwHandleCount) {
return ((dwWaitResult >= WAIT_OBJECT_0) &&
(dwWaitResult < WAIT_OBJECT_0 + dwHandleCount));
}
inline BOOL
WaitAbandoned(DWORD dwWaitResult, DWORD dwHandleCount) {
return ((dwWaitResult >= WAIT_ABANDONED_0) &&
(dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount));
}
inline BOOL
WaitTimeout(DWORD dwWaitResult) {
return (dwWaitResult == WAIT_TIMEOUT);
}
inline BOOL
WaitFailed(DWORD dwWaitResult) {
return (dwWaitResult == WAIT_FAILED);
}
/* compute object indices for waits... */
inline DWORD
WaitSucceededIndex(DWORD dwWaitResult) {
return (dwWaitResult - WAIT_OBJECT_0);
}
inline DWORD
WaitAbandonedIndex(DWORD dwWaitResult) {
return (dwWaitResult - WAIT_ABANDONED_0);
}
typedef HANDLE isc_thread_t;
typedef DWORD isc_threadresult_t;
typedef void * isc_threadarg_t;
typedef isc_threadresult_t(WINAPI *isc_threadfunc_t)(isc_threadarg_t);
#define isc_thread_self (unsigned long)GetCurrentThreadId
ISC_LANG_BEGINDECLS
void
isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
void
isc_thread_join(isc_thread_t, isc_threadresult_t *);
void
isc_thread_setconcurrency(unsigned int level);
void
isc_thread_setname(isc_thread_t, const char *);
isc_result_t
isc_thread_setaffinity(int cpu);
#define isc_thread_yield() Sleep(0)
#define thread_local __declspec(thread)
ISC_LANG_ENDDECLS
#endif /* ISC_THREAD_H */

View File

@@ -65,6 +65,9 @@
<ClInclude Include="..\include\isc\commandline.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\condition.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\counter.h">
<Filter>Library Header Files</Filter>
</ClInclude>
@@ -149,6 +152,9 @@
<ClInclude Include="..\include\isc\meminfo.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\mutex.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\mutexblock.h">
<Filter>Library Header Files</Filter>
</ClInclude>
@@ -161,6 +167,9 @@
<ClInclude Include="..\include\isc\nonce.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\once.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\os.h">
<Filter>Library Header Files</Filter>
</ClInclude>
@@ -251,6 +260,9 @@
<ClInclude Include="..\include\isc\taskpool.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\thread.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\timer.h">
<Filter>Library Header Files</Filter>
</ClInclude>
@@ -289,18 +301,12 @@
<ClInclude Include="include\isc\bindevt.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\condition.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\dir.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\ipv6.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\mutex.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\net.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
@@ -316,9 +322,6 @@
<ClInclude Include="include\isc\offset.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\once.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\platform.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
@@ -337,9 +340,6 @@
<ClInclude Include="include\isc\syslog.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\thread.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>
<ClInclude Include="include\isc\time.h">
<Filter>Win32 Header Files</Filter>
</ClInclude>

View File

@@ -303,6 +303,7 @@ copy InstallFiles ..\Build\Release\
<ClInclude Include="..\include\isc\buffer.h" />
<ClInclude Include="..\include\isc\bufferlist.h" />
<ClInclude Include="..\include\isc\commandline.h" />
<ClInclude Include="..\include\isc\condition.h" />
<ClInclude Include="..\include\isc\counter.h" />
<ClInclude Include="..\include\isc\crc64.h" />
<ClInclude Include="..\include\isc\endian.h" />
@@ -333,10 +334,12 @@ copy InstallFiles ..\Build\Release\
<ClInclude Include="..\include\isc\md.h" />
<ClInclude Include="..\include\isc\mem.h" />
<ClInclude Include="..\include\isc\meminfo.h" />
<ClInclude Include="..\include\isc\mutex.h" />
<ClInclude Include="..\include\isc\mutexblock.h" />
<ClInclude Include="..\include\isc\netaddr.h" />
<ClInclude Include="..\include\isc\netscope.h" />
<ClInclude Include="..\include\isc\nonce.h" />
<ClInclude Include="..\include\isc\once.h" />
<ClInclude Include="..\include\isc\os.h" />
<ClInclude Include="..\include\isc\parseint.h" />
<ClInclude Include="..\include\isc\pool.h" />
@@ -367,6 +370,7 @@ copy InstallFiles ..\Build\Release\
<ClInclude Include="..\include\isc\symtab.h" />
<ClInclude Include="..\include\isc\task.h" />
<ClInclude Include="..\include\isc\taskpool.h" />
<ClInclude Include="..\include\isc\thread.h" />
<ClInclude Include="..\include\isc\timer.h" />
<ClInclude Include="..\include\isc\tm.h" />
<ClInclude Include="..\include\isc\types.h" />
@@ -382,23 +386,19 @@ copy InstallFiles ..\Build\Release\
<ClInclude Include="errno2result.h" />
<ClInclude Include="include\isc\bindevt.h" />
<ClInclude Include="include\isc\bind_registry.h" />
<ClInclude Include="include\isc\condition.h" />
<ClInclude Include="include\isc\dir.h" />
<ClInclude Include="include\isc\ipv6.h" />
<ClInclude Include="include\isc\mutex.h" />
<ClInclude Include="include\isc\net.h" />
<ClInclude Include="include\isc\netdb.h" />
<ClInclude Include="include\isc\ntgroups.h" />
<ClInclude Include="include\isc\ntpaths.h" />
<ClInclude Include="include\isc\offset.h" />
<ClInclude Include="include\isc\once.h" />
<ClInclude Include="include\isc\platform.h" />
<ClInclude Include="include\isc\stat.h" />
<ClInclude Include="include\isc\stdatomic.h" />
<ClInclude Include="include\isc\stdtime.h" />
<ClInclude Include="include\isc\strerror.h" />
<ClInclude Include="include\isc\syslog.h" />
<ClInclude Include="include\isc\thread.h" />
<ClInclude Include="include\isc\time.h" />
<ClInclude Include="include\isc\win32os.h" />
<ClInclude Include="..\entropy_private.h" />
@@ -419,6 +419,7 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="..\buffer.c" />
<ClCompile Include="..\bufferlist.c" />
<ClCompile Include="..\commandline.c" />
<ClCompile Include="..\condition.c" />
<ClCompile Include="..\counter.c" />
<ClCompile Include="..\crc64.c" />
<ClCompile Include="..\entropy.c" />
@@ -448,6 +449,7 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="..\netmgr\tcpdns.c" />
<ClCompile Include="..\netscope.c" />
<ClCompile Include="..\nonce.c" />
<ClCompile Include="..\once.c" />
<ClCompile Include="..\openssl_shim.c" />
<ClCompile Include="..\parseint.c" />
<ClCompile Include="..\pool.c" />
@@ -470,6 +472,7 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="..\symtab.c" />
<ClCompile Include="..\task.c" />
<ClCompile Include="..\taskpool.c" />
<ClCompile Include="..\thread.c" />
<ClCompile Include="..\timer.c" />
<ClCompile Include="..\tm.c" />
<ClCompile Include="..\utf8.c" />
@@ -477,7 +480,6 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="..\pk11.c" />
<ClCompile Include="..\pk11_result.c" />
@END PKCS11
<ClCompile Include="condition.c" />
<ClCompile Include="dir.c" />
<ClCompile Include="DLLMain.c" />
<ClCompile Include="errno.c" />
@@ -489,14 +491,12 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="meminfo.c" />
<ClCompile Include="net.c" />
<ClCompile Include="ntpaths.c" />
<ClCompile Include="once.c" />
<ClCompile Include="os.c" />
<ClCompile Include="resource.c" />
<ClCompile Include="socket.c" />
<ClCompile Include="stdio.c" />
<ClCompile Include="stdtime.c" />
<ClCompile Include="syslog.c" />
<ClCompile Include="thread.c" />
<ClCompile Include="time.c" />
<ClCompile Include="win32os.c" />
@IF PKCS11

View File

@@ -1,41 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <windows.h>
#include <isc/assertions.h>
#include <isc/once.h>
#include <isc/util.h>
isc_result_t
isc_once_do(isc_once_t *controller, void (*function)(void)) {
REQUIRE(controller != NULL && function != NULL);
if (controller->status == ISC_ONCE_INIT_NEEDED) {
if (InterlockedDecrement(&controller->counter) == 0) {
if (controller->status == ISC_ONCE_INIT_NEEDED) {
function();
controller->status = ISC_ONCE_INIT_DONE;
}
} else {
while (controller->status == ISC_ONCE_INIT_NEEDED) {
/*
* Sleep(0) indicates that this thread
* should be suspended to allow other
* waiting threads to execute.
*/
Sleep(0);
}
}
}
return (ISC_R_SUCCESS);
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <process.h>
#include <isc/strerr.h>
#include <isc/thread.h>
#include <isc/util.h>
void
isc_thread_create(isc_threadfunc_t start, isc_threadarg_t arg,
isc_thread_t *threadp) {
isc_thread_t thread;
unsigned int id;
thread = (isc_thread_t)_beginthreadex(NULL, 0, start, arg, 0, &id);
if (thread == NULL) {
char strbuf[ISC_STRERRORSIZE];
strerror_r(errno, strbuf, sizeof(strbuf));
isc_error_fatal(__FILE__, __LINE__, "_beginthreadex failed: %s",
strbuf);
}
*threadp = thread;
return;
}
void
isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) {
DWORD result;
result = WaitForSingleObject(thread, INFINITE);
if (result != WAIT_OBJECT_0) {
isc_error_fatal(__FILE__, __LINE__,
"WaitForSingleObject() != WAIT_OBJECT_0");
}
if (rp != NULL && !GetExitCodeThread(thread, rp)) {
isc_error_fatal(__FILE__, __LINE__,
"GetExitCodeThread() failed: %d",
GetLastError());
}
(void)CloseHandle(thread);
}
void
isc_thread_setconcurrency(unsigned int level) {
/*
* This is unnecessary on Win32 systems, but is here so that the
* call exists
*/
}
void
isc_thread_setname(isc_thread_t thread, const char *name) {
UNUSED(thread);
UNUSED(name);
}
isc_result_t
isc_thread_setaffinity(int cpu) {
/* no-op on Windows for now */
return (ISC_R_SUCCESS);
}