[PATCH] user32: Avoid holding display_dc_section when creating display DC.

Paul Gofman pgofman at codeweavers.com
Mon Nov 16 09:48:02 CST 2020


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 at codeweavers.com>
---
 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;
 }
 
-- 
2.28.0




More information about the wine-devel mailing list