-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
-# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
-# serial 12 (pkg-config-0.29.2)
-
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29.1)
+dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
-[m4_define([PKG_MACROS_VERSION], [0.29.2])
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
-AC_MSG_CHECKING([for $2])
+AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
- AC_MSG_RESULT([no])
+ AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
- else
+ else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
- AC_MSG_RESULT([no])
+ AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
printf(";; Query time: %ld msec\n", (long) diff / 1000);
printf(";; SERVER: %s(%s)\n", fromtext, query->servname);
time(&tnow);
-#if defined(ISC_PLATFORM_USETHREADS) && !defined(WIN32)
+#if !defined(WIN32)
(void)localtime_r(&tnow, &tmnow);
#else
tmnow = *localtime(&tnow);
printf("linked to zlib version: %s\n",
zlibVersion());
#endif
-#ifdef ISC_PLATFORM_USETHREADS
printf("threads support is enabled\n");
-#else
- printf("threads support is disabled\n");
-#endif
exit(0);
case 'x':
/* Obsolete. No longer in use. Ignore. */
INSIST(named_g_cpus_detected > 0);
-#ifdef ISC_PLATFORM_USETHREADS
if (named_g_cpus == 0)
named_g_cpus = named_g_cpus_detected;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
named_g_cpus_detected,
named_g_cpus_detected == 1 ? "" : "s",
named_g_cpus, named_g_cpus == 1 ? "" : "s");
-#else
- named_g_cpus = 1;
-#endif
#ifdef WIN32
named_g_udpdisp = 1;
#else
if (named_g_udpdisp > named_g_cpus)
named_g_udpdisp = named_g_cpus;
#endif
-#ifdef ISC_PLATFORM_USETHREADS
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"using %u UDP listener%s per interface",
named_g_udpdisp, named_g_udpdisp == 1 ? "" : "s");
-#endif
result = isc_taskmgr_create(named_g_mctx, named_g_cpus, 0,
&named_g_taskmgr);
isc_mem_free(named_g_mctx, instance);
#endif /* HAVE_LIBSCF */
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Check for the number of cpu's before named_os_chroot().
*/
named_g_cpus_detected = isc_os_ncpus();
-#endif
named_os_chroot(named_g_chrootdir);
}
CHECK(putstr(text, line));
-#ifdef ISC_PLATFORM_USETHREADS
snprintf(line, sizeof(line), "CPUs found: %u\n", named_g_cpus_detected);
CHECK(putstr(text, line));
snprintf(line, sizeof(line), "UDP listeners per interface: %u\n",
named_g_udpdisp);
CHECK(putstr(text, line));
-#else
- snprintf(line, sizeof(line), "CPUs found: N/A (threads disabled)\n");
- CHECK(putstr(text, line));
-#endif
snprintf(line, sizeof(line), "number of zones: %u (%u automatic)\n",
zonecount, automatic);
#define sleep(x) Sleep(1000 * x)
#endif
-#ifdef ISC_PLATFORM_USETHREADS
-
isc_rwlock_t lock;
static isc_threadresult_t
return (0);
}
-
-#else
-
-int
-main(int argc, char *argv[]) {
- UNUSED(argc);
- UNUSED(argv);
- fprintf(stderr, "This test requires threads.\n");
- return(1);
-}
-
-#endif
ISC_THREAD_DIR
THREADOPTSRCS
THREADOPTOBJS
-ISC_PLATFORM_USETHREADS
ALWAYS_DEFINES
CHECK_DSA
GEOIPLINKOBJS
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
fi
-case "$enable_afl" in
-yes)
- LIBS="$LIBS -lpthread"
- ;;
-esac
#
# Make very sure that these are the first files processed by
case "$host" in
- *solaris-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5
+ *-freebsd*)
+ CC="$CC -pthread"
+ CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
+ STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
+ ;;
+ *-openbsd*)
+ CC="$CC -pthread"
+ CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
+ ;;
+ *-solaris*)
+ LIBS="$LIBS -lthread"
+ ;;
+ *-ibm-aix*)
+ STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
+ ;;
+ esac
+else
+ case $host in
+ *-dec-osf*)
+ CC="$CC -pthread"
+ CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
+ ;;
+ *-solaris*)
+ CC="$CC -mt"
+ CCOPT="$CCOPT -mt"
+ CCNOOPT="$CCNOOPT -mt"
+ ;;
+ *-ibm-aix*)
+ STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
+ ;;
+ *-sco-sysv*uw*|*-*-sysv*UnixWare*)
+ CC="$CC -Kthread"
+ CCOPT="$CCOPT -Kthread"
+ CCNOOPT="$CCNOOPT -Kthread"
+ ;;
+ *-*-sysv*OpenUNIX*)
+ CC="$CC -Kpthread"
+ CCOPT="$CCOPT -Kpthread"
+ CCNOOPT="$CCNOOPT -Kpthread"
+ ;;
+ esac
+fi
+ALWAYS_DEFINES="-D_REENTRANT"
+THREADOPTOBJS='${THREADOPTOBJS}'
+THREADOPTSRCS='${THREADOPTSRCS}'
+thread_dir=pthreads
+#
+# We'd like to use sigwait() too
+#
+ac_fn_c_check_func "$LINENO" "sigwait" "ac_cv_func_sigwait"
+if test "x$ac_cv_func_sigwait" = xyes; then :
+ $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lc" >&5
+$as_echo_n "checking for sigwait in -lc... " >&6; }
+if ${ac_cv_lib_c_sigwait+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sigwait ();
+int
+main ()
+{
+return sigwait ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_sigwait=yes
+else
+ ac_cv_lib_c_sigwait=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_sigwait" >&5
+$as_echo "$ac_cv_lib_c_sigwait" >&6; }
+if test "x$ac_cv_lib_c_sigwait" = xyes; then :
+ $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lpthread" >&5
+$as_echo_n "checking for sigwait in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_sigwait+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sigwait ();
+int
+main ()
+{
+return sigwait ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_sigwait=yes
+else
+ ac_cv_lib_pthread_sigwait=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_sigwait" >&5
+$as_echo "$ac_cv_lib_pthread_sigwait" >&6; }
+if test "x$ac_cv_lib_pthread_sigwait" = xyes; then :
+ $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _Psigwait in -lpthread" >&5
+$as_echo_n "checking for _Psigwait in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread__Psigwait+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _Psigwait ();
+int
+main ()
+{
+return _Psigwait ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread__Psigwait=yes
+else
+ ac_cv_lib_pthread__Psigwait=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread__Psigwait" >&5
+$as_echo "$ac_cv_lib_pthread__Psigwait" >&6; }
+if test "x$ac_cv_lib_pthread__Psigwait" = xyes; then :
+ $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h
+
+fi
+
+fi
+
+fi
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "pthread_attr_getstacksize" "ac_cv_func_pthread_attr_getstacksize"
+if test "x$ac_cv_func_pthread_attr_getstacksize" = xyes; then :
+ $as_echo "#define HAVE_PTHREAD_ATTR_GETSTACKSIZE 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "pthread_attr_setstacksize" "ac_cv_func_pthread_attr_setstacksize"
+if test "x$ac_cv_func_pthread_attr_setstacksize" = xyes; then :
+ $as_echo "#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1" >>confdefs.h
+
+fi
+
+
+
+# Check whether --with-locktype was given.
+if test "${with_locktype+set}" = set; then :
+ withval=$with_locktype; locktype="$withval"
+else
+ locktype="adaptive"
+fi
+
+
+case "$locktype" in
+ adaptive)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_MUTEX_ADAPTIVE_NP" >&5
+$as_echo_n "checking for PTHREAD_MUTEX_ADAPTIVE_NP... " >&6; }
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <pthread.h>
+
+int
+main ()
+{
+
+ return (PTHREAD_MUTEX_ADAPTIVE_NP);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using adaptive lock type" >&5
+$as_echo "using adaptive lock type" >&6; }
+
+$as_echo "#define HAVE_PTHREAD_MUTEX_ADAPTIVE_NP 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using standard lock type" >&5
+$as_echo "using standard lock type" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ;;
+ standard)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using standard lock type" >&5
+$as_echo "using standard lock type" >&6; }
+ ;;
+ *)
+ as_fn_error $? "You must specify \"adaptive\" or \"standard\" for --with-locktype." "$LINENO" 5
+ ;;
+esac
+
+for ac_header in sched.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sched.h" "ac_cv_header_sched_h" "$ac_includes_default"
+if test "x$ac_cv_header_sched_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SCHED_H 1
+_ACEOF
+
+fi
+
+done
+
+
+case "$host" in
+*solaris-*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5
$as_echo_n "checking for sched_yield in -lrt... " >&6; }
if ${ac_cv_lib_rt_sched_yield+:} false; then :
$as_echo_n "(cached) " >&6
fi
- ;;
- esac
+ ;;
+esac
- for ac_func in sched_yield pthread_yield pthread_yield_np
+for ac_func in sched_yield pthread_yield pthread_yield_np
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
done
+#
+# Additional OS-specific issues related to pthreads and sigwait.
+#
+case "$host" in
#
- # Additional OS-specific issues related to pthreads and sigwait.
+ # One more place to look for sigwait.
#
- case "$host" in
- #
- # One more place to look for sigwait.
- #
- *-freebsd*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lc_r" >&5
+ *-freebsd*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lc_r" >&5
$as_echo_n "checking for sigwait in -lc_r... " >&6; }
if ${ac_cv_lib_c_r_sigwait+:} false; then :
$as_echo_n "(cached) " >&6
fi
- case $host in
- *-freebsd5.[012]|*-freebsd5.[012].*);;
- *-freebsd5.[3456789]|*-freebsd5.[3456789].*)
- $as_echo "#define NEED_PTHREAD_SCOPE_SYSTEM 1" >>confdefs.h
-
- ;;
- *-freebsd6.*)
- $as_echo "#define NEED_PTHREAD_SCOPE_SYSTEM 1" >>confdefs.h
+ case $host in
+ *-freebsd5.[012]|*-freebsd5.[012].*);;
+ *-freebsd5.[3456789]|*-freebsd5.[3456789].*)
+ $as_echo "#define NEED_PTHREAD_SCOPE_SYSTEM 1" >>confdefs.h
- ;;
- esac
;;
- #
- # BSDI 3.0 through 4.0.1 needs pthread_init() to be
- # called before certain pthreads calls. This is deprecated
- # in BSD/OS 4.1.
- #
- *-bsdi3.*|*-bsdi4.0*)
- $as_echo "#define NEED_PTHREAD_INIT 1" >>confdefs.h
+ *-freebsd6.*)
+ $as_echo "#define NEED_PTHREAD_SCOPE_SYSTEM 1" >>confdefs.h
;;
- #
- # LinuxThreads requires some changes to the way we
- # deal with signals.
- #
- *-linux*)
- $as_echo "#define HAVE_LINUXTHREADS 1" >>confdefs.h
+ esac
+ ;;
+ #
+ # BSDI 3.0 through 4.0.1 needs pthread_init() to be
+ # called before certain pthreads calls. This is deprecated
+ # in BSD/OS 4.1.
+ #
+ *-bsdi3.*|*-bsdi4.0*)
+ $as_echo "#define NEED_PTHREAD_INIT 1" >>confdefs.h
- ;;
- #
- # Ensure the right sigwait() semantics on Solaris and make
- # sure we call pthread_setconcurrency.
- #
- *-solaris*)
- $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+ ;;
+ #
+ # LinuxThreads requires some changes to the way we
+ # deal with signals.
+ #
+ *-linux*)
+ $as_echo "#define HAVE_LINUXTHREADS 1" >>confdefs.h
+
+ ;;
+ #
+ # Ensure the right sigwait() semantics on Solaris and make
+ # sure we call pthread_setconcurrency.
+ #
+ *-solaris*)
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
- ac_fn_c_check_func "$LINENO" "pthread_setconcurrency" "ac_cv_func_pthread_setconcurrency"
+ ac_fn_c_check_func "$LINENO" "pthread_setconcurrency" "ac_cv_func_pthread_setconcurrency"
if test "x$ac_cv_func_pthread_setconcurrency" = xyes; then :
$as_echo "#define CALL_PTHREAD_SETCONCURRENCY 1" >>confdefs.h
fi
- ;;
- #
- # UnixWare does things its own way.
- #
- *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*)
- $as_echo "#define HAVE_UNIXWARE_SIGWAIT 1" >>confdefs.h
+ ;;
+ #
+ # UnixWare does things its own way.
+ #
+ *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*)
+ $as_echo "#define HAVE_UNIXWARE_SIGWAIT 1" >>confdefs.h
- ;;
- esac
+ ;;
+esac
- # Look for functions relating to thread naming
- for ac_func in pthread_setname_np pthread_set_name_np
+# Look for functions relating to thread naming
+for ac_func in pthread_setname_np pthread_set_name_np
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
fi
done
- for ac_header in pthread_np.h
+for ac_header in pthread_np.h
do :
ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "#include <pthread.h>
"
done
- #
- # Look for sysconf to allow detection of the number of processors.
- #
- ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf"
+#
+# Look for sysconf to allow detection of the number of processors.
+#
+ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf"
if test "x$ac_cv_func_sysconf" = xyes; then :
$as_echo "#define HAVE_SYSCONF 1" >>confdefs.h
fi
-else
- ISC_PLATFORM_USETHREADS="#undef ISC_PLATFORM_USETHREADS"
- thread_dir=nothreads
- THREADOPTOBJS=""
- THREADOPTSRCS=""
- ALWAYS_DEFINES=""
-fi
-
-
fi
-#
-# Indicate what the final decision was regarding threads.
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with threads" >&5
-$as_echo_n "checking whether to build with threads... " >&6; }
-if $use_threads; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-#
-# End of pthreads stuff.
-#
-
#
# Large File
#
#
# CPU relax (for spin locks)
#
-if $use_threads
-then
- case "$host" in
- i[3456]86-*)
- # x86_32
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"rep; nop\"); works" >&5
+case "$host" in
+i[3456]86-*)
+ # x86_32
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"rep; nop\"); works" >&5
$as_echo_n "checking if asm(\"rep; nop\"); works... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ;;
- x86_64-*|amd64-*)
- # x86_64
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"rep; nop\"); works" >&5
+ ;;
+x86_64-*|amd64-*)
+ # x86_64
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"rep; nop\"); works" >&5
$as_echo_n "checking if asm(\"rep; nop\"); works... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ;;
- ia64-*)
- # ia64
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"hint @pause\"); works" >&5
+ ;;
+ia64-*)
+ # ia64
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"hint @pause\"); works" >&5
$as_echo_n "checking if asm(\"hint @pause\"); works... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ;;
- sparc-*)
- # sparc
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if cpu_relax(); or __cpu_relax(); works" >&5
+ ;;
+sparc-*)
+ # sparc
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if cpu_relax(); or __cpu_relax(); works" >&5
$as_echo_n "checking if cpu_relax(); or __cpu_relax(); works... " >&6; }
- ac_fn_c_check_func "$LINENO" "cpu_relax" "ac_cv_func_cpu_relax"
+ ac_fn_c_check_func "$LINENO" "cpu_relax" "ac_cv_func_cpu_relax"
if test "x$ac_cv_func_cpu_relax" = xyes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP cpu_relax()"
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP cpu_relax()"
else
ac_fn_c_check_func "$LINENO" "__cpu_relax" "ac_cv_func___cpu_relax"
if test "x$ac_cv_func___cpu_relax" = xyes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP __cpu_relax()"
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP __cpu_relax()"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
- ;;
- esac
-fi
+ ;;
+esac
DNSTAPTARGETS=
DNSTAP_PB_C_H=
if test "x$use_dnstap" != "xno"; then
- if ! $use_threads; then
- as_fn_error $? "Dnstap requires threads." "$LINENO" 5
- fi
# Check whether --with-protobuf-c was given.
if test "${with_protobuf_c+set}" = set; then :
yes) :
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libidn2" >&5
-$as_echo_n "checking for libidn2... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBIDN2" >&5
+$as_echo_n "checking for LIBIDN2... " >&6; }
if test -n "$LIBIDN2_CFLAGS"; then
pkg_cv_LIBIDN2_CFLAGS="$LIBIDN2_CFLAGS"
if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
and LIBIDN2_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
yes) :
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cmocka" >&5
-$as_echo_n "checking for cmocka... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CMOCKA" >&5
+$as_echo_n "checking for CMOCKA... " >&6; }
if test -n "$CMOCKA_CFLAGS"; then
pkg_cv_CMOCKA_CFLAGS="$CMOCKA_CFLAGS"
if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
and CMOCKA_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
case "$use_tuning" in
large)
- if ! $use_threads; then
- as_fn_error $? "Large-system tuning requires threads." "$LINENO" 5
- fi
$as_echo "#define TUNE_LARGE 1" >>confdefs.h
echo "Configuration summary:"
echo "-------------------------------------------------------------------------------"
echo "Optional features enabled:"
- if $use_threads; then
- echo " Multiprocessing support (--enable-threads)"
- if test "yes" = "$enable_full_report" -o "standard" = "$locktype"; then
- echo " Mutex lock type: $locktype"
- fi
+ if test "yes" = "$enable_full_report" -o "standard" = "$locktype"; then
+ echo " Mutex lock type: $locktype"
fi
test "large" = "$use_tuning" && echo " Large-system tuning (--with-tuning)"
test "no" = "$use_dnstap" || \
echo "-------------------------------------------------------------------------------"
echo "Features disabled or unavailable on this platform:"
- $use_threads || echo " Multiprocessing support (--enable-threads)"
test "no" = "$enable_ipv6" -o "no" = "$found_ipv6" && \
echo " IPv6 support (--enable-ipv6)"
test "large" = "$use_tuning" || echo " Large-system tuning (--with-tuning)"
[default=no]]),
[AC_DEFINE([ENABLE_AFL], [1],
[Define to enable American Fuzzy Lop test harness])])
-case "$enable_afl" in
-yes)
- LIBS="$LIBS -lpthread"
- ;;
-esac
#
# Make very sure that these are the first files processed by
AC_CHECK_HEADERS(sched.h)
case "$host" in
- *solaris-*)
- AC_CHECK_LIB(rt, sched_yield)
+ *-freebsd*)
+ CC="$CC -pthread"
+ CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
+ STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
+ ;;
+ *-openbsd*)
+ CC="$CC -pthread"
+ CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
+ ;;
+ *-solaris*)
+ LIBS="$LIBS -lthread"
+ ;;
+ *-ibm-aix*)
+ STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
+ ;;
+ esac
+else
+ case $host in
+ *-dec-osf*)
+ CC="$CC -pthread"
+ CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
+ ;;
+ *-solaris*)
+ CC="$CC -mt"
+ CCOPT="$CCOPT -mt"
+ CCNOOPT="$CCNOOPT -mt"
+ ;;
+ *-ibm-aix*)
+ STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
+ ;;
+ *-sco-sysv*uw*|*-*-sysv*UnixWare*)
+ CC="$CC -Kthread"
+ CCOPT="$CCOPT -Kthread"
+ CCNOOPT="$CCNOOPT -Kthread"
+ ;;
+ *-*-sysv*OpenUNIX*)
+ CC="$CC -Kpthread"
+ CCOPT="$CCOPT -Kpthread"
+ CCNOOPT="$CCNOOPT -Kpthread"
;;
esac
+fi
+ALWAYS_DEFINES="-D_REENTRANT"
+THREADOPTOBJS='${THREADOPTOBJS}'
+THREADOPTSRCS='${THREADOPTSRCS}'
+thread_dir=pthreads
+#
+# We'd like to use sigwait() too
+#
+AC_CHECK_FUNC(sigwait,
+ AC_DEFINE(HAVE_SIGWAIT),
+ AC_CHECK_LIB(c, sigwait,
+ AC_DEFINE(HAVE_SIGWAIT),
+ AC_CHECK_LIB(pthread, sigwait,
+ AC_DEFINE(HAVE_SIGWAIT),
+ AC_CHECK_LIB(pthread, _Psigwait,
+ AC_DEFINE(HAVE_SIGWAIT),))))
+
+AC_CHECK_FUNC(pthread_attr_getstacksize,
+ AC_DEFINE(HAVE_PTHREAD_ATTR_GETSTACKSIZE),)
+
+AC_CHECK_FUNC(pthread_attr_setstacksize,
+ AC_DEFINE(HAVE_PTHREAD_ATTR_SETSTACKSIZE),)
+
+AC_ARG_WITH(locktype,
+ AS_HELP_STRING([--with-locktype=ARG],
+ [Specify mutex lock type
+ (adaptive or standard)]),
+ locktype="$withval", locktype="adaptive")
+
+case "$locktype" in
+ adaptive)
+ AC_MSG_CHECKING([for PTHREAD_MUTEX_ADAPTIVE_NP])
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <pthread.h>
+ ]], [[
+ return (PTHREAD_MUTEX_ADAPTIVE_NP);
+ ]])],
+ [ AC_MSG_RESULT(using adaptive lock type)
+ AC_DEFINE([HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], 1,
+ [Support for PTHREAD_MUTEX_ADAPTIVE_NP]) ],
+ [ AC_MSG_RESULT(using standard lock type) ])
+ ;;
+ standard)
+ AC_MSG_RESULT(using standard lock type)
+ ;;
+ *)
+ AC_MSG_ERROR([You must specify "adaptive" or "standard" for --with-locktype.])
+ ;;
+esac
- AC_CHECK_FUNCS(sched_yield pthread_yield pthread_yield_np)
+AC_CHECK_HEADERS(sched.h)
+case "$host" in
+*solaris-*)
+ AC_CHECK_LIB(rt, sched_yield)
+ ;;
+esac
+
+AC_CHECK_FUNCS(sched_yield pthread_yield pthread_yield_np)
+
+#
+# Additional OS-specific issues related to pthreads and sigwait.
+#
+case "$host" in
#
- # Additional OS-specific issues related to pthreads and sigwait.
+ # One more place to look for sigwait.
#
- case "$host" in
- #
- # One more place to look for sigwait.
- #
- *-freebsd*)
- AC_CHECK_LIB(c_r, sigwait, AC_DEFINE(HAVE_SIGWAIT),)
- case $host in
- *-freebsd5.[[012]]|*-freebsd5.[[012]].*);;
- *-freebsd5.[[3456789]]|*-freebsd5.[[3456789]].*)
- AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM)
- ;;
- *-freebsd6.*)
- AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM)
- ;;
- esac
- ;;
- #
- # BSDI 3.0 through 4.0.1 needs pthread_init() to be
- # called before certain pthreads calls. This is deprecated
- # in BSD/OS 4.1.
- #
- *-bsdi3.*|*-bsdi4.0*)
- AC_DEFINE(NEED_PTHREAD_INIT)
- ;;
- #
- # LinuxThreads requires some changes to the way we
- # deal with signals.
- #
- *-linux*)
- AC_DEFINE(HAVE_LINUXTHREADS)
- ;;
- #
- # Ensure the right sigwait() semantics on Solaris and make
- # sure we call pthread_setconcurrency.
- #
- *-solaris*)
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS)
- AC_CHECK_FUNC(pthread_setconcurrency,
- AC_DEFINE(CALL_PTHREAD_SETCONCURRENCY))
+ *-freebsd*)
+ AC_CHECK_LIB(c_r, sigwait, AC_DEFINE(HAVE_SIGWAIT),)
+ case $host in
+ *-freebsd5.[[012]]|*-freebsd5.[[012]].*);;
+ *-freebsd5.[[3456789]]|*-freebsd5.[[3456789]].*)
+ AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM)
;;
- #
- # UnixWare does things its own way.
- #
- *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*)
- AC_DEFINE(HAVE_UNIXWARE_SIGWAIT)
+ *-freebsd6.*)
+ AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM)
;;
- esac
-
- # Look for functions relating to thread naming
- AC_CHECK_FUNCS(pthread_setname_np pthread_set_name_np)
- AC_CHECK_HEADERS([pthread_np.h], [], [], [#include <pthread.h>])
-
+ esac
+ ;;
+ #
+ # BSDI 3.0 through 4.0.1 needs pthread_init() to be
+ # called before certain pthreads calls. This is deprecated
+ # in BSD/OS 4.1.
+ #
+ *-bsdi3.*|*-bsdi4.0*)
+ AC_DEFINE(NEED_PTHREAD_INIT)
+ ;;
#
- # Look for sysconf to allow detection of the number of processors.
+ # LinuxThreads requires some changes to the way we
+ # deal with signals.
#
- AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF),)
+ *-linux*)
+ AC_DEFINE(HAVE_LINUXTHREADS)
+ ;;
+ #
+ # Ensure the right sigwait() semantics on Solaris and make
+ # sure we call pthread_setconcurrency.
+ #
+ *-solaris*)
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS)
+ AC_CHECK_FUNC(pthread_setconcurrency,
+ AC_DEFINE(CALL_PTHREAD_SETCONCURRENCY))
+ ;;
+ #
+ # UnixWare does things its own way.
+ #
+ *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*)
+ AC_DEFINE(HAVE_UNIXWARE_SIGWAIT)
+ ;;
+esac
-else
- ISC_PLATFORM_USETHREADS="#undef ISC_PLATFORM_USETHREADS"
- thread_dir=nothreads
- THREADOPTOBJS=""
- THREADOPTSRCS=""
- ALWAYS_DEFINES=""
-fi
+# Look for functions relating to thread naming
+AC_CHECK_FUNCS(pthread_setname_np pthread_set_name_np)
+AC_CHECK_HEADERS([pthread_np.h], [], [], [#include <pthread.h>])
+
+#
+# Look for sysconf to allow detection of the number of processors.
+#
+AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF),)
AC_SUBST(ALWAYS_DEFINES)
-AC_SUBST(ISC_PLATFORM_USETHREADS)
AC_SUBST(THREADOPTOBJS)
AC_SUBST(THREADOPTSRCS)
ISC_THREAD_DIR=$thread_dir
AC_CHECK_FUNC(flockfile, AC_DEFINE(HAVE_FLOCKFILE),)
AC_CHECK_FUNC(getc_unlocked, AC_DEFINE(HAVE_GETCUNLOCKED),)
-#
-# Indicate what the final decision was regarding threads.
-#
-AC_MSG_CHECKING(whether to build with threads)
-if $use_threads; then
- AC_MSG_RESULT(yes)
-else
- AC_MSG_RESULT(no)
-fi
-
-#
-# End of pthreads stuff.
-#
-
#
# Large File
#
#
# CPU relax (for spin locks)
#
-if $use_threads
-then
- case "$host" in
- [i[3456]86-*])
- # x86_32
- AC_MSG_CHECKING([if asm("rep; nop"); works])
- AC_TRY_COMPILE(,[asm("rep; nop");],
- [AC_MSG_RESULT(yes)
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"],
- [AC_MSG_RESULT(no)],
- [AC_MSG_RESULT([cross compile, assume yes])
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"])
- ;;
- x86_64-*|amd64-*)
- # x86_64
- AC_MSG_CHECKING([if asm("rep; nop"); works])
- AC_TRY_COMPILE(,[asm("rep; nop");],
- [AC_MSG_RESULT(yes)
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"],
- [AC_MSG_RESULT(no)],
- [AC_MSG_RESULT([cross compile, assume yes])
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"])
- ;;
- ia64-*)
- # ia64
- AC_MSG_CHECKING([if asm("hint @pause"); works])
- AC_TRY_COMPILE(,[asm("hint @pause");],
- [AC_MSG_RESULT(yes)
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"],
- [AC_MSG_RESULT(no)],
- [AC_MSG_RESULT([cross compile, assume yes])
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"])
- ;;
- sparc-*)
- # sparc
- AC_MSG_CHECKING([if cpu_relax(); or __cpu_relax(); works])
- AC_CHECK_FUNC(cpu_relax,
- [AC_MSG_RESULT(yes)
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP cpu_relax()"],
- [AC_CHECK_FUNC(__cpu_relax,
- [AC_MSG_RESULT(yes)
- ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP __cpu_relax()"],
- [AC_MSG_RESULT(no)])])
- ;;
- esac
-fi
+case "$host" in
+[i[3456]86-*])
+ # x86_32
+ AC_MSG_CHECKING([if asm("rep; nop"); works])
+ AC_TRY_COMPILE(,[asm("rep; nop");],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"])
+ ;;
+x86_64-*|amd64-*)
+ # x86_64
+ AC_MSG_CHECKING([if asm("rep; nop"); works])
+ AC_TRY_COMPILE(,[asm("rep; nop");],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"])
+ ;;
+ia64-*)
+ # ia64
+ AC_MSG_CHECKING([if asm("hint @pause"); works])
+ AC_TRY_COMPILE(,[asm("hint @pause");],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"])
+ ;;
+sparc-*)
+ # sparc
+ AC_MSG_CHECKING([if cpu_relax(); or __cpu_relax(); works])
+ AC_CHECK_FUNC(cpu_relax,
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP cpu_relax()"],
+ [AC_CHECK_FUNC(__cpu_relax,
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP __cpu_relax()"],
+ [AC_MSG_RESULT(no)])])
+ ;;
+esac
AC_SUBST(ISC_PLATFORM_BUSYWAITNOP)
DNSTAPTARGETS=
DNSTAP_PB_C_H=
if test "x$use_dnstap" != "xno"; then
- if ! $use_threads; then
- AC_MSG_ERROR([Dnstap requires threads.])
- fi
AC_ARG_WITH([protobuf-c],
AS_HELP_STRING([--with-protobuf-c=path],
[Path where protobuf-c is installed, for dnstap]), [
case "$use_tuning" in
large)
- if ! $use_threads; then
- AC_MSG_ERROR([Large-system tuning requires threads.])
- fi
AC_DEFINE(TUNE_LARGE, 1, [Define to use large-system tuning.])
AC_MSG_RESULT(using large-system tuning)
;;
echo "Configuration summary:"
echo "-------------------------------------------------------------------------------"
echo "Optional features enabled:"
- if $use_threads; then
- echo " Multiprocessing support (--enable-threads)"
- if test "yes" = "$enable_full_report" -o "standard" = "$locktype"; then
- echo " Mutex lock type: $locktype"
- fi
+ if test "yes" = "$enable_full_report" -o "standard" = "$locktype"; then
+ echo " Mutex lock type: $locktype"
fi
test "large" = "$use_tuning" && echo " Large-system tuning (--with-tuning)"
test "no" = "$use_dnstap" || \
echo "-------------------------------------------------------------------------------"
echo "Features disabled or unavailable on this platform:"
- $use_threads || echo " Multiprocessing support (--enable-threads)"
test "no" = "$enable_ipv6" -o "no" = "$found_ipv6" && \
echo " IPv6 support (--enable-ipv6)"
test "large" = "$use_tuning" || echo " Large-system tuning (--with-tuning)"
static dns_sdlzimplementation_t *dlz_bdb = NULL;
/* should the bdb driver use threads. */
-#ifdef ISC_PLATFORM_USETHREADS
#define bdb_threads DB_THREAD
-#else
-#define bdb_threads 0
-#endif
/* BDB database names */
#define dlz_data "dns_data"
static dns_sdlzimplementation_t *dlz_bdbhpt = NULL;
/* should the bdb driver use threads. */
-#ifdef ISC_PLATFORM_USETHREADS
#define bdbhpt_threads DB_THREAD
-#else
-#define bdbhpt_threads 0
-#endif
/* bdbhpt database names */
#define dlz_data "dns_data"
*/
typedef struct {
-#ifdef ISC_PLATFORM_USETHREADS
db_list_t *db; /*%< handle to a list of DB */
-#else
- dbinstance_t *db; /*%< handle to db */
-#endif
int method; /*%< security authentication method */
char *user; /*%< who is authenticating */
char *cred; /*%< password for simple authentication method */
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
-
-
/*%
* Properly cleans up a list of database instances.
* This function is only used when the driver is compiled for
count);
return (NULL);
}
-#endif /* ISC_PLATFORM_USETHREADS */
static isc_result_t
ldap_process_results(LDAP *dbc, LDAPMessage *msg, char ** attrs,
int entries;
/* get db instance / connection */
-#ifdef ISC_PLATFORM_USETHREADS
-
/* find an available DBI from the list */
dbi = ldap_find_avail_conn((db_list_t *)
((ldap_instance_t *)dbdata)->db);
-#else /* ISC_PLATFORM_USETHREADS */
-
- /*
- * only 1 DBI - no need to lock instance lock either
- * only 1 thread in the whole process, no possible contention.
- */
- dbi = (dbinstance_t *) ((ldap_instance_t *)dbdata)->db;
-
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* if DBI is null, can't do anything else */
if (dbi == NULL)
return (ISC_R_FAILURE);
if (dbi->client != NULL)
isc_mem_free(named_g_mctx, dbi->client);
-#ifdef ISC_PLATFORM_USETHREADS
-
/* release the lock so another thread can use this dbi */
isc_mutex_unlock(&dbi->instance_lock);
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* release query string */
if (querystring != NULL)
isc_mem_free(named_g_mctx, querystring );
dbinstance_t *dbi = NULL;
int protocol;
int method;
-
-#ifdef ISC_PLATFORM_USETHREADS
- /* if multi-threaded, we need a few extra variables. */
int dbcount;
char *endp;
/* db_list_t *dblist = NULL; */
int i;
-#endif /* ISC_PLATFORM_USETHREADS */
UNUSED(dlzname);
UNUSED(driverarg);
-#ifdef ISC_PLATFORM_USETHREADS
/* if debugging, let user know we are multithreaded. */
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
"LDAP driver running multithreaded");
-#else /* ISC_PLATFORM_USETHREADS */
- /* if debugging, let user know we are single threaded. */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
- "LDAP driver running single threaded");
-#endif /* ISC_PLATFORM_USETHREADS */
if (argc < 9) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
return (ISC_R_FAILURE);
}
- /* multithreaded build can have multiple DB connections */
-#ifdef ISC_PLATFORM_USETHREADS
-
/* check how many db connections we should create */
dbcount = strtol(argv[1], &endp, 10);
if (*endp != '\0' || dbcount < 0) {
"must be positive.");
return (ISC_R_FAILURE);
}
-#endif
/* check that LDAP URL parameters make sense */
switch(argc) {
goto cleanup;
}
-#ifdef ISC_PLATFORM_USETHREADS
/* allocate memory for database connection list */
ldap_inst->db = isc_mem_get(named_g_mctx, sizeof(db_list_t));
if (ldap_inst->db == NULL) {
*/
for (i = 0; i < dbcount; i++) {
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* how many queries were passed in from config file? */
switch(argc) {
case 9:
goto cleanup;
}
-#ifdef ISC_PLATFORM_USETHREADS
- /* when multithreaded, build a list of DBI's */
ISC_LINK_INIT(dbi, link);
ISC_LIST_APPEND(*(ldap_inst->db), dbi, link);
-#else
- /*
- * when single threaded, hold onto the one connection
- * instance.
- */
- ldap_inst->db = dbi;
-#endif
/* attempt to connect */
result = dlz_ldap_connect(ldap_inst, dbi);
* allocate memory
*/
case ISC_R_NOMEMORY:
-#ifdef ISC_PLATFORM_USETHREADS
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
"LDAP driver could not allocate memory "
"for connection number %u",
i+1);
-#else
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "LDAP driver could not allocate memory "
- "for connection");
-#endif
goto cleanup;
break;
/*
break;
/* failure means couldn't connect to ldap server */
case ISC_R_FAILURE:
-#ifdef ISC_PLATFORM_USETHREADS
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
"LDAP driver could not "
"bind connection number %u to server.",
i+1);
-#else
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "LDAP driver could not "
- "bind connection to server.");
-#endif
goto cleanup;
break;
/*
break;
} /* end switch(result) */
-
-#ifdef ISC_PLATFORM_USETHREADS
-
/* set DBI = null for next loop through. */
dbi = NULL;
} /* end for loop */
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* set dbdata to the ldap_instance we created. */
*dbdata = ldap_inst;
UNUSED(driverarg);
if (dbdata != NULL) {
-#ifdef ISC_PLATFORM_USETHREADS
/* cleanup the list of DBI's */
ldap_destroy_dblist((db_list_t *)
((ldap_instance_t *)dbdata)->db);
-#else /* ISC_PLATFORM_USETHREADS */
- if (((ldap_instance_t *)dbdata)->db->dbconn != NULL)
- ldap_unbind_s((LDAP *)
- ((ldap_instance_t *)dbdata)->db->dbconn);
-
- /* destroy single DB instance */
- destroy_sqldbinstance(((ldap_instance_t *)dbdata)->db);
-#endif /* ISC_PLATFORM_USETHREADS */
-
if (((ldap_instance_t *)dbdata)->hosts != NULL)
isc_mem_free(named_g_mctx,
((ldap_instance_t *)dbdata)->hosts);
*/
typedef struct {
-
-#ifdef ISC_PLATFORM_USETHREADS
-
db_list_t *db; /* handle to a list of DB */
-
-#else
-
- dbinstance_t *db; /* handle to db */
-
-#endif
-
SQLHENV sql_env; /* handle to SQL environment */
SQLCHAR *dsn;
SQLCHAR *user;
static void
destroy_odbc_instance(odbc_instance_t *odbc_inst) {
-
-#ifdef ISC_PLATFORM_USETHREADS
-
dbinstance_t *ndbi = NULL;
dbinstance_t *dbi = NULL;
/* release memory for the list structure */
isc_mem_put(named_g_mctx, odbc_inst->db, sizeof(db_list_t));
-#else /* ISC_PLATFORM_USETHREADS */
-
- /* free statement handle */
- if (((odbc_db_t *) (odbc_inst->db->dbconn))->stmnt != NULL) {
- SQLFreeHandle(SQL_HANDLE_STMT,
- ((odbc_db_t *) (odbc_inst->db->dbconn))->stmnt);
- ((odbc_db_t *) (odbc_inst->db->dbconn))->stmnt = NULL;
- }
-
- /* disconnect from database, free connection handle */
- if (((odbc_db_t *) (odbc_inst->db->dbconn))->dbc != NULL) {
- SQLDisconnect(((odbc_db_t *) (odbc_inst->db->dbconn))->dbc);
- SQLFreeHandle(SQL_HANDLE_DBC,
- ((odbc_db_t *) (odbc_inst->db->dbconn))->dbc);
- ((odbc_db_t *) (odbc_inst->db->dbconn))->dbc = NULL;
- }
- /* free mem for the odbc_db_t structure held in db */
- if (((odbc_db_t *) odbc_inst->db->dbconn) != NULL) {
- isc_mem_free(named_g_mctx, odbc_inst->db->dbconn);
- odbc_inst->db->dbconn = NULL;
- }
-
- if (odbc_inst->db != NULL)
- destroy_sqldbinstance(odbc_inst->db);
-
-#endif /* ISC_PLATFORM_USETHREADS */
-
-
/* free sql environment */
if (odbc_inst->sql_env != NULL)
SQLFreeHandle(SQL_HANDLE_ENV, odbc_inst->sql_env);
* multithreaded operation.
*/
-#ifdef ISC_PLATFORM_USETHREADS
-
static dbinstance_t *
odbc_find_avail_conn(db_list_t *dblist)
{
return NULL;
}
-#endif /* ISC_PLATFORM_USETHREADS */
-
/*% Allocates memory for a new string, and then constructs the new
* string by "escaping" the input string. The new string is
* safe to be used in queries. This is necessary because we cannot
REQUIRE(*r_dbi == NULL);
/* get db instance / connection */
-#ifdef ISC_PLATFORM_USETHREADS
/* find an available DBI from the list */
dbi = odbc_find_avail_conn(((odbc_instance_t *) dbdata)->db);
-#else /* ISC_PLATFORM_USETHREADS */
-
- /*
- * only 1 DBI - no need to lock instance lock either
- * only 1 thread in the whole process, no possible contention.
- */
- dbi = (dbinstance_t *) ((odbc_instance_t *) dbdata)->db;
-
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* if DBI is null, can't do anything else */
if (dbi == NULL) {
result = ISC_R_FAILURE;
if (dbi->client != NULL)
isc_mem_free(named_g_mctx, dbi->client);
-#ifdef ISC_PLATFORM_USETHREADS
-
/* if we are done using this dbi, release the lock */
if (result != ISC_R_SUCCESS)
isc_mutex_unlock(&dbi->instance_lock);
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* release query string */
if (querystring != NULL)
isc_mem_free(named_g_mctx, querystring );
/* close cursor */
SQLCloseCursor(((odbc_db_t *) (dbi->dbconn))->stmnt);
-#ifdef ISC_PLATFORM_USETHREADS
-
/* free lock on dbi so someone else can use it. */
isc_mutex_unlock(&dbi->instance_lock);
-#endif
-
return result;
}
/* get rid of result set, we are done with it. */
SQLCloseCursor(((odbc_db_t *) (dbi->dbconn))->stmnt);
-#ifdef ISC_PLATFORM_USETHREADS
-
/* free lock on dbi so someone else can use it. */
isc_mutex_unlock(&dbi->instance_lock);
-#endif
}
return result;
/* get rid of result set, we are done with it. */
SQLCloseCursor(((odbc_db_t *) (dbi->dbconn))->stmnt);
-#ifdef ISC_PLATFORM_USETHREADS
-
/* free lock on dbi so someone else can use it. */
isc_mutex_unlock(&dbi->instance_lock);
-#endif
}
/* close cursor */
SQLCloseCursor(((odbc_db_t *) (dbi->dbconn))->stmnt);
-#ifdef ISC_PLATFORM_USETHREADS
-
/* free lock on dbi so someone else can use it. */
isc_mutex_unlock(&dbi->instance_lock);
-#endif
-
return result;
}
odbc_instance_t *odbc_inst = NULL;
dbinstance_t *db = NULL;
SQLRETURN sqlRes;
-
-#ifdef ISC_PLATFORM_USETHREADS
- /* if multi-threaded, we need a few extra variables. */
int dbcount;
int i;
char *endp;
-#endif /* ISC_PLATFORM_USETHREADS */
-
UNUSED(dlzname);
UNUSED(driverarg);
-#ifdef ISC_PLATFORM_USETHREADS
/* if debugging, let user know we are multithreaded. */
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
"Odbc driver running multithreaded");
-#else /* ISC_PLATFORM_USETHREADS */
- /* if debugging, let user know we are single threaded. */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
- "Odbc driver running single threaded");
-#endif /* ISC_PLATFORM_USETHREADS */
/* verify we have at least 5 arg's passed to the driver */
if (argc < 5) {
}
/* multithreaded build can have multiple DB connections */
-#ifdef ISC_PLATFORM_USETHREADS
-
/* check how many db connections we should create */
dbcount = strtol(argv[1], &endp, 10);
if (*endp != '\0' || dbcount < 0) {
return (ISC_R_FAILURE);
}
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* allocate memory for odbc instance */
odbc_inst = isc_mem_get(named_g_mctx, sizeof(odbc_instance_t));
if (odbc_inst == NULL)
}
}
-#ifdef ISC_PLATFORM_USETHREADS
-
/* allocate memory for database connection list */
odbc_inst->db = isc_mem_get(named_g_mctx, sizeof(db_list_t));
if (odbc_inst->db == NULL) {
/* append each new DBI to the end of the list */
for (i=0; i < dbcount; i++) {
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* how many queries were passed in from config file? */
switch(argc) {
case 5:
goto cleanup;
}
-#ifdef ISC_PLATFORM_USETHREADS
-
/* when multithreaded, build a list of DBI's */
ISC_LINK_INIT(db, link);
ISC_LIST_APPEND(*odbc_inst->db, db, link);
-#endif
-
result = odbc_connect(odbc_inst, (odbc_db_t **) &(db->dbconn));
if (result != ISC_R_SUCCESS) {
-#ifdef ISC_PLATFORM_USETHREADS
-
/*
* if multi threaded, let user know which
* connection failed. user could be
"Odbc driver failed to create database "
"connection number %u after 3 attempts",
i+1);
-#else
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "Odbc driver failed to create database "
- "connection after 3 attempts");
-#endif
goto cleanup;
}
-#ifdef ISC_PLATFORM_USETHREADS
-
/* set DB = null for next loop through. */
db = NULL;
} /* end for loop */
-#else
- /* tell odbc_inst about the db connection we just created. */
- odbc_inst->db = db;
-
-#endif
-
/* set dbdata to the odbc_instance we created. */
*dbdata = odbc_inst;
return target - to;
}
-#ifdef ISC_PLATFORM_USETHREADS
-
/*%
* Properly cleans up a list of database instances.
* This function is only used when the driver is compiled for
return NULL;
}
-#endif /* ISC_PLATFORM_USETHREADS */
-
/*%
* Allocates memory for a new string, and then constructs the new
* string by "escaping" the input string. The new string is
#endif
/* get db instance / connection */
-#ifdef ISC_PLATFORM_USETHREADS
/* find an available DBI from the list */
dbi = postgres_find_avail_conn((db_list_t *) dbdata);
-#else /* ISC_PLATFORM_USETHREADS */
-
- /*
- * only 1 DBI - no need to lock instance lock either
- * only 1 thread in the whole process, no possible contention.
- */
- dbi = (dbinstance_t *) dbdata;
-
-#endif /* ISC_PLATFORM_USETHREADS */
-
#if 0
/* temporary logging message */
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
if (dbi->client != NULL)
isc_mem_free(named_g_mctx, dbi->client);
-#ifdef ISC_PLATFORM_USETHREADS
-
#if 0
/* temporary logging message */
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
/* release the lock so another thread can use this dbi */
isc_mutex_unlock(&dbi->instance_lock);
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* release query string */
if (querystring != NULL)
isc_mem_free(named_g_mctx, querystring );
dbinstance_t *dbi = NULL;
unsigned int j;
-#ifdef ISC_PLATFORM_USETHREADS
/* if multi-threaded, we need a few extra variables. */
int dbcount;
db_list_t *dblist = NULL;
int i;
char *endp;
-#endif /* ISC_PLATFORM_USETHREADS */
-
UNUSED(driverarg);
UNUSED(dlzname);
srand( (unsigned)time( NULL ) );
-#ifdef ISC_PLATFORM_USETHREADS
/* if debugging, let user know we are multithreaded. */
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
"Postgres driver running multithreaded");
-#else /* ISC_PLATFORM_USETHREADS */
- /* if debugging, let user know we are single threaded. */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
- "Postgres driver running single threaded");
-#endif /* ISC_PLATFORM_USETHREADS */
/* verify we have at least 5 arg's passed to the driver */
if (argc < 5) {
}
/* multithreaded build can have multiple DB connections */
-#ifdef ISC_PLATFORM_USETHREADS
/* check how many db connections we should create */
dbcount = strtol(argv[1], &endp, 10);
*/
for (i=0; i < dbcount; i++) {
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* how many queries were passed in from config file? */
switch(argc) {
case 5:
goto cleanup;
}
-#ifdef ISC_PLATFORM_USETHREADS
-
/* when multithreaded, build a list of DBI's */
ISC_LINK_INIT(dbi, link);
ISC_LIST_APPEND(*dblist, dbi, link);
-#endif
-
/* create and set db connection */
dbi->dbconn = PQconnectdb(argv[2]);
/*
PQreset((PGconn *) dbi->dbconn);
-#ifdef ISC_PLATFORM_USETHREADS
-
/*
* if multi threaded, let user know which connection
* failed. user could be attempting to create 10 db
/* set dbdata to the list we created. */
*dbdata = dblist;
-#else /* ISC_PLATFORM_USETHREADS */
- /* if single threaded, just let user know we couldn't connect. */
- if (PQstatus((PGconn *) dbi->dbconn) != CONNECTION_OK) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "Postgres driver failed to create database "
- "connection after 4 attempts");
- goto cleanup;
- }
-
- /*
- * single threaded build can only use 1 db connection, return
- * it via dbdata
- */
- *dbdata = dbi;
-
-#endif /* ISC_PLATFORM_USETHREADS */
-
/* hey, we got through all of that ok, return success. */
return(ISC_R_SUCCESS);
cleanup:
-#ifdef ISC_PLATFORM_USETHREADS
/*
* if multithreaded, we could fail because only 1 connection
* couldn't be made. We should cleanup the other successful
*/
postgres_destroy_dblist(dblist);
-#else /* ISC_PLATFORM_USETHREADS */
- if (dbi != NULL)
- destroy_sqldbinstance(dbi);
-
-#endif /* ISC_PLATFORM_USETHREADS */
return(ISC_R_FAILURE);
}
static void
postgres_destroy(void *driverarg, void *dbdata)
{
-
-#ifdef ISC_PLATFORM_USETHREADS
-
UNUSED(driverarg);
/* cleanup the list of DBI's */
postgres_destroy_dblist((db_list_t *) dbdata);
-
-#else /* ISC_PLATFORM_USETHREADS */
-
- dbinstance_t *dbi;
-
- UNUSED(driverarg);
-
- dbi = (dbinstance_t *) dbdata;
-
- /* release DB connection */
- if (dbi->dbconn != NULL)
- PQfinish((PGconn *) dbi->dbconn);
-
- /* destroy single DB instance */
- destroy_sqldbinstance(dbi);
-
-#endif /* ISC_PLATFORM_USETHREADS */
}
/* pointers to all our runtime methods. */
#include "dlz_minimal.h"
/* should the bdb driver use threads. */
-#ifdef ISC_PLATFORM_USETHREADS
#define bdbhpt_threads DB_THREAD
-#else
-#define bdbhpt_threads 0
-#endif
/* bdbhpt database names */
#define dlz_data "dns_data"
static void
printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) {
isc_result_t result;
-#ifdef ISC_PLATFORM_USETHREADS
char output[26]; /* Minimum buffer as per ctime_r() specification. */
-#else
- const char *output;
-#endif
isc_stdtime_t when;
time_t t;
char utc[sizeof("YYYYMMDDHHSSMM")];
/* time_t and isc_stdtime_t might be different sizes */
t = when;
-#ifdef ISC_PLATFORM_USETHREADS
#ifdef WIN32
if (ctime_s(output, sizeof(output), &t) != 0)
goto error;
if (ctime_r(&t, output) == NULL)
goto error;
#endif
-#else
- output = ctime(&t);
-#endif
isc_buffer_init(&b, utc, sizeof(utc));
result = dns_time32_totext(when, &b);
isc_mem_t *mctx;
} geoip_state_t;
-#ifdef ISC_PLATFORM_USETHREADS
static isc_mutex_t key_mutex;
static isc_boolean_t state_key_initialized = ISC_FALSE;
static isc_thread_key_t state_key;
return (result);
}
-#else
-static geoip_state_t saved_state;
-#endif
static void
clean_state(geoip_state_t *state) {
GeoIPRegion *region, char *name, const char *text, int id)
{
geoip_state_t *state = NULL;
-#ifdef ISC_PLATFORM_USETHREADS
isc_result_t result;
result = state_key_init();
isc_mem_attach(state_mctx, &state->mctx);
} else
clean_state(state);
-#else
- state = &saved_state;
- clean_state(state);
-#endif
if (family == AF_INET) {
state->ipnum = ipnum;
{
geoip_state_t *state;
-#ifdef ISC_PLATFORM_USETHREADS
isc_result_t result;
result = state_key_init();
state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
if (state == NULL)
return (NULL);
-#else
- state = &saved_state;
-#endif
if (state->family == family &&
((state->family == AF_INET && state->ipnum == ipnum) ||
dns_geoip_shutdown(void) {
#ifdef HAVE_GEOIP
GeoIP_cleanup();
-#ifdef ISC_PLATFORM_USETHREADS
if (state_mctx != NULL)
isc_mem_detach(&state_mctx);
-#endif
#else
return;
#endif
/*
* dns_name_t to text post-conversion procedure.
*/
-#ifdef ISC_PLATFORM_USETHREADS
static int thread_key_initialized = 0;
static isc_mutex_t thread_key_mutex;
static isc_mem_t *thread_key_mctx = NULL;
static isc_thread_key_t totext_filter_proc_key;
static isc_once_t once = ISC_ONCE_INIT;
-#else
-static dns_name_totextfilter_t totext_filter_proc = NULL;
-#endif
static void
set_offsets(const dns_name_t *name, unsigned char *offsets,
return (ISC_R_SUCCESS);
}
-#ifdef ISC_PLATFORM_USETHREADS
static void
free_specific(void *arg) {
dns_name_totextfilter_t *mem = arg;
}
return (result);
}
-#endif
isc_result_t
dns_name_totext(const dns_name_t *name, isc_boolean_t omit_final_dot,
unsigned int labels;
isc_boolean_t saw_root = ISC_FALSE;
unsigned int oused = target->used;
-#ifdef ISC_PLATFORM_USETHREADS
dns_name_totextfilter_t *mem;
dns_name_totextfilter_t totext_filter_proc = NULL;
isc_result_t result;
-#endif
isc_boolean_t omit_final_dot =
ISC_TF(options & DNS_NAME_OMITFINALDOT);
REQUIRE(VALID_NAME(name));
REQUIRE(ISC_BUFFER_VALID(target));
-#ifdef ISC_PLATFORM_USETHREADS
result = totext_filter_proc_key_init();
if (result != ISC_R_SUCCESS)
return (result);
-#endif
ndata = name->ndata;
nlen = name->length;
labels = name->labels;
}
isc_buffer_add(target, tlen - trem);
-#ifdef ISC_PLATFORM_USETHREADS
mem = isc_thread_key_getspecific(totext_filter_proc_key);
if (mem != NULL)
totext_filter_proc = *mem;
-#endif
if (totext_filter_proc != NULL)
return ((*totext_filter_proc)(target, oused));
isc_result_t
dns_name_settotextfilter(dns_name_totextfilter_t proc) {
-#ifdef ISC_PLATFORM_USETHREADS
isc_result_t result;
dns_name_totextfilter_t *mem;
int res;
result = ISC_R_UNEXPECTED;
}
return (result);
-#else
- totext_filter_proc = proc;
- return (ISC_R_SUCCESS);
-#endif
}
void
void
dns_name_destroy(void) {
-#ifdef ISC_PLATFORM_USETHREADS
RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
== ISC_R_SUCCESS);
}
UNLOCK(&thread_key_mutex);
-#endif
}
/*
}
res->buckets[i].mctx = NULL;
snprintf(name, sizeof(name), "res%u", i);
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Use a separate memory context for each bucket to reduce
* contention among multiple threads. Do this only when
goto cleanup_buckets;
}
isc_mem_setname(res->buckets[i].mctx, name, NULL);
-#else
- isc_mem_attach(view->mctx, &res->buckets[i].mctx);
-#endif
isc_task_setname(res->buckets[i].task, name, res);
ISC_LIST_INIT(res->buckets[i].fctxs);
res->buckets[i].exiting = ISC_FALSE;
static isc_result_t
create_managers(void) {
isc_result_t result;
-#ifdef ISC_PLATFORM_USETHREADS
ncpus = isc_os_ncpus();
-#else
- ncpus = 1;
-#endif
CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
CHECK(isc_timermgr_create(mctx, &timermgr));
}
}
-#ifdef ISC_PLATFORM_USETHREADS
#ifdef DNS_BENCHMARK_TESTS
/*
}
#endif /* DNS_BENCHMARK_TESTS */
-#endif /* ISC_PLATFORM_USETHREADS */
/*
* Main
ATF_TP_ADD_TC(tp, countlabels);
ATF_TP_ADD_TC(tp, getlabel);
ATF_TP_ADD_TC(tp, getlabelsequence);
-#ifdef ISC_PLATFORM_USETHREADS
#ifdef DNS_BENCHMARK_TESTS
ATF_TP_ADD_TC(tp, benchmark);
#endif /* DNS_BENCHMARK_TESTS */
-#endif /* ISC_PLATFORM_USETHREADS */
return (atf_no_error());
}
dns_test_end();
}
-#ifdef ISC_PLATFORM_USETHREADS
#ifdef DNS_BENCHMARK_TESTS
/*
}
#endif /* DNS_BENCHMARK_TESTS */
-#endif /* ISC_PLATFORM_USETHREADS */
/*
* Main
ATF_TP_ADD_TC(tp, rbt_addname);
ATF_TP_ADD_TC(tp, rbt_deletename);
ATF_TP_ADD_TC(tp, rbt_nodechain);
-#ifdef ISC_PLATFORM_USETHREADS
#ifdef DNS_BENCHMARK_TESTS
ATF_TP_ADD_TC(tp, benchmark);
#endif /* DNS_BENCHMARK_TESTS */
-#endif /* ISC_PLATFORM_USETHREADS */
return (atf_no_error());
}
epoch_to_yyyymmdd(time_t when) {
struct tm *tm;
-#if defined(ISC_PLATFORM_USETHREADS) && !defined(WIN32)
+#if !defined(WIN32)
struct tm tm0;
tm = localtime_r(&when, &tm0);
#else
if (result != ISC_R_SUCCESS) {
UNLOCK_ZONE(zone);
secure = NULL;
-#ifdef ISC_PLATFORM_USETHREADS
- isc_thread_yield();
-#endif
goto again;
}
if (result != ISC_R_SUCCESS) {
UNLOCK_ZONE(zone);
secure = NULL;
-#if ISC_PLATFORM_USETHREADS
- isc_thread_yield();
-#endif
goto again;
}
}
if (result != ISC_R_SUCCESS) {
UNLOCK_ZONE(zone);
secure = NULL;
-#if ISC_PLATFORM_USETHREADS
- isc_thread_yield();
-#endif
goto again;
}
}
if (result != ISC_R_SUCCESS) {
UNLOCK_ZONE(zone);
secure = NULL;
-#if ISC_PLATFORM_USETHREADS
- isc_thread_yield();
-#endif
goto again;
}
}
if (result != ISC_R_SUCCESS) {
UNLOCK_ZONE(zone);
secure = NULL;
-#if ISC_PLATFORM_USETHREADS
- isc_thread_yield();
-#endif
goto again;
}
}
if (result != ISC_R_SUCCESS) {
UNLOCK_ZONE(zone);
secure = NULL;
-#if ISC_PLATFORM_USETHREADS
- isc_thread_yield();
-#endif
goto again;
}
}
#define DNS_CONF "/etc/dns.conf"
#endif
-#ifndef ISC_PLATFORM_USETHREADS
-irs_context_t *irs_g_context = NULL;
-#else
static isc_boolean_t thread_key_initialized = ISC_FALSE;
static isc_mutex_t thread_key_mutex;
static isc_thread_key_t irs_context_key;
static isc_once_t once = ISC_ONCE_INIT;
-#endif
struct irs_context {
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
static void
free_specific_context(void *arg) {
irs_context_t *context = arg;
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
isc_result_t
irs_context_get(irs_context_t **contextp) {
REQUIRE(contextp != NULL && *contextp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
- if (irs_g_context == NULL) {
- result = irs_context_create(&irs_g_context);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- context = irs_g_context;
-#else
result = thread_key_init();
if (result != ISC_R_SUCCESS)
return (result);
return (result);
}
}
-#endif /* ISC_PLATFORM_USETHREADS */
*contextp = context;
*contextp = NULL;
-#ifndef ISC_PLATFORM_USETHREADS
- irs_g_context = NULL;
-#else
(void)isc_thread_key_setspecific(irs_context_key, NULL);
-#endif
}
isc_mem_t *
*** Miscellaneous.
***/
-/*
- * Defined if we are using threads.
- */
-@ISC_PLATFORM_USETHREADS@
-
/*
* Defined if unistd.h does not cause fd_set to be delared.
*/
/*
* Sample implementations
*/
-#ifdef ISC_PLATFORM_USETHREADS
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD)
#define ISC_REFCOUNT_HAVEATOMIC 1
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE))
} while (0)
#endif /* (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD) */
-#else /* ISC_PLATFORM_USETHREADS */
-
-typedef struct isc_refcount {
- int refs;
-} isc_refcount_t;
-
-#define isc_refcount_destroy(rp) ISC_REQUIRE((rp)->refs == 0)
-#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
-
-#define isc_refcount_increment0(rp, tp) \
- do { \
- unsigned int *_tmp = (unsigned int *)(tp); \
- int _n = ++(rp)->refs; \
- if (_tmp != NULL) \
- *_tmp = _n; \
- } while (0)
-
-#define isc_refcount_increment(rp, tp) \
- do { \
- unsigned int *_tmp = (unsigned int *)(tp); \
- int _n; \
- ISC_REQUIRE((rp)->refs > 0); \
- _n = ++(rp)->refs; \
- if (_tmp != NULL) \
- *_tmp = _n; \
- } while (0)
-
-#define isc_refcount_decrement(rp, tp) \
- do { \
- unsigned int *_tmp = (unsigned int *)(tp); \
- int _n; \
- ISC_REQUIRE((rp)->refs > 0); \
- _n = --(rp)->refs; \
- if (_tmp != NULL) \
- *_tmp = _n; \
- } while (0)
-
-#endif /* ISC_PLATFORM_USETHREADS */
isc_result_t
isc_refcount_init(isc_refcount_t *ref, unsigned int n);
isc_rwlocktype_write
} isc_rwlocktype_t;
-#ifdef ISC_PLATFORM_USETHREADS
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || (defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG))
#define ISC_RWLOCK_USEATOMIC 1
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE))
isc_rwlocktype_t original;
#endif /* ISC_RWLOCK_USEATOMIC */
};
-#else /* ISC_PLATFORM_USETHREADS */
-struct isc_rwlock {
- unsigned int magic;
- isc_rwlocktype_t type;
- unsigned int active;
-};
-#endif /* ISC_PLATFORM_USETHREADS */
-
isc_result_t
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
* These functions allow unit tests to manipulate the processing
* of the task queue. They are not intended as part of the public API.
*/
-#if defined(ISC_PLATFORM_USETHREADS)
void
isc__taskmgr_pause(isc_taskmgr_t *taskmgr);
void
isc__taskmgr_resume(isc_taskmgr_t *taskmgr);
-#else
-isc_boolean_t
-isc__taskmgr_ready(isc_taskmgr_t *taskmgr);
-
-isc_result_t
-isc__taskmgr_dispatch(isc_taskmgr_t *taskmgr);
-#endif /* !ISC_PLATFORM_USETHREADS */
ISC_LANG_ENDDECLS
REQUIRE(ref != NULL);
ref->refs = n;
-#if defined(ISC_PLATFORM_USETHREADS) && !defined(ISC_REFCOUNT_HAVEATOMIC)
+#if !defined(ISC_REFCOUNT_HAVEATOMIC)
return (isc_mutex_init(&ref->lock));
#else
return (ISC_R_SUCCESS);
#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
-#ifdef ISC_PLATFORM_USETHREADS
-
#ifndef RWLOCK_DEFAULT_READ_QUOTA
#define RWLOCK_DEFAULT_READ_QUOTA 4
#endif
}
#endif /* ISC_RWLOCK_USEATOMIC */
-#else /* ISC_PLATFORM_USETHREADS */
-
-isc_result_t
-isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
- unsigned int write_quota)
-{
- REQUIRE(rwl != NULL);
-
- UNUSED(read_quota);
- UNUSED(write_quota);
-
- rwl->type = isc_rwlocktype_read;
- rwl->active = 0;
- rwl->magic = RWLOCK_MAGIC;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
- REQUIRE(VALID_RWLOCK(rwl));
-
- if (type == isc_rwlocktype_read) {
- if (rwl->type != isc_rwlocktype_read && rwl->active != 0)
- return (ISC_R_LOCKBUSY);
- rwl->type = isc_rwlocktype_read;
- rwl->active++;
- } else {
- if (rwl->active != 0)
- return (ISC_R_LOCKBUSY);
- rwl->type = isc_rwlocktype_write;
- rwl->active = 1;
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
- return (isc_rwlock_lock(rwl, type));
-}
-
-isc_result_t
-isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(VALID_RWLOCK(rwl));
- REQUIRE(rwl->type == isc_rwlocktype_read);
- REQUIRE(rwl->active != 0);
-
- /* If we are the only reader then succeed. */
- if (rwl->active == 1)
- rwl->type = isc_rwlocktype_write;
- else
- result = ISC_R_LOCKBUSY;
- return (result);
-}
-
-void
-isc_rwlock_downgrade(isc_rwlock_t *rwl) {
-
- REQUIRE(VALID_RWLOCK(rwl));
- REQUIRE(rwl->type == isc_rwlocktype_write);
- REQUIRE(rwl->active == 1);
-
- rwl->type = isc_rwlocktype_read;
-}
-
-isc_result_t
-isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
- REQUIRE(VALID_RWLOCK(rwl));
- REQUIRE(rwl->type == type);
-
- UNUSED(type);
-
- INSIST(rwl->active > 0);
- rwl->active--;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-isc_rwlock_destroy(isc_rwlock_t *rwl) {
- REQUIRE(rwl != NULL);
- REQUIRE(rwl->active == 0);
- rwl->magic = 0;
-}
-
-#endif /* ISC_PLATFORM_USETHREADS */
* is expected to have a separate manager; no "worker threads" are shared by
* the application threads.
*/
-#ifdef ISC_PLATFORM_USETHREADS
-#define USE_WORKER_THREADS
-#else
-#define USE_SHARED_MANAGER
-#endif /* ISC_PLATFORM_USETHREADS */
-
#ifdef ISC_TASK_TRACE
#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
task, isc_thread_self(), (m))
isc_taskmgr_t common;
isc_mem_t * mctx;
isc_mutex_t lock;
-#ifdef ISC_PLATFORM_USETHREADS
unsigned int workers;
isc_thread_t * threads;
-#endif /* ISC_PLATFORM_USETHREADS */
/* Locked by task manager lock. */
unsigned int default_quantum;
LIST(isc__task_t) tasks;
isc__tasklist_t ready_tasks;
isc__tasklist_t ready_priority_tasks;
isc_taskmgrmode_t mode;
-#ifdef ISC_PLATFORM_USETHREADS
isc_condition_t work_available;
isc_condition_t exclusive_granted;
isc_condition_t paused;
-#endif /* ISC_PLATFORM_USETHREADS */
unsigned int tasks_running;
unsigned int tasks_ready;
isc_boolean_t pause_requested;
*/
isc_mutex_t excl_lock;
isc__task_t *excl;
-#ifdef USE_SHARED_MANAGER
- unsigned int refs;
-#endif /* ISC_PLATFORM_USETHREADS */
};
#define DEFAULT_TASKMGR_QUANTUM 10
#define DEFAULT_DEFAULT_QUANTUM 5
#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
-#ifdef USE_SHARED_MANAGER
-static isc__taskmgr_t *taskmgr = NULL;
-#endif /* USE_SHARED_MANAGER */
-
/*%
* The following are intended for internal use (indicated by "isc__"
* prefix) but are not declared as static, allowing direct access from
LOCK(&manager->lock);
UNLINK(manager->tasks, task, link);
-#ifdef USE_WORKER_THREADS
if (FINISHED(manager)) {
/*
* All tasks have completed and the
*/
BROADCAST(&manager->work_available);
}
-#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
DESTROYLOCK(&task->lock);
static inline void
task_ready(isc__task_t *task) {
isc__taskmgr_t *manager = task->manager;
-#ifdef USE_WORKER_THREADS
isc_boolean_t has_privilege = isc__task_privilege((isc_task_t *) task);
-#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
REQUIRE(task->state == task_state_ready);
LOCK(&manager->lock);
push_readyq(manager, task);
-#ifdef USE_WORKER_THREADS
if (manager->mode == isc_taskmgrmode_normal || has_privilege)
SIGNAL(&manager->work_available);
-#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
}
static void
dispatch(isc__taskmgr_t *manager) {
isc__task_t *task;
-#ifndef USE_WORKER_THREADS
unsigned int total_dispatch_count = 0;
isc__tasklist_t new_ready_tasks;
isc__tasklist_t new_priority_tasks;
unsigned int tasks_ready = 0;
-#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
* unlocks. The while expression is always protected by the lock.
*/
-#ifndef USE_WORKER_THREADS
ISC_LIST_INIT(new_ready_tasks);
ISC_LIST_INIT(new_priority_tasks);
-#endif
LOCK(&manager->lock);
while (!FINISHED(manager)) {
-#ifdef USE_WORKER_THREADS
/*
* For reasons similar to those given in the comment in
* isc_task_send() above, it is safe for us to dequeue
ISC_MSGSET_TASK,
ISC_MSG_AWAKE, "awake"));
}
-#else /* USE_WORKER_THREADS */
- if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||
- empty_readyq(manager))
- break;
-#endif /* USE_WORKER_THREADS */
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
ISC_MSG_WORKING, "working"));
LOCK(&task->lock);
}
dispatch_count++;
-#ifndef USE_WORKER_THREADS
- total_dispatch_count++;
-#endif /* USE_WORKER_THREADS */
}
if (task->references == 0 &&
LOCK(&manager->lock);
manager->tasks_running--;
-#ifdef USE_WORKER_THREADS
if (manager->exclusive_requested &&
manager->tasks_running == 1) {
SIGNAL(&manager->exclusive_granted);
manager->tasks_running == 0) {
SIGNAL(&manager->paused);
}
-#endif /* USE_WORKER_THREADS */
if (requeue) {
/*
* We know we're awake, so we don't have
* were usually nonempty, the 'optimization'
* might even hurt rather than help.
*/
-#ifdef USE_WORKER_THREADS
push_readyq(manager, task);
-#else
- ENQUEUE(new_ready_tasks, task, ready_link);
- if ((task->flags & TASK_F_PRIVILEGED) != 0)
- ENQUEUE(new_priority_tasks, task,
- ready_priority_link);
- tasks_ready++;
-#endif
}
}
-#ifdef USE_WORKER_THREADS
/*
* If we are in privileged execution mode and there are no
* tasks remaining on the current ready queue, then
if (!empty_readyq(manager))
BROADCAST(&manager->work_available);
}
-#endif
}
-#ifndef USE_WORKER_THREADS
- ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link);
- ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks,
- ready_priority_link);
- manager->tasks_ready += tasks_ready;
- if (empty_readyq(manager))
- manager->mode = isc_taskmgrmode_normal;
-#endif
-
UNLOCK(&manager->lock);
}
-#ifdef USE_WORKER_THREADS
static isc_threadresult_t
#ifdef _WIN32
WINAPI
return ((isc_threadresult_t)0);
}
-#endif /* USE_WORKER_THREADS */
static void
manager_free(isc__taskmgr_t *manager) {
isc_mem_t *mctx;
-#ifdef USE_WORKER_THREADS
(void)isc_condition_destroy(&manager->exclusive_granted);
(void)isc_condition_destroy(&manager->work_available);
(void)isc_condition_destroy(&manager->paused);
isc_mem_free(manager->mctx, manager->threads);
-#endif /* USE_WORKER_THREADS */
DESTROYLOCK(&manager->lock);
DESTROYLOCK(&manager->excl_lock);
manager->common.impmagic = 0;
mctx = manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
-
-#ifdef USE_SHARED_MANAGER
- taskmgr = NULL;
-#endif /* USE_SHARED_MANAGER */
}
isc_result_t
REQUIRE(workers > 0);
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef USE_WORKER_THREADS
- UNUSED(i);
- UNUSED(started);
-#endif
-
-#ifdef USE_SHARED_MANAGER
- if (taskmgr != NULL) {
- if (taskmgr->refs == 0)
- return (ISC_R_SHUTTINGDOWN);
- taskmgr->refs++;
- *managerp = (isc_taskmgr_t *)taskmgr;
- return (ISC_R_SUCCESS);
- }
-#endif /* USE_SHARED_MANAGER */
-
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
goto cleanup_mgr;
}
-#ifdef USE_WORKER_THREADS
manager->workers = 0;
manager->threads = isc_mem_allocate(mctx,
workers * sizeof(isc_thread_t));
result = ISC_R_UNEXPECTED;
goto cleanup_exclusivegranted;
}
-#endif /* USE_WORKER_THREADS */
if (default_quantum == 0)
default_quantum = DEFAULT_DEFAULT_QUANTUM;
manager->default_quantum = default_quantum;
isc_mem_attach(mctx, &manager->mctx);
-#ifdef USE_WORKER_THREADS
LOCK(&manager->lock);
/*
* Start workers.
return (ISC_R_NOTHREADS);
}
isc_thread_setconcurrency(workers);
-#endif /* USE_WORKER_THREADS */
-#ifdef USE_SHARED_MANAGER
- manager->refs = 1;
- taskmgr = manager;
-#endif /* USE_SHARED_MANAGER */
*managerp = (isc_taskmgr_t *)manager;
return (ISC_R_SUCCESS);
-#ifdef USE_WORKER_THREADS
cleanup_exclusivegranted:
(void)isc_condition_destroy(&manager->exclusive_granted);
cleanup_workavailable:
isc_mem_free(mctx, manager->threads);
cleanup_lock:
DESTROYLOCK(&manager->lock);
-#endif
cleanup_mgr:
isc_mem_put(mctx, manager, sizeof(*manager));
return (result);
manager = (isc__taskmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
-#ifndef USE_WORKER_THREADS
- UNUSED(i);
-#endif /* USE_WORKER_THREADS */
-
-#ifdef USE_SHARED_MANAGER
- manager->refs--;
- if (manager->refs > 0) {
- *managerp = NULL;
- return;
- }
-#endif
-
XTHREADTRACE("isc_taskmgr_destroy");
/*
* Only one non-worker thread may ever call this routine.
push_readyq(manager, task);
UNLOCK(&task->lock);
}
-#ifdef USE_WORKER_THREADS
/*
* Wake up any sleeping workers. This ensures we get work done if
* there's work left to do, and if there are already no tasks left
*/
for (i = 0; i < manager->workers; i++)
(void)isc_thread_join(manager->threads[i], NULL);
-#else /* USE_WORKER_THREADS */
- /*
- * Dispatch the shutdown events.
- */
- UNLOCK(&manager->lock);
- while (isc__taskmgr_ready((isc_taskmgr_t *)manager))
- (void)isc__taskmgr_dispatch((isc_taskmgr_t *)manager);
- if (!ISC_LIST_EMPTY(manager->tasks)) {
- isc__task_t *t;
- isc_mem_printallactive(stderr);
- for (t = ISC_LIST_HEAD(manager->tasks);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- fprintf(stderr, "task: %p (%s)\n", t, t->name);
- }
- }
- INSIST(ISC_LIST_EMPTY(manager->tasks));
-#ifdef USE_SHARED_MANAGER
- taskmgr = NULL;
-#endif
-#endif /* USE_WORKER_THREADS */
manager_free(manager);
return (mode);
}
-#ifndef USE_WORKER_THREADS
-isc_boolean_t
-isc__taskmgr_ready(isc_taskmgr_t *manager0) {
- isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
- isc_boolean_t is_ready;
-
-#ifdef USE_SHARED_MANAGER
- if (manager == NULL)
- manager = taskmgr;
-#endif
- if (manager == NULL)
- return (ISC_FALSE);
-
- LOCK(&manager->lock);
- is_ready = !empty_readyq(manager);
- UNLOCK(&manager->lock);
-
- return (is_ready);
-}
-
-isc_result_t
-isc__taskmgr_dispatch(isc_taskmgr_t *manager0) {
- isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
-
-#ifdef USE_SHARED_MANAGER
- if (manager == NULL)
- manager = taskmgr;
-#endif
- if (manager == NULL)
- return (ISC_R_NOTFOUND);
-
- dispatch(manager);
-
- return (ISC_R_SUCCESS);
-}
-
-#else
void
isc__taskmgr_pause(isc_taskmgr_t *manager0) {
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
}
UNLOCK(&manager->lock);
}
-#endif /* USE_WORKER_THREADS */
void
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) {
isc_result_t
isc__task_beginexclusive(isc_task_t *task0) {
-#ifdef USE_WORKER_THREADS
isc__task_t *task = (isc__task_t *)task0;
isc__taskmgr_t *manager = task->manager;
WAIT(&manager->exclusive_granted, &manager->lock);
}
UNLOCK(&manager->lock);
-#else
- UNUSED(task0);
-#endif
return (ISC_R_SUCCESS);
}
void
isc__task_endexclusive(isc_task_t *task0) {
-#ifdef USE_WORKER_THREADS
isc__task_t *task = (isc__task_t *)task0;
isc__taskmgr_t *manager = task->manager;
manager->exclusive_requested = ISC_FALSE;
BROADCAST(&manager->work_available);
UNLOCK(&manager->lock);
-#else
- UNUSED(task0);
-#endif
}
void
* on which type is enabled.
*/
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model"));
-#ifdef ISC_PLATFORM_USETHREADS
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded"));
TRY0(xmlTextWriterEndElement(writer)); /* type */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads"));
TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers));
TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */
-#else /* ISC_PLATFORM_USETHREADS */
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
- TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded"));
- TRY0(xmlTextWriterEndElement(writer)); /* type */
-
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
- TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs));
- TRY0(xmlTextWriterEndElement(writer)); /* references */
-#endif /* ISC_PLATFORM_USETHREADS */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"));
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
* Write out the thread-model, and some details about each depending
* on which type is enabled.
*/
-#ifdef ISC_PLATFORM_USETHREADS
obj = json_object_new_string("threaded");
CHECKMEM(obj);
json_object_object_add(tasks, "thread-model", obj);
obj = json_object_new_int(mgr->workers);
CHECKMEM(obj);
json_object_object_add(tasks, "worker-threads", obj);
-#else /* ISC_PLATFORM_USETHREADS */
- obj = json_object_new_string("non-threaded");
- CHECKMEM(obj);
- json_object_object_add(tasks, "thread-model", obj);
-
- obj = json_object_new_int(mgr->refs);
- CHECKMEM(obj);
- json_object_object_add(tasks, "references", obj);
-#endif /* ISC_PLATFORM_USETHREADS */
obj = json_object_new_int(mgr->default_quantum);
CHECKMEM(obj);
char *p;
if (workers == 0) {
-#ifdef ISC_PLATFORM_USETHREADS
workers = isc_os_ncpus();
-#else
- workers = 1;
-#endif
}
p = getenv("ISC_TASK_WORKERS");
CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
}
-#ifdef ISC_PLATFORM_USETHREADS
ncpus = isc_os_ncpus();
-#else
- ncpus = 1;
-#endif
if (start_managers) {
CHECK(create_managers(workers));
waitfor(completion_t *completion) {
int i = 0;
while (!completion->done && i++ < 5000) {
-#ifndef ISC_PLATFORM_USETHREADS
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
-#endif
isc_test_nap(1000);
}
if (completion->done)
static void
waitbody(void) {
-#ifndef ISC_PLATFORM_USETHREADS
- struct timeval tv;
- isc_socketwait_t *swait = NULL;
-
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
- if (socketmgr != NULL) {
- tv.tv_sec = 0;
- tv.tv_usec = 1000 ;
- if (isc__socketmgr_waitevents(socketmgr, &tv, &swait) > 0)
- isc__socketmgr_dispatch(socketmgr, swait);
- } else
-#endif
isc_test_nap(1000);
}
static int active[10];
static isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
static isc_condition_t cv;
-#endif
static void
set(isc_task_t *task, isc_event_t *event) {
isc_task_send(task, &event);
while ((a == 0 || b == 0) && i++ < 5000) {
-#ifndef ISC_PLATFORM_USETHREADS
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
-#endif
isc_test_nap(1000);
}
result = isc_test_begin(NULL, ISC_TRUE, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Pause the task manager so we can fill up the work queue
* without things happening while we do it.
*/
isc__taskmgr_pause(taskmgr);
-#endif
result = isc_task_create(taskmgr, 0, &task1);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
-#ifdef ISC_PLATFORM_USETHREADS
isc__taskmgr_resume(taskmgr);
-#endif
/* We're waiting for *all* variables to be set */
while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) {
-#ifndef ISC_PLATFORM_USETHREADS
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
-#endif
isc_test_nap(1000);
}
result = isc_test_begin(NULL, ISC_TRUE, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Pause the task manager so we can fill up the work queue
* without things happening while we do it.
*/
isc__taskmgr_pause(taskmgr);
-#endif
result = isc_task_create(taskmgr, 0, &task1);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
-#ifdef ISC_PLATFORM_USETHREADS
isc__taskmgr_resume(taskmgr);
-#endif
/* We're waiting for all variables to be set. */
while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) &&
i++ < 5000) {
-#ifndef ISC_PLATFORM_USETHREADS
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
-#endif
isc_test_nap(1000);
}
isc_test_end();
}
-/*
- * The remainder of these tests require threads
- */
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Max tasks test:
* The task system can create and execute many tasks. Tests with 10000.
ATF_TC_BODY(purgeevent_notpurge, tc) {
try_purgeevent(ISC_FALSE);
}
-#endif
/*
* Main
ATF_TP_ADD_TC(tp, privilege_drop);
ATF_TP_ADD_TC(tp, basic);
ATF_TP_ADD_TC(tp, task_exclusive);
-
-#ifdef ISC_PLATFORM_USETHREADS
ATF_TP_ADD_TC(tp, manytasks);
ATF_TP_ADD_TC(tp, shutdown);
ATF_TP_ADD_TC(tp, post_shutdown);
ATF_TP_ADD_TC(tp, purgerange);
ATF_TP_ADD_TC(tp, purgeevent);
ATF_TP_ADD_TC(tp, purgeevent_notpurge);
-#endif
-
return (atf_no_error());
}
#include "isctest.h"
-/*
- * This entire test requires threads.
- */
-#ifdef ISC_PLATFORM_USETHREADS
-
/*
* Helper functions
*/
isc_test_end();
}
-#else
-ATF_TC(untested);
-ATF_TC_HEAD(untested, tc) {
- atf_tc_set_md_var(tc, "descr", "skipping nsec3 test");
-}
-ATF_TC_BODY(untested, tc) {
- UNUSED(tc);
- atf_tc_skip("DNSSEC not available");
-}
-#endif
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
-#ifdef ISC_PLATFORM_USETHREADS
ATF_TP_ADD_TC(tp, ticker);
ATF_TP_ADD_TC(tp, once_life);
ATF_TP_ADD_TC(tp, once_idle);
ATF_TP_ADD_TC(tp, reset);
ATF_TP_ADD_TC(tp, purge);
-#else
- ATF_TP_ADD_TC(tp, untested);
-#endif
-
return (atf_no_error());
}
#include <openssl/err.h>
#endif
-/* See task.c about the following definition: */
-#ifdef ISC_PLATFORM_USETHREADS
-#define USE_TIMER_THREAD
-#else
-#define USE_SHARED_MANAGER
-#endif /* ISC_PLATFORM_USETHREADS */
-
-#ifndef USE_TIMER_THREAD
-#include "timer_p.h"
-#endif /* USE_TIMER_THREAD */
-
#ifdef ISC_TIMER_TRACE
#define XTRACE(s) fprintf(stderr, "%s\n", (s))
#define XTRACEID(s, t) fprintf(stderr, "%s %p\n", (s), (t))
LIST(isc__timer_t) timers;
unsigned int nscheduled;
isc_time_t due;
-#ifdef USE_TIMER_THREAD
isc_condition_t wakeup;
isc_thread_t thread;
-#endif /* USE_TIMER_THREAD */
-#ifdef USE_SHARED_MANAGER
- unsigned int refs;
-#endif /* USE_SHARED_MANAGER */
isc_heap_t * heap;
};
(void *)isc_timermgr_poke
};
-#ifdef USE_SHARED_MANAGER
-/*!
- * If the manager is supposed to be shared, there can be only one.
- */
-static isc__timermgr_t *timermgr = NULL;
-#endif /* USE_SHARED_MANAGER */
-
static inline isc_result_t
schedule(isc__timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
isc_result_t result;
isc__timermgr_t *manager;
isc_time_t due;
int cmp;
-#ifdef USE_TIMER_THREAD
isc_boolean_t timedwait;
-#endif
/*!
* Note: the caller must ensure locking.
REQUIRE(timer->type != isc_timertype_inactive);
-#ifndef USE_TIMER_THREAD
UNUSED(signal_ok);
-#endif /* USE_TIMER_THREAD */
manager = timer->manager;
-#ifdef USE_TIMER_THREAD
/*!
* If the manager was timed wait, we may need to signal the
* manager to force a wakeup.
*/
timedwait = ISC_TF(manager->nscheduled > 0 &&
isc_time_seconds(&manager->due) != 0);
-#endif
/*
* Compute the new due time.
* the current "next" timer. We do this either by waking up the
* run thread, or explicitly setting the value in the manager.
*/
-#ifdef USE_TIMER_THREAD
/*
* This is a temporary (probably) hack to fix a bug on tru64 5.1
"signal (schedule)"));
SIGNAL(&manager->wakeup);
}
-#else /* USE_TIMER_THREAD */
- if (timer->index == 1 &&
- isc_time_compare(&timer->due, &manager->due) < 0)
- manager->due = timer->due;
-#endif /* USE_TIMER_THREAD */
return (ISC_R_SUCCESS);
}
static inline void
deschedule(isc__timer_t *timer) {
-#ifdef USE_TIMER_THREAD
isc_boolean_t need_wakeup = ISC_FALSE;
-#endif
isc__timermgr_t *manager;
/*
manager = timer->manager;
if (timer->index > 0) {
-#ifdef USE_TIMER_THREAD
if (timer->index == 1)
need_wakeup = ISC_TRUE;
-#endif
isc_heap_delete(manager->heap, timer->index);
timer->index = 0;
INSIST(manager->nscheduled > 0);
manager->nscheduled--;
-#ifdef USE_TIMER_THREAD
if (need_wakeup) {
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
ISC_MSG_SIGNALDESCHED,
"signal (deschedule)"));
SIGNAL(&manager->wakeup);
}
-#endif /* USE_TIMER_THREAD */
}
}
}
}
-#ifdef USE_TIMER_THREAD
static isc_threadresult_t
#ifdef _WIN32 /* XXXDCL */
WINAPI
return ((isc_threadresult_t)0);
}
-#endif /* USE_TIMER_THREAD */
static isc_boolean_t
sooner(void *v1, void *v2) {
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifdef USE_SHARED_MANAGER
- if (timermgr != NULL) {
- timermgr->refs++;
- *managerp = (isc_timermgr_t *)timermgr;
- return (ISC_R_SUCCESS);
- }
-#endif /* USE_SHARED_MANAGER */
-
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
return (result);
}
isc_mem_attach(mctx, &manager->mctx);
-#ifdef USE_TIMER_THREAD
if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) {
isc_mem_detach(&manager->mctx);
DESTROYLOCK(&manager->lock);
return (ISC_R_UNEXPECTED);
}
isc_thread_setname(manager->thread, "isc-timer");
-#endif
-#ifdef USE_SHARED_MANAGER
- manager->refs = 1;
- timermgr = manager;
-#endif /* USE_SHARED_MANAGER */
*managerp = (isc_timermgr_t *)manager;
void
isc_timermgr_poke(isc_timermgr_t *manager0) {
-#ifdef USE_TIMER_THREAD
isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
REQUIRE(VALID_MANAGER(manager));
SIGNAL(&manager->wakeup);
-#else
- UNUSED(manager0);
-#endif
}
void
LOCK(&manager->lock);
-#ifdef USE_SHARED_MANAGER
- manager->refs--;
- if (manager->refs > 0) {
- UNLOCK(&manager->lock);
- *managerp = NULL;
- return;
- }
- timermgr = NULL;
-#endif /* USE_SHARED_MANAGER */
-
-#ifndef USE_TIMER_THREAD
- isc__timermgr_dispatch((isc_timermgr_t *)manager);
-#endif
-
REQUIRE(EMPTY(manager->timers));
manager->done = ISC_TRUE;
-#ifdef USE_TIMER_THREAD
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
ISC_MSG_SIGNALDESTROY, "signal (destroy)"));
SIGNAL(&manager->wakeup);
-#endif /* USE_TIMER_THREAD */
UNLOCK(&manager->lock);
-#ifdef USE_TIMER_THREAD
/*
* Wait for thread to exit.
*/
"isc_thread_join() %s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
-#endif /* USE_TIMER_THREAD */
/*
* Clean up.
*/
-#ifdef USE_TIMER_THREAD
(void)isc_condition_destroy(&manager->wakeup);
-#endif /* USE_TIMER_THREAD */
DESTROYLOCK(&manager->lock);
isc_heap_destroy(&manager->heap);
manager->common.impmagic = 0;
*managerp = NULL;
-#ifdef USE_SHARED_MANAGER
- timermgr = NULL;
-#endif
-}
-
-#ifndef USE_TIMER_THREAD
-isc_result_t
-isc__timermgr_nextevent(isc_timermgr_t *manager0, isc_time_t *when) {
- isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
-
-#ifdef USE_SHARED_MANAGER
- if (manager == NULL)
- manager = timermgr;
-#endif
- if (manager == NULL || manager->nscheduled == 0)
- return (ISC_R_NOTFOUND);
- *when = manager->due;
- return (ISC_R_SUCCESS);
-}
-
-void
-isc__timermgr_dispatch(isc_timermgr_t *manager0) {
- isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
- isc_time_t now;
-
-#ifdef USE_SHARED_MANAGER
- if (manager == NULL)
- manager = timermgr;
-#endif
- if (manager == NULL)
- return;
- TIME_NOW(&now);
- dispatch(manager, &now);
}
-#endif /* USE_TIMER_THREAD */
isc_result_t
isc__timer_register(void) {
#include <isc/time.h>
#include <isc/util.h>
-#ifdef ISC_PLATFORM_USETHREADS
#include <pthread.h>
-#endif
/*%
* For BIND9 internal applications built with threads, we use a single app
* For other cases (including BIND9 built without threads) an app context acts
* as an event loop dispatching various events.
*/
-#ifndef ISC_PLATFORM_USETHREADS
-#include "../timer_p.h"
-#include "socket_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
-
-#ifdef ISC_PLATFORM_USETHREADS
static pthread_t blockedthread;
-#endif /* ISC_PLATFORM_USETHREADS */
/*%
* The following are intended for internal use (indicated by "isc__"
isc_taskmgr_t *taskmgr;
isc_socketmgr_t *socketmgr;
isc_timermgr_t *timermgr;
-#ifdef ISC_PLATFORM_USETHREADS
isc_mutex_t readylock;
isc_condition_t ready;
-#endif /* ISC_PLATFORM_USETHREADS */
} isc__appctx_t;
static isc__appctx_t isc_g_appctx;
}
#endif
-#ifdef ISC_PLATFORM_USETHREADS
#ifdef HAVE_LINUXTHREADS
main_thread = pthread_self();
#endif /* HAVE_LINUXTHREADS */
if (result != ISC_R_SUCCESS)
goto cleanup_rlock;
- result = isc_mutex_init(&ctx->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rcond;
-#else /* ISC_PLATFORM_USETHREADS */
result = isc_mutex_init(&ctx->lock);
if (result != ISC_R_SUCCESS)
goto cleanup;
-#endif /* ISC_PLATFORM_USETHREADS */
ISC_LIST_INIT(ctx->on_run);
goto cleanup;
#endif
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Block SIGHUP, SIGINT, SIGTERM.
*
result = ISC_R_UNEXPECTED;
goto cleanup;
}
-#else /* ISC_PLATFORM_USETHREADS */
- /*
- * Unblock SIGHUP, SIGINT, SIGTERM.
- *
- * If we're not using threads, we need to make sure that SIGHUP,
- * SIGINT and SIGTERM are not inherited as blocked from the parent
- * process.
- */
- if (sigemptyset(&sset) != 0 ||
- sigaddset(&sset, SIGHUP) != 0 ||
- sigaddset(&sset, SIGINT) != 0 ||
- sigaddset(&sset, SIGTERM) != 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_start() sigsetops: %s", strbuf);
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
- presult = sigprocmask(SIG_UNBLOCK, &sset, NULL);
- if (presult != 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_start() sigprocmask: %s", strbuf);
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
-#endif /* ISC_PLATFORM_USETHREADS */
return (ISC_R_SUCCESS);
cleanup:
-#ifdef ISC_PLATFORM_USETHREADS
- cleanup_rcond:
(void)isc_condition_destroy(&ctx->ready);
cleanup_rlock:
(void)isc_mutex_destroy(&ctx->readylock);
-#endif /* ISC_PLATFORM_USETHREADS */
return (result);
}
return (result);
}
-#ifndef ISC_PLATFORM_USETHREADS
-/*!
- * Event loop for nonthreaded programs.
- */
-static isc_result_t
-evloop(isc__appctx_t *ctx) {
- isc_result_t result;
-
- while (!ctx->want_shutdown) {
- int n;
- isc_time_t when, now;
- struct timeval tv, *tvp;
- isc_socketwait_t *swait;
- isc_boolean_t readytasks;
- isc_boolean_t call_timer_dispatch = ISC_FALSE;
-
- /*
- * Check the reload (or suspend) case first for exiting the
- * loop as fast as possible in case:
- * - the direct call to isc__taskmgr_dispatch() in
- * isc__app_ctxrun() completes all the tasks so far,
- * - there is thus currently no active task, and
- * - there is a timer event
- */
- if (ctx->want_reload) {
- ctx->want_reload = ISC_FALSE;
- return (ISC_R_RELOAD);
- }
-
- readytasks = isc__taskmgr_ready(ctx->taskmgr);
- if (readytasks) {
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- tvp = &tv;
- call_timer_dispatch = ISC_TRUE;
- } else {
- result = isc__timermgr_nextevent(ctx->timermgr, &when);
- if (result != ISC_R_SUCCESS)
- tvp = NULL;
- else {
- isc_uint64_t us;
-
- TIME_NOW(&now);
- us = isc_time_microdiff(&when, &now);
- if (us == 0)
- call_timer_dispatch = ISC_TRUE;
- tv.tv_sec = us / 1000000;
- tv.tv_usec = us % 1000000;
- tvp = &tv;
- }
- }
-
- swait = NULL;
- n = isc__socketmgr_waitevents(ctx->socketmgr, tvp, &swait);
-
- if (n == 0 || call_timer_dispatch) {
- /*
- * We call isc__timermgr_dispatch() only when
- * necessary, in order to reduce overhead. If the
- * select() call indicates a timeout, we need the
- * dispatch. Even if not, if we set the 0-timeout
- * for the select() call, we need to check the timer
- * events. In the 'readytasks' case, there may be no
- * timeout event actually, but there is no other way
- * to reduce the overhead.
- * Note that we do not have to worry about the case
- * where a new timer is inserted during the select()
- * call, since this loop only runs in the non-thread
- * mode.
- */
- isc__timermgr_dispatch(ctx->timermgr);
- }
- if (n > 0)
- (void)isc__socketmgr_dispatch(ctx->socketmgr, swait);
- (void)isc__taskmgr_dispatch(ctx->taskmgr);
- }
- return (ISC_R_SUCCESS);
-}
-
-/*
- * This is a gross hack to support waiting for condition
- * variables in nonthreaded programs in a limited way;
- * see lib/isc/nothreads/include/isc/condition.h.
- * We implement isc_condition_wait() by entering the
- * event loop recursively until the want_shutdown flag
- * is set by isc_condition_signal().
- */
-
-/*!
- * \brief True if we are currently executing in the recursive
- * event loop.
- */
-static isc_boolean_t in_recursive_evloop = ISC_FALSE;
-
-/*!
- * \brief True if we are exiting the event loop as the result of
- * a call to isc_condition_signal() rather than a shutdown
- * or reload.
- */
-static isc_boolean_t signalled = ISC_FALSE;
-
-isc_result_t
-isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) {
- isc_result_t result;
-
- UNUSED(cp);
- UNUSED(mp);
-
- INSIST(!in_recursive_evloop);
- in_recursive_evloop = ISC_TRUE;
-
- INSIST(*mp == 1); /* Mutex must be locked on entry. */
- --*mp;
-
- result = evloop(&isc_g_appctx);
- if (result == ISC_R_RELOAD)
- isc_g_appctx.want_reload = ISC_TRUE;
- if (signalled) {
- isc_g_appctx.want_shutdown = ISC_FALSE;
- signalled = ISC_FALSE;
- }
-
- ++*mp;
- in_recursive_evloop = ISC_FALSE;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc__nothread_signal_hack(isc_condition_t *cp) {
-
- UNUSED(cp);
-
- INSIST(in_recursive_evloop);
-
- isc_g_appctx.want_shutdown = ISC_TRUE;
- signalled = ISC_TRUE;
- return (ISC_R_SUCCESS);
-}
-#endif /* ISC_PLATFORM_USETHREADS */
-
isc_result_t
isc__app_ctxrun(isc_appctx_t *ctx0) {
isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
int result;
isc_event_t *event, *next_event;
isc_task_t *task;
-#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
char strbuf[ISC_STRERRORSIZE];
#ifdef HAVE_SIGWAIT
int sig;
#endif /* HAVE_SIGWAIT */
-#endif /* ISC_PLATFORM_USETHREADS */
REQUIRE(VALID_APPCTX(ctx));
UNLOCK(&ctx->lock);
-#ifndef ISC_PLATFORM_USETHREADS
- if (isc_bind9 && ctx == &isc_g_appctx) {
- result = handle_signal(SIGHUP, reload_action);
- if (result != ISC_R_SUCCESS)
- return (ISC_R_SUCCESS);
- }
-
- (void) isc__taskmgr_dispatch(ctx->taskmgr);
- result = evloop(ctx);
- return (result);
-#else /* ISC_PLATFORM_USETHREADS */
/*
* BIND9 internal tools using multiple contexts do not
* rely on signal.
}
return (ISC_R_SUCCESS);
-#endif /* ISC_PLATFORM_USETHREADS */
}
isc_result_t
isc__app_ctxshutdown(isc_appctx_t *ctx0) {
isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_boolean_t want_kill = ISC_TRUE;
-#ifdef ISC_PLATFORM_USETHREADS
char strbuf[ISC_STRERRORSIZE];
-#endif /* ISC_PLATFORM_USETHREADS */
REQUIRE(VALID_APPCTX(ctx));
/* BIND9 internal, but using multiple contexts */
ctx->want_shutdown = ISC_TRUE;
else {
-#ifndef ISC_PLATFORM_USETHREADS
- ctx->want_shutdown = ISC_TRUE;
-#else /* ISC_PLATFORM_USETHREADS */
#ifdef HAVE_LINUXTHREADS
if (isc_bind9) {
/* BIND9 internal, single context */
UNLOCK(&ctx->readylock);
SIGNAL(&ctx->ready);
}
-#endif /* ISC_PLATFORM_USETHREADS */
}
}
isc__app_ctxsuspend(isc_appctx_t *ctx0) {
isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_boolean_t want_kill = ISC_TRUE;
-#ifdef ISC_PLATFORM_USETHREADS
char strbuf[ISC_STRERRORSIZE];
-#endif
REQUIRE(VALID_APPCTX(ctx));
/* BIND9 internal, but using multiple contexts */
ctx->want_reload = ISC_TRUE;
else {
-#ifndef ISC_PLATFORM_USETHREADS
- ctx->want_reload = ISC_TRUE;
-#else /* ISC_PLATFORM_USETHREADS */
#ifdef HAVE_LINUXTHREADS
if (isc_bind9) {
/* BIND9 internal, single context */
UNLOCK(&ctx->readylock);
SIGNAL(&ctx->ready);
}
-#endif /* ISC_PLATFORM_USETHREADS */
}
}
void
isc__app_block(void) {
-#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
-#endif /* ISC_PLATFORM_USETHREADS */
REQUIRE(isc_g_appctx.running);
REQUIRE(!isc_g_appctx.blocked);
isc_g_appctx.blocked = ISC_TRUE;
-#ifdef ISC_PLATFORM_USETHREADS
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 /* ISC_PLATFORM_USETHREADS */
}
void
isc__app_unblock(void) {
-#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
-#endif /* ISC_PLATFORM_USETHREADS */
REQUIRE(isc_g_appctx.running);
REQUIRE(isc_g_appctx.blocked);
isc_g_appctx.blocked = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
REQUIRE(blockedthread == pthread_self());
RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
sigaddset(&sset, SIGINT) == 0 &&
sigaddset(&sset, SIGTERM) == 0);
RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0);
-#endif /* ISC_PLATFORM_USETHREADS */
}
isc_result_t
#include "errno2result.h"
-/* See task.c about the following definition: */
-#ifdef ISC_PLATFORM_USETHREADS
-#define USE_WATCHER_THREAD
-#else
-#define USE_SHARED_MANAGER
-#endif /* ISC_PLATFORM_USETHREADS */
-
-#ifndef USE_WATCHER_THREAD
-#include "socket_p.h"
-#endif /* USE_WATCHER_THREAD */
-
#if defined(SO_BSDCOMPAT) && defined(__linux__)
#include <sys/utsname.h>
#endif
#define USE_SELECT
#endif /* ISC_PLATFORM_HAVEKQUEUE */
-#ifndef USE_WATCHER_THREAD
-#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
-struct isc_socketwait {
- int nevents;
-};
-#elif defined (USE_SELECT)
-struct isc_socketwait {
- fd_set *readset;
- fd_set *writeset;
- int nfds;
- int maxfd;
-};
-#endif /* USE_KQUEUE */
-#endif /* !USE_WATCHER_THREAD */
-
/*
* Set by the -T dscp option on the command line. If set to a value
* other than -1, we check to make sure DSCP values match it, and
/*%
* Size of per-FD lock buckets.
*/
-#ifdef ISC_PLATFORM_USETHREADS
#define FDLOCK_COUNT 1024
#define FDLOCK_ID(fd) ((fd) % FDLOCK_COUNT)
-#else
-#define FDLOCK_COUNT 1
-#define FDLOCK_ID(fd) 0
-#endif /* ISC_PLATFORM_USETHREADS */
/*%
* Maximum number of events communicated with the kernel. There should normally
int fd_bufsize;
#endif /* USE_SELECT */
unsigned int maxsocks;
-#ifdef ISC_PLATFORM_USETHREADS
int pipe_fds[2];
-#endif
/* Locked by fdlock. */
isc__socket_t **fds;
int maxfd;
#endif /* USE_SELECT */
int reserved; /* unlocked */
-#ifdef USE_WATCHER_THREAD
isc_thread_t watcher;
isc_condition_t shutdown_ok;
-#else /* USE_WATCHER_THREAD */
- unsigned int refs;
-#endif /* USE_WATCHER_THREAD */
int maxudp;
};
-#ifdef USE_SHARED_MANAGER
-static isc__socketmgr_t *socketmgr = NULL;
-#endif /* USE_SHARED_MANAGER */
-
#define CLOSED 0 /* this one must be zero */
#define MANAGED 1
#define CLOSE_PENDING 2
struct msghdr *, struct iovec *, size_t *);
static void build_msghdr_recv(isc__socket_t *, char *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
-#ifdef USE_WATCHER_THREAD
static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager);
-#endif
static void setdscp(isc__socket_t *sock, isc_dscp_t dscp);
/*%
isc_sockstatscounter_rawactive
};
-#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \
- defined(USE_WATCHER_THREAD)
static void
manager_log(isc__socketmgr_t *sockmgr,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_log_write(isc_lctx, category, module, level,
"sockmgr %p: %s", sockmgr, msgbuf);
}
-#endif
static void
socket_log(isc__socket_t *sock, const isc_sockaddr_t *address,
}
}
-#ifdef USE_WATCHER_THREAD
/*
* Poke the select loop when there is something for us to do.
* The write is required (by POSIX) to complete. That is, we
*fd = buf[0];
*msg = buf[1];
}
-#else /* USE_WATCHER_THREAD */
-/*
- * Update the state of the socketmgr when something changes.
- */
-static void
-select_poke(isc__socketmgr_t *manager, int fd, int msg) {
- if (msg == SELECT_POKE_SHUTDOWN)
- return;
- else if (fd >= 0)
- wakeup_socket(manager, fd, msg);
- return;
-}
-#endif /* USE_WATCHER_THREAD */
/*
* Make a fd non-blocking.
}
UNLOCK(&manager->fdlock[lockid]);
}
-#ifdef ISC_PLATFORM_USETHREADS
if (manager->maxfd < manager->pipe_fds[0])
manager->maxfd = manager->pipe_fds[0];
-#endif
}
UNLOCK(&manager->lock);
ISC_LIST_UNLINK(manager->socklist, sock, link);
-#ifdef USE_WATCHER_THREAD
if (ISC_LIST_EMPTY(manager->socklist))
SIGNAL(&manager->shutdown_ok);
-#endif /* USE_WATCHER_THREAD */
/* can't unlock manager as its memory context is still used */
free_socket(sockp);
int i;
isc_boolean_t readable, writable;
isc_boolean_t done = ISC_FALSE;
-#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
-#endif
if (nevents == manager->nevents) {
/*
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].ident < manager->maxsocks);
-#ifdef USE_WATCHER_THREAD
if (events[i].ident == (uintptr_t)manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
}
-#endif
readable = ISC_TF(events[i].filter == EVFILT_READ);
writable = ISC_TF(events[i].filter == EVFILT_WRITE);
process_fd(manager, events[i].ident, readable, writable);
}
-#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
-#endif
return (done);
}
{
int i;
isc_boolean_t done = ISC_FALSE;
-#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
-#endif
if (nevents == manager->nevents) {
manager_log(manager, ISC_LOGCATEGORY_GENERAL,
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].data.fd < (int)manager->maxsocks);
-#ifdef USE_WATCHER_THREAD
if (events[i].data.fd == manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
}
-#endif
if ((events[i].events & EPOLLERR) != 0 ||
(events[i].events & EPOLLHUP) != 0) {
/*
(events[i].events & EPOLLOUT) != 0);
}
-#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
-#endif
return (done);
}
process_fds(isc__socketmgr_t *manager, struct pollfd *events, int nevents) {
int i;
isc_boolean_t done = ISC_FALSE;
-#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
-#endif
if (nevents == manager->nevents) {
manager_log(manager, ISC_LOGCATEGORY_GENERAL,
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].fd < (int)manager->maxsocks);
-#ifdef USE_WATCHER_THREAD
if (events[i].fd == manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
}
-#endif
process_fd(manager, events[i].fd,
(events[i].events & POLLIN) != 0,
(events[i].events & POLLOUT) != 0);
}
-#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
-#endif
return (done);
}
REQUIRE(maxfd <= (int)manager->maxsocks);
for (i = 0; i < maxfd; i++) {
-#ifdef USE_WATCHER_THREAD
if (i == manager->pipe_fds[0] || i == manager->pipe_fds[1])
continue;
-#endif /* USE_WATCHER_THREAD */
process_fd(manager, i, FD_ISSET(i, readfds),
FD_ISSET(i, writefds));
}
}
#endif
-#ifdef USE_WATCHER_THREAD
static isc_boolean_t
process_ctlfd(isc__socketmgr_t *manager) {
int msg, fd;
return ((isc_threadresult_t)0);
}
-#endif /* USE_WATCHER_THREAD */
void
isc__socketmgr_setreserved(isc_socketmgr_t *manager0, isc_uint32_t reserved) {
return (result);
}
-#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->kqueue_fd);
sizeof(struct kevent) * manager->nevents);
return (result);
}
-#endif /* USE_WATCHER_THREAD */
#elif defined(USE_EPOLL)
manager->nevents = ISC_SOCKET_MAXEVENTS;
manager->events = isc_mem_get(mctx, sizeof(struct epoll_event) *
sizeof(struct epoll_event) * manager->nevents);
return (result);
}
-#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->epoll_fd);
sizeof(struct epoll_event) * manager->nevents);
return (result);
}
-#endif /* USE_WATCHER_THREAD */
#elif defined(USE_DEVPOLL)
manager->nevents = ISC_SOCKET_MAXEVENTS;
result = isc_resource_getcurlimit(isc_resource_openfiles,
sizeof(pollinfo_t) * manager->maxsocks);
return (result);
}
-#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->devpoll_fd);
sizeof(pollinfo_t) * manager->maxsocks);
return (result);
}
-#endif /* USE_WATCHER_THREAD */
#elif defined(USE_SELECT)
UNUSED(result);
memset(manager->read_fds, 0, manager->fd_bufsize);
memset(manager->write_fds, 0, manager->fd_bufsize);
-#ifdef USE_WATCHER_THREAD
(void)watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
manager->maxfd = manager->pipe_fds[0];
-#else /* USE_WATCHER_THREAD */
- manager->maxfd = 0;
-#endif /* USE_WATCHER_THREAD */
#endif /* USE_KQUEUE */
return (ISC_R_SUCCESS);
static void
cleanup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) {
-#ifdef USE_WATCHER_THREAD
isc_result_t result;
result = unwatch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
}
-#endif /* USE_WATCHER_THREAD */
#ifdef USE_KQUEUE
close(manager->kqueue_fd);
{
int i;
isc__socketmgr_t *manager;
-#ifdef USE_WATCHER_THREAD
char strbuf[ISC_STRERRORSIZE];
-#endif
isc_result_t result;
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifdef USE_SHARED_MANAGER
- if (socketmgr != NULL) {
- /* Don't allow maxsocks to be updated */
- if (maxsocks > 0 && socketmgr->maxsocks != maxsocks)
- return (ISC_R_EXISTS);
-
- socketmgr->refs++;
- *managerp = (isc_socketmgr_t *)socketmgr;
- return (ISC_R_SUCCESS);
- }
-#endif /* USE_SHARED_MANAGER */
-
if (maxsocks == 0)
maxsocks = ISC_SOCKET_MAXSOCKETS;
}
}
-#ifdef USE_WATCHER_THREAD
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_condition_init() %s",
}
RUNTIME_CHECK(make_nonblock(manager->pipe_fds[0]) == ISC_R_SUCCESS);
-#if 0
- RUNTIME_CHECK(make_nonblock(manager->pipe_fds[1]) == ISC_R_SUCCESS);
-#endif
-#endif /* USE_WATCHER_THREAD */
-
-#ifdef USE_SHARED_MANAGER
- manager->refs = 1;
-#endif /* USE_SHARED_MANAGER */
/*
* Set up initial state for the select loop
memset(manager->fdstate, 0, manager->maxsocks * sizeof(int));
-#ifdef USE_WATCHER_THREAD
/*
* Start up the select/poll thread.
*/
goto cleanup;
}
isc_thread_setname(manager->watcher, "isc-socket");
-#endif /* USE_WATCHER_THREAD */
isc_mem_attach(mctx, &manager->mctx);
-#ifdef USE_SHARED_MANAGER
- socketmgr = manager;
-#endif /* USE_SHARED_MANAGER */
*managerp = (isc_socketmgr_t *)manager;
return (ISC_R_SUCCESS);
cleanup:
-#ifdef USE_WATCHER_THREAD
(void)close(manager->pipe_fds[0]);
(void)close(manager->pipe_fds[1]);
-#endif /* USE_WATCHER_THREAD */
-#ifdef USE_WATCHER_THREAD
cleanup_condition:
(void)isc_condition_destroy(&manager->shutdown_ok);
-#endif /* USE_WATCHER_THREAD */
cleanup_lock:
manager = (isc__socketmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
-#ifdef USE_SHARED_MANAGER
- manager->refs--;
- if (manager->refs > 0) {
- *managerp = NULL;
- return;
- }
- socketmgr = NULL;
-#endif /* USE_SHARED_MANAGER */
-
LOCK(&manager->lock);
/*
* Wait for all sockets to be destroyed.
*/
while (!ISC_LIST_EMPTY(manager->socklist)) {
-#ifdef USE_WATCHER_THREAD
manager_log(manager, CREATION, "%s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET,
ISC_MSG_SOCKETSREMAIN,
"sockets exist"));
WAIT(&manager->shutdown_ok, &manager->lock);
-#else /* USE_WATCHER_THREAD */
- UNLOCK(&manager->lock);
- isc__taskmgr_dispatch(NULL);
- LOCK(&manager->lock);
-#endif /* USE_WATCHER_THREAD */
}
UNLOCK(&manager->lock);
*/
select_poke(manager, 0, SELECT_POKE_SHUTDOWN);
-#ifdef USE_WATCHER_THREAD
/*
* Wait for thread to exit.
*/
"isc_thread_join() %s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
-#endif /* USE_WATCHER_THREAD */
/*
* Clean up.
*/
cleanup_watcher(manager->mctx, manager);
-#ifdef USE_WATCHER_THREAD
(void)close(manager->pipe_fds[0]);
(void)close(manager->pipe_fds[1]);
(void)isc_condition_destroy(&manager->shutdown_ok);
-#endif /* USE_WATCHER_THREAD */
for (i = 0; i < (int)manager->maxsocks; i++)
if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */
*managerp = NULL;
-#ifdef USE_SHARED_MANAGER
- socketmgr = NULL;
-#endif
}
static isc_result_t
return (allocate_socketevent(mctx, sender, eventtype, action, arg));
}
-#ifndef USE_WATCHER_THREAD
-/*
- * In our assumed scenario, we can simply use a single static object.
- * XXX: this is not true if the application uses multiple threads with
- * 'multi-context' mode. Fixing this is a future TODO item.
- */
-static isc_socketwait_t swait_private;
-
-int
-isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp,
- isc_socketwait_t **swaitp)
-{
- isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
- int n;
-#ifdef USE_KQUEUE
- struct timespec ts, *tsp;
-#endif
-#ifdef USE_EPOLL
- int timeout;
-#endif
-#ifdef USE_DEVPOLL
- isc_result_t result;
- int pass;
- struct dvpoll dvp;
-#endif
-
- REQUIRE(swaitp != NULL && *swaitp == NULL);
-
-#ifdef USE_SHARED_MANAGER
- if (manager == NULL)
- manager = socketmgr;
-#endif
- if (manager == NULL)
- return (0);
-
-#ifdef USE_KQUEUE
- if (tvp != NULL) {
- ts.tv_sec = tvp->tv_sec;
- ts.tv_nsec = tvp->tv_usec * 1000;
- tsp = &ts;
- } else
- tsp = NULL;
- swait_private.nevents = kevent(manager->kqueue_fd, NULL, 0,
- manager->events, manager->nevents,
- tsp);
- n = swait_private.nevents;
-#elif defined(USE_EPOLL)
- if (tvp != NULL)
- timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000;
- else
- timeout = -1;
- swait_private.nevents = epoll_wait(manager->epoll_fd,
- manager->events,
- manager->nevents, timeout);
- n = swait_private.nevents;
-#elif defined(USE_DEVPOLL)
- /*
- * Re-probe every thousand calls.
- */
- if (manager->calls++ > 1000U) {
- result = isc_resource_getcurlimit(isc_resource_openfiles,
- &manager->open_max);
- if (result != ISC_R_SUCCESS)
- manager->open_max = 64;
- manager->calls = 0;
- }
- for (pass = 0; pass < 2; pass++) {
- dvp.dp_fds = manager->events;
- dvp.dp_nfds = manager->nevents;
- if (dvp.dp_nfds >= manager->open_max)
- dvp.dp_nfds = manager->open_max - 1;
- if (tvp != NULL) {
- dvp.dp_timeout = tvp->tv_sec * 1000 +
- (tvp->tv_usec + 999) / 1000;
- } else
- dvp.dp_timeout = -1;
- n = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
- if (n == -1 && errno == EINVAL) {
- /*
- * {OPEN_MAX} may have dropped. Look
- * up the current value and try again.
- */
- result = isc_resource_getcurlimit(
- isc_resource_openfiles,
- &manager->open_max);
- if (result != ISC_R_SUCCESS)
- manager->open_max = 64;
- } else
- break;
- }
- swait_private.nevents = n;
-#elif defined(USE_SELECT)
- memmove(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize);
- memmove(manager->write_fds_copy, manager->write_fds,
- manager->fd_bufsize);
-
- swait_private.readset = manager->read_fds_copy;
- swait_private.writeset = manager->write_fds_copy;
- swait_private.maxfd = manager->maxfd + 1;
-
- n = select(swait_private.maxfd, swait_private.readset,
- swait_private.writeset, NULL, tvp);
-#endif
-
- *swaitp = &swait_private;
- return (n);
-}
-
-isc_result_t
-isc__socketmgr_dispatch(isc_socketmgr_t *manager0, isc_socketwait_t *swait) {
- isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
-
- REQUIRE(swait == &swait_private);
-
-#ifdef USE_SHARED_MANAGER
- if (manager == NULL)
- manager = socketmgr;
-#endif
- if (manager == NULL)
- return (ISC_R_NOTFOUND);
-
-#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
- (void)process_fds(manager, manager->events, swait->nevents);
- return (ISC_R_SUCCESS);
-#elif defined(USE_SELECT)
- process_fds(manager, swait->maxfd, swait->readset, swait->writeset);
- return (ISC_R_SUCCESS);
-#endif
-}
-#endif /* USE_WATCHER_THREAD */
-
void
isc__socket_setname(isc_socket_t *socket0, const char *name, void *tag) {
isc__socket_t *sock = (isc__socket_t *)socket0;
LOCK(&mgr->lock);
-#ifdef USE_SHARED_MANAGER
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
- TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs));
- TRY0(xmlTextWriterEndElement(writer));
-#endif /* USE_SHARED_MANAGER */
-
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"));
sock = ISC_LIST_HEAD(mgr->socklist);
while (sock != NULL) {
LOCK(&mgr->lock);
-#ifdef USE_SHARED_MANAGER
- obj = json_object_new_int(mgr->refs);
- CHECKMEM(obj);
- json_object_object_add(stats, "references", obj);
-#endif /* USE_SHARED_MANAGER */
-
sock = ISC_LIST_HEAD(mgr->socklist);
while (sock != NULL) {
json_object *states, *entry = json_object_new_object();
isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
REQUIRE(len > 0);
now = (time_t) t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%d-%b-%Y %X", localtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%d-%b-%Y %X", localtime(&now));
-#endif
INSIST(flen < len);
if (flen != 0)
snprintf(buf + flen, len - flen,
isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
* 5 spaces, 1 comma, 3 GMT, 2 %d, 4 %Y, 8 %H:%M:%S, 3+ %a, 3+ %b (29+)
*/
now = (time_t)t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT",
gmtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
-#endif
INSIST(flen < len);
}
isc_time_formatISO8601L(const isc_time_t *t, char *buf, unsigned int len) {
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
REQUIRE(len > 0);
now = (time_t)t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%S", localtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%S", localtime(&now));
-#endif
INSIST(flen < len);
}
isc_time_formatISO8601Lms(const isc_time_t *t, char *buf, unsigned int len) {
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
REQUIRE(len > 0);
now = (time_t)t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%S", localtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%S", localtime(&now));
-#endif
INSIST(flen < len);
if (flen > 0U && len - flen >= 6) {
snprintf(buf + flen, len - flen, ".%03u",
isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
REQUIRE(len > 0);
now = (time_t)t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
-#endif
INSIST(flen < len);
}
isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
REQUIRE(len > 0);
now = (time_t)t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
-#endif
INSIST(flen < len);
if (flen > 0U && len - flen >= 5) {
flen -= 1; /* rewind one character (Z) */
{
time_t now;
unsigned int flen;
-#ifdef ISC_PLATFORM_USETHREADS
struct tm tm;
-#endif
REQUIRE(t != NULL);
INSIST(t->nanoseconds < NS_PER_S);
REQUIRE(len > 0);
now = (time_t)t->seconds;
-#ifdef ISC_PLATFORM_USETHREADS
flen = strftime(buf, len, "%Y%m%d%H%M%S", gmtime_r(&now, &tm));
-#else
- flen = strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&now));
-#endif
INSIST(flen < len);
if (flen > 0U && len - flen >= 5) {
snprintf(buf + flen, len - flen, "%03u",
***** Platform-dependent defines.
*****/
-#define ISC_PLATFORM_USETHREADS 1
-
/*
* Some compatibility cludges
*/
LOCK(&mgr->lock);
-#ifndef ISC_PLATFORM_USETHREADS
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
- TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs));
- TRY0(xmlTextWriterEndElement(writer));
-#endif
-
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"));
sock = ISC_LIST_HEAD(mgr->socklist);
while (sock != NULL) {
isc_int32_t prev = val;
__asm__ volatile(
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xadd %0, %1"
:"=q"(prev)
:"m"(*p), "0"(prev)
isc_int64_t prev = val;
__asm__ volatile(
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xaddq %0, %1"
:"=q"(prev)
:"m"(*p), "0"(prev)
static __inline__ void
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
__asm__ volatile(
-#ifdef ISC_PLATFORM_USETHREADS
/*
* xchg should automatically lock memory, but we add it
* explicitly just in case (it at least doesn't harm)
*/
"lock;"
-#endif
"xchgl %1, %0"
:
static __inline__ void
isc_atomic_storeq(isc_int64_t *p, isc_int64_t val) {
__asm__ volatile(
-#ifdef ISC_PLATFORM_USETHREADS
/*
* xchg should automatically lock memory, but we add it
* explicitly just in case (it at least doesn't harm)
*/
"lock;"
-#endif
"xchgq %1, %0"
:
static __inline__ isc_int32_t
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
__asm__ volatile(
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"cmpxchgl %1, %2"
: "=a"(cmpval)
: "r"(val), "m"(*p), "a"(cmpval)
__asm (
"movl 8(%ebp), %ecx\n"
"movl 12(%ebp), %edx\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xadd %edx, (%ecx)\n"
/*
__asm (
"movl 8(%ebp), %ecx\n"
"movl 12(%ebp), %edx\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xchgl (%ecx), %edx\n"
);
}
"movl 8(%ebp), %ecx\n"
"movl 12(%ebp), %eax\n" /* must be %eax for cmpxchgl */
"movl 16(%ebp), %edx\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
/*
* If (%ecx) == %eax then (%ecx) := %edx.
__asm (
"movq %rdi, %rdx\n"
"movl %esi, %eax\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xadd %eax, (%rdx)\n"
/*
* XXX: assume %eax will be used as the return value.
__asm (
"movq %rdi, %rdx\n"
"movq %rsi, %rax\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xaddq %rax, (%rdx)\n"
/*
* XXX: assume %rax will be used as the return value.
__asm (
"movq %rdi, %rax\n"
"movl %esi, %edx\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xchgl (%rax), %edx\n"
);
}
__asm (
"movq %rdi, %rax\n"
"movq %rsi, %rdx\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
"xchgq (%rax), %rdx\n"
);
}
"movl %esi, %eax\n"
"movq %rdi, %rdx\n"
-#ifdef ISC_PLATFORM_USETHREADS
"lock;"
-#endif
/*
* If [%rdi] == %eax then [%rdi] := %ecx (equal to %edx
* from above), and %eax is untouched (equal to %esi)
*
* The state must be seeded so that it is not everywhere zero.
*/
-#if defined(ISC_PLATFORM_USETHREADS)
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
static volatile HANDLE _mutex = NULL;
#define _LOCK() pthread_mutex_lock(&_mutex)
#define _UNLOCK() pthread_mutex_unlock(&_mutex)
#endif /* defined(_WIN32) || defined(_WIN64) */
-#else /* defined(ISC_PLATFORM_USETHREADS) */
-#define _LOCK()
-#define _UNLOCK()
-#endif
static inline isc_uint32_t rotl(const isc_uint32_t x, int k) {
return (x << k) | (x >> (32 - k));
#define SEND_BUFFER_SIZE 4096
#define RECV_BUFFER_SIZE 4096
-#ifdef ISC_PLATFORM_USETHREADS
#define NMCTXS 100
/*%<
* Number of 'mctx pools' for clients. (Should this be configurable?)
* completely avoiding contentions among threads for an authoritative-only
* server.
*/
-#else
-#define NMCTXS 0
-/*%<
- * If named with built without thread, simply share manager's context. Using
- * a separate context in this case would simply waste memory.
- */
-#endif
#define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */
#define ECS_SIZE 20U /* 2 + 1 + 1 + [0..16] */
}
while (run_managers && !shutdown_done) {
-#ifndef ISC_PLATFORM_USETHREADS
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
-#else
/*
* There's no straightforward way to determine
* whether all the clients have shut down, so
* we'll just sleep for a bit and hope.
*/
ns_test_nap(500000);
-#endif
}
if (sctx != NULL)
isc_result_t result;
ns_listenlist_t *listenon = NULL;
isc_event_t *event = NULL;
-#ifdef ISC_PLATFORM_USETHREADS
ncpus = isc_os_ncpus();
-#else
- ncpus = 1;
-#endif
CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
scan_interfaces, NULL,
sizeof (isc_event_t));
isc_task_send(maintask, &event);
-#ifndef ISC_PLATFORM_USETHREADS
- while (isc__taskmgr_ready(taskmgr))
- isc__taskmgr_dispatch(taskmgr);
-#else
/*
* There's no straightforward way to determine
* whether the interfaces have been scanned,
* we'll just sleep for a bit and hope.
*/
ns_test_nap(500000);
-#endif
run_managers = ISC_TRUE;