Jacek Caban : win32u: Move user lock from user32.

Alexandre Julliard julliard at winehq.org
Tue Feb 22 16:06:51 CST 2022


Module: wine
Branch: master
Commit: 3e4f83f762943b4f3fe026754c2e87ec02209237
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3e4f83f762943b4f3fe026754c2e87ec02209237

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb 22 13:43:44 2022 +0100

win32u: Move user lock from user32.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/hook.c           |  2 --
 dlls/user32/user_main.c      | 20 +++-----------------
 dlls/win32u/hook.c           |  2 ++
 dlls/win32u/sysparams.c      | 39 +++++++++++++++++++++++++++++++++++++++
 dlls/win32u/win32u_private.h |  3 +++
 include/ntuser.h             |  1 +
 6 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 1ccd69f5a98..c068231cca7 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -651,8 +651,6 @@ BOOL WINAPI User32CallWinEventHook( const struct win_hook_proc_params *params, U
     WINEVENTPROC proc = params->proc;
     HMODULE free_module = 0;
 
-    USER_CheckNotLock(); /* FIXME: move to NtUserNotifyWinEvent */
-
     if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module ))) return FALSE;
 
     TRACE_(relay)( "\1Call winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c
index ea30772067d..47f7ec7513a 100644
--- a/dlls/user32/user_main.c
+++ b/dlls/user32/user_main.c
@@ -35,15 +35,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(graphics);
 
 HMODULE user32_module = 0;
 
-static CRITICAL_SECTION user_section;
-static CRITICAL_SECTION_DEBUG critsect_debug =
-{
-    0, 0, &user_section,
-    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
-      0, 0, { (DWORD_PTR)(__FILE__ ": user_section") }
-};
-static CRITICAL_SECTION user_section = { &critsect_debug, -1, 0, 0, 0, 0 };
-
 static DWORD exiting_thread_id;
 
 extern void WDML_NotifyThreadDetach(void);
@@ -53,7 +44,7 @@ extern void WDML_NotifyThreadDetach(void);
  */
 void USER_Lock(void)
 {
-    EnterCriticalSection( &user_section );
+    NtUserCallOneParam( 0, NtUserLock );
 }
 
 
@@ -62,7 +53,7 @@ void USER_Lock(void)
  */
 void USER_Unlock(void)
 {
-    LeaveCriticalSection( &user_section );
+    NtUserCallOneParam( 1, NtUserLock );
 }
 
 
@@ -73,11 +64,7 @@ void USER_Unlock(void)
  */
 void USER_CheckNotLock(void)
 {
-    if (RtlIsCriticalSectionLockedByThread(&user_section))
-    {
-        ERR( "BUG: holding USER lock\n" );
-        DebugBreak();
-    }
+    NtUserCallOneParam( 2, NtUserLock );
 }
 
 
@@ -237,7 +224,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
     case DLL_PROCESS_DETACH:
         USER_unload_driver();
         FreeLibrary(imm32_module);
-        DeleteCriticalSection(&user_section);
         break;
     }
     return ret;
diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c
index b390676fc60..427f4cc8527 100644
--- a/dlls/win32u/hook.c
+++ b/dlls/win32u/hook.c
@@ -254,6 +254,8 @@ void WINAPI NtUserNotifyWinEvent( DWORD event, HWND hwnd, LONG object_id, LONG c
 
     TRACE( "%04x, %p, %d, %d\n", event, hwnd, object_id, child_id );
 
+    user_check_not_lock();
+
     if (!hwnd)
     {
         SetLastError( ERROR_INVALID_WINDOW_HANDLE );
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index 58bd22a3adf..c2b09689c2b 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -25,6 +25,8 @@
 #endif
 
 #include <pthread.h>
+#include <assert.h>
+
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "ntgdi_private.h"
@@ -360,6 +362,30 @@ static RECT work_area;
 static HDC display_dc;
 static pthread_mutex_t display_dc_lock = PTHREAD_MUTEX_INITIALIZER;
 
+static pthread_mutex_t user_mutex;
+static unsigned int user_lock_thread, user_lock_rec;
+
+void user_lock(void)
+{
+    pthread_mutex_lock( &user_mutex );
+    if (!user_lock_rec++) user_lock_thread = GetCurrentThreadId();
+}
+
+void user_unlock(void)
+{
+    if (!--user_lock_rec) user_lock_thread = 0;
+    pthread_mutex_unlock( &user_mutex );
+}
+
+void user_check_not_lock(void)
+{
+    if (user_lock_thread == GetCurrentThreadId())
+    {
+        ERR( "BUG: holding USER lock\n" );
+        assert( 0 );
+    }
+}
+
 static HANDLE get_display_device_init_mutex( void )
 {
     static const WCHAR display_device_initW[] =
@@ -3008,6 +3034,7 @@ void sysparams_init(void)
 
     DWORD i, dispos, dpi_scaling;
     WCHAR layout[KL_NAMELENGTH];
+    pthread_mutexattr_t attr;
     HKEY hkey;
 
     static const WCHAR software_wineW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e'};
@@ -3018,6 +3045,11 @@ void sysparams_init(void)
     static const WCHAR kl_preloadW[] =
         {'K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','\\','P','r','e','l','o','a','d'};
 
+    pthread_mutexattr_init( &attr );
+    pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
+    pthread_mutex_init( &user_mutex, &attr );
+    pthread_mutexattr_destroy( &attr );
+
     if ((hkey = reg_create_key( hkcu_key, kl_preloadW, sizeof(kl_preloadW), 0, NULL )))
     {
         if (NtUserGetKeyboardLayoutName( layout ))
@@ -4550,6 +4582,13 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
         return get_entry( &entry_DESKPATTERN, 256, (WCHAR *)arg );
     case NtUserIncrementKeyStateCounter:
         return InterlockedAdd( &global_key_state_counter, arg );
+    case NtUserLock:
+        switch( arg )
+        {
+        case 0: user_lock(); return 0;
+        case 1: user_unlock(); return 0;
+        default: user_check_not_lock(); return 0;
+        }
     case NtUserSetCallbacks:
         return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg );
     default:
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index 3017b7e6a72..34b3b545129 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -263,6 +263,9 @@ extern HMONITOR monitor_from_rect( const RECT *rect, DWORD flags, UINT dpi ) DEC
 extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN;
 extern void register_window_surface( struct window_surface *old,
                                      struct window_surface *new ) DECLSPEC_HIDDEN;
+extern void user_lock(void) DECLSPEC_HIDDEN;
+extern void user_unlock(void) DECLSPEC_HIDDEN;
+extern void user_check_not_lock(void) DECLSPEC_HIDDEN;
 
 extern void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN;
 extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN;
diff --git a/include/ntuser.h b/include/ntuser.h
index a54da6095f1..f36549250bd 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -87,6 +87,7 @@ enum
     NtUserFlushWindowSurfaces,
     NtUserGetDeskPattern,
     NtUserIncrementKeyStateCounter,
+    NtUserLock,
     NtUserSetCallbacks,
 };
 




More information about the wine-cvs mailing list