Module: wine Branch: master Commit: 073b6dc240bada1f700a7c37d6797a6b15a176d2 URL: https://source.winehq.org/git/wine.git/?a=commit;h=073b6dc240bada1f700a7c37d...
Author: Paul Gofman pgofman@codeweavers.com Date: Mon Nov 16 18:48:02 2020 +0300
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 pgofman@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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; }