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 7db9947fcf #22045
Follow-up to 9ea48811fe #22487
Follow-up to b11e0026f7 #22495
Follow-up to 208b87744e #21039
Follow-up to f450f3801b #19897
Follow-up to 2701ac6a4d #19421
Follow-up to 4e203f65a1 #17054

Closes #22496
This commit is contained in:
Viktor Szakats 2026-08-06 14:07:15 +02:00
parent 45a84dfe06
commit 3b0cb22eb6
No known key found for this signature in database
2 changed files with 12 additions and 6 deletions

View file

@ -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'

View file

@ -33,6 +33,10 @@
#include <share.h>
#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)) {