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>
This commit is contained in:
Paul Gofman 2020-11-16 18:48:02 +03:00 committed by Alexandre Julliard
parent 358d4f5a91
commit 073b6dc240
1 changed files with 12 additions and 1 deletions

View File

@ -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;
}