From 391f401f21894a35f7fe20352ae3b7ad63a7838c Mon Sep 17 00:00:00 2001 From: Alexandre Zollinger Chohfi Date: Thu, 22 Oct 2026 14:22:19 -0700 Subject: [PATCH] compat/poll: load user32 only when poll() runs On Windows, poll() waits with MsgWaitForMultipleObjects() and pumps window messages with PeekMessage(), TranslateMessage() and DispatchMessage(). These are the only functions git.exe imports from user32.dll, so every Git process loads user32, and with it gdi32, gdi32full, win32u and imm32, even though most commands never call poll(). Load the four functions with the existing lazyload helpers the first time poll() runs instead. If user32 cannot be loaded, the process cannot have a message queue to pump, so wait with WaitForMultipleObjects(). Signed-off-by: Alexandre Zollinger Chohfi --- compat/poll/poll.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/compat/poll/poll.c b/compat/poll/poll.c index 1205f09ce9fbc8..0be425c7005280 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -48,6 +48,7 @@ # include # include # include +# include "compat/win32/lazyload.h" #else # include # include @@ -473,6 +474,21 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) MSG msg; int rc = 0; nfds_t i; + /* + * Load the message-loop functions from user32 only when poll() runs, so + * that Git commands that never poll do not load user32 (and gdi32, + * win32u and imm32 with it) at start-up. + */ + DECLARE_PROC_ADDR(user32.dll, DWORD, WINAPI, MsgWaitForMultipleObjects, + DWORD, const HANDLE *, BOOL, DWORD, DWORD); + DECLARE_PROC_ADDR(user32.dll, BOOL, WINAPI, PeekMessageA, + LPMSG, HWND, UINT, UINT, UINT); + DECLARE_PROC_ADDR(user32.dll, BOOL, WINAPI, TranslateMessage, const MSG *); + DECLARE_PROC_ADDR(user32.dll, LRESULT, WINAPI, DispatchMessageA, const MSG *); + int have_user32 = INIT_PROC_ADDR(MsgWaitForMultipleObjects) && + INIT_PROC_ADDR(PeekMessageA) && + INIT_PROC_ADDR(TranslateMessage) && + INIT_PROC_ADDR(DispatchMessageA); if (nfd < 0 || timeout < -1) { @@ -574,6 +590,12 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) for (;;) { + if (!have_user32) + { + ret = WaitForMultipleObjects (nhandles, handle_array, FALSE, + wait_timeout); + break; + } ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE, wait_timeout, QS_ALLINPUT);