[PATCH v2 13/22] ntdll: Use shared loader locking in LdrUnloadDll() when possible.
Paul Gofman
pgofman at codeweavers.com
Tue Oct 5 17:49:19 CDT 2021
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v2:
- use ldr_data_srw_lock instead of introducing a new one.
dlls/ntdll/loader.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 8e2ed03ad4c..5f4f4fea036 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3858,7 +3858,7 @@ static void free_modref( WINE_MODREF *wm )
* Remove all unused modrefs and call the internal unloading routines
* for the library type.
*
- * The loader must be locked while calling this function.
+ * The loader must be exclusively locked while calling this function.
*/
static void MODULE_FlushModrefs(void)
{
@@ -3889,7 +3889,7 @@ static void MODULE_FlushModrefs(void)
/***********************************************************************
* MODULE_DecRefCount
*
- * The loader must be locked while calling this function.
+ * The loader must be exclusively locked while calling this function.
*/
static void MODULE_DecRefCount( WINE_MODREF *wm )
{
@@ -3921,17 +3921,34 @@ static void MODULE_DecRefCount( WINE_MODREF *wm )
/******************************************************************
* LdrUnloadDll (NTDLL.@)
*
- *
+ * The loader must be unlocked or exclusively locked while calling this function.
*/
NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
{
WINE_MODREF *wm;
NTSTATUS retv = STATUS_SUCCESS;
+ BOOL need_exclusive = FALSE;
if (process_detaching) return retv;
TRACE("(%p)\n", hModule);
+ lock_loader_shared();
+ if ((wm = get_modref( hModule )))
+ {
+ RtlAcquireSRWLockExclusive( &ldr_data_srw_lock );
+ if (wm->ldr.LoadCount && wm->ldr.LoadCount != 1)
+ {
+ if (wm->ldr.LoadCount != -1) --wm->ldr.LoadCount;
+ }
+ else if (wm->ldr.LoadCount) need_exclusive = TRUE;
+ /* If the module is already being unloaded LdrUnloadDll() succeeds and doesn't wait. */
+ RtlReleaseSRWLockExclusive( &ldr_data_srw_lock );
+ }
+ else retv = STATUS_DLL_NOT_FOUND;
+ unlock_loader();
+ if (!need_exclusive) return retv;
+
lock_loader_exclusive();
free_lib_count++;
--
2.31.1
More information about the wine-devel
mailing list