It was discovered that on some platforms (f.e. Alpine Linux with MUSL)
the result of isc_os_ncpus() call differ when called before and after we
drop privileges. This commit changes the isc_os_ncpus() call to cache
the result from the first call and thus always return the same value
during the runtime of the named. The first call to isc_os_ncpus() is
made as soon as possible on the library initalization.
#include <isc/bind9.h>
#include <isc/lib.h>
#include <isc/mem.h>
+#include <isc/os.h>
#include <isc/tls.h>
#include <isc/util.h>
isc__mem_initialize();
isc__tls_initialize();
isc__trampoline_initialize();
+ (void)isc_os_ncpus();
}
void
* information regarding copyright ownership.
*/
+#include <isc/once.h>
#include <isc/os.h>
+#include <isc/util.h>
+
+static isc_once_t ncpus_once = ISC_ONCE_INIT;
+static unsigned int ncpus = 0;
#ifdef HAVE_SYSCONF
}
#endif /* if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) */
-unsigned int
-isc_os_ncpus(void) {
- long ncpus = 0;
-
+static void
+ncpus_initialize(void) {
#if defined(HAVE_SYSCONF)
ncpus = sysconf_ncpus();
#endif /* if defined(HAVE_SYSCONF) */
if (ncpus <= 0) {
ncpus = 1;
}
+}
+
+unsigned int
+isc_os_ncpus(void) {
+ isc_result_t result = isc_once_do(&ncpus_once, ncpus_initialize);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ INSIST(ncpus > 0);
- return ((unsigned int)ncpus);
+ return (ncpus);
}