From 3b0cb22eb6246b0da2b944e713f801339443303e Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Thu, 6 Aug 2026 14:07:15 +0200 Subject: [PATCH] servers: add option to build without window handler (Windows) curl already built like this in UWP mode; add a macro to allow building regular Win32 targets too, meaning without the hidden GUI window, window handler, and thus without support for shutting down `servers.exe` gracefully. To test the server in CI as a plain console app and remove one component/variable from the system, in an effort chasing flaky runs. The graceful option was used by `taskkill` (without `-f`) in runtests, and it has been disabled (in favor of always `-f` (forced) kill), in an attempt to avoid taskkill hanging. Those resolved, but general CI flakiness remained. We see `taskkill` invoked seldom per job, and in most of these cases it doesn't find the PID requested. It means the graceful option is not actually used since 2025-04, and rather rarely before that. Also just today, the callback and main loop received a few updates to avoid potentially unsafe calls and interaction with the ctrl handler. Not expecting anything breakthrough here. Also graceful shutdown is a useful feature to cleanup properly and to be in sync with other platforms. Also: GHA/windows: enable in Windows CI jobs. Ref: https://learn.microsoft.com/windows/console/registering-a-control-handler-function#listen-with-hidden-window-example Follow-up to 7db9947fcf5d3deebe98e7992ebedc9a2f624bf5 #22045 Follow-up to 9ea48811fed455d4a869eb100b2216f039f8677a #22487 Follow-up to b11e0026f71aa33b47d3b31f7c6a2aee4f929b12 #22495 Follow-up to 208b87744e8ce326e2569c2efd735da43ce74a0b #21039 Follow-up to f450f3801b6b9dff0ea280f5fb4bf28203f7b313 #19897 Follow-up to 2701ac6a4d16a62130dad05be1c484903b8545c7 #19421 Follow-up to 4e203f65a1e5e448daf1da2b8c3aaa33654dd080 #17054 Closes #22496 --- .github/workflows/windows.yml | 6 ++++-- tests/server/util.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 71921ea400..b7fc7c4c9f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -368,6 +368,7 @@ jobs: MATRIX_TYPE: '${{ matrix.type }}' TFLAGS: '${{ matrix.tflags }}' run: | + CPPFLAGS+=' -DCURL_DEBUG_NO_WIN32_WND' if [ "${MATRIX_TEST}" = 'uwp' ]; then CPPFLAGS+=' -DWINSTORECOMPAT -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WIN32_WINNT=0x0a00' if [[ "${MATRIX_ENV}" != 'clang'* ]]; then @@ -581,7 +582,7 @@ jobs: ver: '16.1.0' url: 'https://github.com/skeeto/w64devkit/releases/download/v2.8.0/w64devkit-x64-2.8.0.7z.exe' SHA256: 6252bf34fe2231a55ac7f03d482b36d2c7c58697990551bba508102cfb3f342e - config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_GCC_ANALYZER=ON' + config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_GCC_ANALYZER=ON -DCMAKE_C_FLAGS=-DCURL_DEBUG_NO_WIN32_WND' type: 'Debug' - name: 'schannel' # mingw-w64 10.0 sys: 'mingw64' @@ -590,7 +591,7 @@ jobs: ver: '9.5.0' url: 'https://github.com/brechtsanders/winlibs_mingw/releases/download/9.5.0-10.0.0-msvcrt-r1/winlibs-x86_64-posix-seh-gcc-9.5.0-mingw-w64msvcrt-10.0.0-r1.7z' SHA256: 41637132ea7dc36a7f86a1961eaa334c380b5a3423d36aecb481cabcd006e3fe - config: '-DBUILD_SHARED_LIBS=OFF -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=OFF -DCURL_DISABLE_VERBOSE_STRINGS=ON' + config: '-DBUILD_SHARED_LIBS=OFF -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=OFF -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCMAKE_C_FLAGS=-DCURL_DEBUG_NO_WIN32_WND' type: 'Release' tflags: 'skiprun' - name: 'schannel mbedtls U' # mingw-w64 6.0 @@ -1013,6 +1014,7 @@ jobs: cflags='' rcflags='' ldflags='' + cflags+=' -DCURL_DEBUG_NO_WIN32_WND' if [ "${MATRIX_PLAT}" = 'uwp' ]; then options+=' -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0' cflags+=' -DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP' diff --git a/tests/server/util.c b/tests/server/util.c index c2e1d52f60..b2e4d4535f 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -33,6 +33,10 @@ #include #endif +#if defined(CURL_WINDOWS_UWP) && !defined(CURL_DEBUG_NO_WIN32_WND) +#define CURL_DEBUG_NO_WIN32_WND +#endif + void loghex(const unsigned char *buffer, ssize_t len) { char data[12000]; @@ -450,7 +454,7 @@ static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType) /* stay signal-safe */ return TRUE; } -#ifndef CURL_WINDOWS_UWP +#ifndef CURL_DEBUG_NO_WIN32_WND static DWORD thread_main_id = 0; static HANDLE thread_main_window = NULL; static HWND hidden_main_window = NULL; @@ -538,7 +542,7 @@ static DWORD WINAPI main_window_loop(void *lpParameter) hidden_main_window = NULL; return (DWORD)msg.wParam; } -#endif /* CURL_WINDOWS_UWP */ +#endif /* !CURL_DEBUG_NO_WIN32_WND */ #endif /* !_WIN32 */ void install_signal_handlers(bool keep_sigalrm) @@ -592,7 +596,7 @@ void install_signal_handlers(bool keep_sigalrm) if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE)) logmsg("cannot install CTRL event handler"); -#ifndef CURL_WINDOWS_UWP +#ifndef CURL_DEBUG_NO_WIN32_WND thread_main_window = CreateThread(NULL, 0, &main_window_loop, GetModuleHandle(NULL), 0, &thread_main_id); if(!thread_main_window || !thread_main_id) @@ -629,7 +633,7 @@ void restore_signal_handlers(bool keep_sigalrm) #endif #else /* _WIN32 */ (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE); -#ifndef CURL_WINDOWS_UWP +#ifndef CURL_DEBUG_NO_WIN32_WND if(thread_main_window && thread_main_id) { if(PostThreadMessage(thread_main_id, WM_APP, 0, 0)) { if(WaitForSingleObjectEx(thread_main_window, INFINITE, TRUE)) {