From 073b6dc240bada1f700a7c37d6797a6b15a176d2 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Mon, 16 Nov 2020 18:48:02 +0300 Subject: [PATCH] user32: Avoid holding display_dc_section when creating display DC. get_display_dc() may be locking display_dc_section at the end of user driver initialization in LoadCursorA() called from register_builtin_classes(). If the driver initialization initiated in CreateDCW() goes in parallel with the initialization started elsewhere without holding display_dc_section, the process can deadlock. Fixes random lockup on start in Hammerting. Signed-off-by: Paul Gofman Signed-off-by: Alexandre Julliard --- dlls/user32/sysparams.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 1381f387e03..a620116053a 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -548,7 +548,18 @@ static BOOL init_entry_string( struct sysparam_entry *entry, const WCHAR *str ) HDC get_display_dc(void) { EnterCriticalSection( &display_dc_section ); - if (!display_dc) display_dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL ); + if (!display_dc) + { + HDC dc; + + LeaveCriticalSection( &display_dc_section ); + dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL ); + EnterCriticalSection( &display_dc_section ); + if (display_dc) + DeleteDC(dc); + else + display_dc = dc; + } return display_dc; }