Signed-off-by: Paul Gofman <pgofman(a)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