]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Initialize the main thread trampoline for Windows Service process
authorOndřej Surý <ondrej@isc.org>
Tue, 31 Aug 2021 17:25:07 +0000 (17:25 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Tue, 31 Aug 2021 17:53:30 +0000 (17:53 +0000)
When BIND is running as a Windows Service the ISC library's
initializations initiated by the DLLMain loading procedure are
happening under the Windows Service Manager thread instead of
BIND's main thread.

This commit will make sure that BIND's main thread trampoline has
been initialized before running the main() function.

bin/named/win32/ntservice.c
lib/isc/include/isc/lib.h
lib/isc/lib.c
lib/isc/trampoline.c
lib/isc/trampoline_p.h
lib/isc/win32/libisc.def.in

index 02c3fe83afdd15ca49b7de5411587a562709d45f..e4ba9d9b095e50675898c081882afc50d49d8cc9 100644 (file)
@@ -30,11 +30,22 @@ static char ConsoleTitle[128];
 /*
  * Forward declarations
  */
+static int
+bindmain_service_wrapper(int argc, char *argv[]);
 void
 ServiceControl(DWORD dwCtrlCode);
 int
 bindmain(int, char *[]); /* From main.c */
 
+/*
+ * Initialize the ISC library running as a Windows Service before calling
+ * bindmain()
+ */
+static int
+bindmain_service_wrapper(int argc, char *argv[]) {
+       return (isc_lib_ntservice(bindmain, argc, argv));
+}
+
 /*
  * Initialize the Service by registering it.
  */
@@ -60,6 +71,7 @@ void
 ntservice_shutdown(void) {
        UpdateSCM(SERVICE_STOPPED);
 }
+
 /*
  * Routine to check if this is a service or a foreground program
  */
@@ -67,6 +79,7 @@ BOOL
 ntservice_isservice(void) {
        return (!foreground);
 }
+
 /*
  * ServiceControl(): Handles requests from the SCM and passes them on
  * to named.
@@ -159,7 +172,7 @@ main(int argc, char *argv[]) {
 
                SERVICE_TABLE_ENTRY dispatchTable[] = {
                        { TEXT(SERVICE_NAME),
-                         (LPSERVICE_MAIN_FUNCTION)bindmain },
+                         (LPSERVICE_MAIN_FUNCTION)bindmain_service_wrapper },
                        { NULL, NULL }
                };
 
index 05e6dfe608ccc972b565f40fff76ef1179f5755c..dff2ae6d6b5853438ccc88357ee70e1a416ff613 100644 (file)
@@ -27,10 +27,19 @@ isc_lib_register(void);
  * function very early in main().
  */
 
+#ifdef WIN32
+int
+isc_lib_ntservice(int(WINAPI *mainfunc)(int argc, char *argv[]), int argc,
+                 char *argv[]);
+/*!<
+ * \brief Execute a special routine needed when running as a Windows Service.
+ */
+#endif /* ifdef WIN32 */
+
 extern void
 isc_enable_constructors(void);
 /*!<
- * \bried Enable constructor linkage in non-libtool static builds
+ * \brief Enable constructor linkage in non-libtool static builds.
  */
 
 ISC_LANG_ENDDECLS
index f3576b2659cb3a8bc874cc42b959d7a0a6811794..056d58b5e8952d4b73c1d880ac9950e5eec5d39d 100644 (file)
@@ -34,6 +34,23 @@ isc_lib_register(void) {
        isc_bind9 = false;
 }
 
+#ifdef WIN32
+int
+isc_lib_ntservice(int(WINAPI *mainfunc)(int argc, char *argv[]), int argc,
+                 char *argv[]) {
+       isc__trampoline_t *trampoline = isc__trampoline_get(NULL, NULL);
+       int r;
+
+       isc__trampoline_attach(trampoline);
+
+       r = mainfunc(argc, argv);
+
+       isc__trampoline_detach(trampoline);
+
+       return (r);
+}
+#endif /* ifdef WIN32 */
+
 void
 isc__initialize(void) ISC_CONSTRUCTOR;
 void
index 9d3e9cf8a36aaf9b85e438f417a4a84a3e63a56a..a265cf156d372b2e41ef55c7ed8e2dcb384f865f 100644 (file)
@@ -154,8 +154,8 @@ done:
        return (trampoline);
 }
 
-static void
-trampoline_put(isc__trampoline_t *trampoline) {
+void
+isc__trampoline_detach(isc__trampoline_t *trampoline) {
        LOCK(&isc__trampoline_lock);
        REQUIRE(trampoline->tid > 0 &&
                (size_t)trampoline->tid < isc__trampoline_max);
@@ -174,11 +174,8 @@ trampoline_put(isc__trampoline_t *trampoline) {
        return;
 }
 
-isc_threadresult_t
-isc__trampoline_run(isc_threadarg_t arg) {
-       isc__trampoline_t *trampoline = (isc__trampoline_t *)arg;
-       isc_threadresult_t result;
-
+void
+isc__trampoline_attach(isc__trampoline_t *trampoline) {
        REQUIRE(trampoline->tid > 0 &&
                (size_t)trampoline->tid < isc__trampoline_max);
        REQUIRE(trampoline->self == ISC__TRAMPOLINE_UNUSED);
@@ -186,11 +183,19 @@ isc__trampoline_run(isc_threadarg_t arg) {
        /* Initialize the trampoline */
        isc_tid_v = trampoline->tid;
        trampoline->self = isc_thread_self();
+}
+
+isc_threadresult_t
+isc__trampoline_run(isc_threadarg_t arg) {
+       isc__trampoline_t *trampoline = (isc__trampoline_t *)arg;
+       isc_threadresult_t result;
+
+       isc__trampoline_attach(trampoline);
 
        /* Run the main function */
        result = (trampoline->start)(trampoline->arg);
 
-       trampoline_put(trampoline);
+       isc__trampoline_detach(trampoline);
 
        return (result);
 }
index 750f1f5550eeb3383eee361488145e3bdc714cf7..beff720f61f68ab59e992b4a1058633fd1bd917a 100644 (file)
@@ -63,6 +63,17 @@ isc__trampoline_get(isc_threadfunc_t start_routine, isc_threadarg_t arg);
  *\li  'start_routine' is a valid non-NULL thread start_routine
  */
 
+void
+isc__trampoline_attach(isc__trampoline_t *trampoline);
+void
+isc__trampoline_detach(isc__trampoline_t *trampoline);
+/*%<
+ * Attach/detach the trampoline to/from the current thread.
+ *
+ * Requires:
+ * \li  'trampoline' is a valid isc__trampoline_t
+ */
+
 isc_threadresult_t
 isc__trampoline_run(isc_threadarg_t arg);
 /*%<
index a132046a6fed23d18a29b9d35caa30c7e1372bd0..3858c4320db7b011e4b5c5b0931f066dbd1d5c49 100644 (file)
@@ -329,6 +329,7 @@ isc_lfsr_generate
 isc_lfsr_generate32
 isc_lfsr_init
 isc_lfsr_skip
+isc_lib_ntservice
 isc_lib_register
 isc_log_categorybyname
 isc_log_closefilelogs