From 6e95a132bd80c0019df6cbfa4494dea619e8a4d3 Mon Sep 17 00:00:00 2001 From: Ahmed Arif Date: Fri, 26 Jun 2026 14:07:15 +0200 Subject: [PATCH] [WIN32SS:ENG/NTUSER] Use shared locks for display list lookups (#9090) - Use shared locks for the display device and PDEV lookup paths. These functions only walk existing lists and take references, while list updates and mode-switch paths still use exclusive locking. This avoids serializing read-only display queries unnecessarily. - Use shared locks for other read-only NtUser calls. --- win32ss/gdi/eng/device.c | 2 +- win32ss/gdi/eng/pdevobj.c | 2 +- win32ss/user/ntuser/menu.c | 2 +- win32ss/user/ntuser/simplecall.c | 32 +++++++++++++++++++++++++++++--- win32ss/user/ntuser/window.c | 2 +- win32ss/user/ntuser/winpos.c | 2 +- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/win32ss/gdi/eng/device.c b/win32ss/gdi/eng/device.c index 384d4c960c8..81592b88f41 100644 --- a/win32ss/gdi/eng/device.c +++ b/win32ss/gdi/eng/device.c @@ -803,7 +803,7 @@ EngpFindGraphicsDevice( pustrDevice, iDevNum); /* Lock list */ - EngAcquireSemaphore(ghsemGraphicsDeviceList); + EngAcquireSemaphoreShared(ghsemGraphicsDeviceList); if (pustrDevice && pustrDevice->Buffer) { diff --git a/win32ss/gdi/eng/pdevobj.c b/win32ss/gdi/eng/pdevobj.c index 9bc2f88684e..90c81ed59a9 100644 --- a/win32ss/gdi/eng/pdevobj.c +++ b/win32ss/gdi/eng/pdevobj.c @@ -805,7 +805,7 @@ EngpGetPDEV( ULONG i; /* Acquire PDEV lock */ - EngAcquireSemaphore(ghsemPDEV); + EngAcquireSemaphoreShared(ghsemPDEV); /* Did the caller pass a device name? */ if (pustrDeviceName) diff --git a/win32ss/user/ntuser/menu.c b/win32ss/user/ntuser/menu.c index 4d14fe1b55d..e4ade4016e6 100644 --- a/win32ss/user/ntuser/menu.c +++ b/win32ss/user/ntuser/menu.c @@ -6315,7 +6315,7 @@ NtUserMenuItemFromPoint( int Ret = -1; TRACE("Enter NtUserMenuItemFromPoint\n"); - UserEnterExclusive(); + UserEnterShared(); if (!(Menu = UserGetMenuObject(hMenu))) { diff --git a/win32ss/user/ntuser/simplecall.c b/win32ss/user/ntuser/simplecall.c index 6a433ed7120..412b9fea2b1 100644 --- a/win32ss/user/ntuser/simplecall.c +++ b/win32ss/user/ntuser/simplecall.c @@ -61,7 +61,19 @@ NtUserCallNoParam(DWORD Routine) DWORD_PTR Result = 0; TRACE("Enter NtUserCallNoParam\n"); - UserEnterExclusive(); + + /* Read-only routines only need a shared lock; the rest stay exclusive */ + switch (Routine) + { + case NOPARAM_ROUTINE_GETMSESSAGEPOS: + case NOPARAM_ROUTINE_GETIMESHOWSTATUS: + case NOPARAM_ROUTINE_ISCONSOLEMODE: + UserEnterShared(); + break; + default: + UserEnterExclusive(); + break; + } switch (Routine) { @@ -158,7 +170,22 @@ NtUserCallOneParam( TRACE("Enter NtUserCallOneParam\n"); - UserEnterExclusive(); + /* Read-only routines only need a shared lock; the rest stay exclusive */ + switch (Routine) + { + case ONEPARAM_ROUTINE_GETDESKTOPMAPPING: + case ONEPARAM_ROUTINE_WINDOWFROMDC: + case ONEPARAM_ROUTINE_GETKEYBOARDTYPE: + case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT: + case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS: + case ONEPARAM_ROUTINE_GETCURSORPOS: + case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT: + UserEnterShared(); + break; + default: + UserEnterExclusive(); + break; + } switch (Routine) { @@ -319,7 +346,6 @@ NtUserCallOneParam( } case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS: - /* FIXME: Should use UserEnterShared */ Result = UserEnumClipboardFormats(Param); break; diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index 49ee4d3bcb0..58bf7c7c2d3 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -1527,7 +1527,7 @@ NtUserBuildHwndList( if (pcHwndNeeded == NULL) return STATUS_INVALID_PARAMETER; - UserEnterExclusive(); + UserEnterShared(); if (hwndParent || !dwThreadId) { diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index 43a52ab5cf8..74c0563e8a4 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -3283,7 +3283,7 @@ NtUserChildWindowFromPointEx(HWND hwndParent, { PWND pwndParent; TRACE("Enter NtUserChildWindowFromPointEx\n"); - UserEnterExclusive(); + UserEnterShared(); if ((pwndParent = UserGetWindowObject(hwndParent))) { pwndParent = IntChildWindowFromPointEx(pwndParent, x, y, uiFlags);