Module: wine Branch: master Commit: 93f292506c4fefa126474ad323362e2bc9bfd3d0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=93f292506c4fefa126474ad323...
Author: Hans Leidekker hans@codeweavers.com Date: Mon Apr 30 09:34:15 2012 +0200
fusion: Add locking around operations on the assembly cache.
---
dlls/fusion/asmcache.c | 56 ++++++++++++++++++++++++++++++++++++------------ 1 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/dlls/fusion/asmcache.c b/dlls/fusion/asmcache.c index d0b45c7..e6a2a65 100644 --- a/dlls/fusion/asmcache.c +++ b/dlls/fusion/asmcache.c @@ -41,6 +41,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(fusion);
+static const WCHAR cache_mutex_nameW[] = + {'_','_','W','I','N','E','_','F','U','S','I','O','N','_','C','A','C','H','E','_','M','U','T','E','X','_','_',0}; + static BOOL create_full_path(LPCWSTR path) { LPWSTR new_path; @@ -126,6 +129,7 @@ typedef struct { IAssemblyCache IAssemblyCache_iface;
LONG ref; + HANDLE lock; } IAssemblyCacheImpl;
static inline IAssemblyCacheImpl *impl_from_IAssemblyCache(IAssemblyCache *iface) @@ -166,17 +170,29 @@ static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface)
static ULONG WINAPI IAssemblyCacheImpl_Release(IAssemblyCache *iface) { - IAssemblyCacheImpl *This = impl_from_IAssemblyCache(iface); - ULONG refCount = InterlockedDecrement(&This->ref); + IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); + ULONG refCount = InterlockedDecrement( &cache->ref );
- TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); + TRACE("(%p)->(ref before = %u)\n", cache, refCount + 1);
if (!refCount) - HeapFree(GetProcessHeap(), 0, This); - + { + CloseHandle( cache->lock ); + HeapFree( GetProcessHeap(), 0, cache ); + } return refCount; }
+static void cache_lock( IAssemblyCacheImpl *cache ) +{ + WaitForSingleObject( cache->lock, INFINITE ); +} + +static void cache_unlock( IAssemblyCacheImpl *cache ) +{ + ReleaseMutex( cache->lock ); +} + static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszAssemblyName, @@ -184,6 +200,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface ULONG *pulDisposition) { HRESULT hr; + IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); IAssemblyName *asmname, *next = NULL; IAssemblyEnum *asmenum = NULL; WCHAR *p, *path = NULL; @@ -202,6 +219,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface if (FAILED( hr )) return hr;
+ cache_lock( cache ); + hr = CreateAssemblyEnum( &asmenum, NULL, asmname, ASM_CACHE_GAC, NULL ); if (FAILED( hr )) goto done; @@ -253,6 +272,7 @@ done: if (next) IAssemblyName_Release( next ); if (asmenum) IAssemblyEnum_Release( asmenum ); HeapFree( GetProcessHeap(), 0, path ); + cache_unlock( cache ); return hr; }
@@ -261,6 +281,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface LPCWSTR pszAssemblyName, ASSEMBLY_INFO *pAsmInfo) { + IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); IAssemblyName *asmname, *next = NULL; IAssemblyEnum *asmenum = NULL; HRESULT hr; @@ -281,6 +302,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface if (FAILED(hr)) return hr;
+ cache_lock( cache ); + hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL); if (FAILED(hr)) goto done; @@ -303,7 +326,7 @@ done: IAssemblyName_Release(asmname); if (next) IAssemblyName_Release(next); if (asmenum) IAssemblyEnum_Release(asmenum); - + cache_unlock( cache ); return hr; }
@@ -331,9 +354,10 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, LPCWSTR pszManifestFilePath, LPCFUSION_INSTALL_REFERENCE pRefData) { - static const WCHAR format[] = - {'%','s','\','%','s','\','%','s','_','_','%','s','\',0}; - + static const WCHAR format[] = {'%','s','\','%','s','\','%','s','_','_','%','s','\',0}; + static const WCHAR ext_exe[] = {'.','e','x','e',0}; + static const WCHAR ext_dll[] = {'.','d','l','l',0}; + IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); ASSEMBLY *assembly; LPWSTR filename; LPWSTR name = NULL; @@ -345,9 +369,6 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, LPWSTR ext; HRESULT hr;
- static const WCHAR ext_exe[] = {'.','e','x','e',0}; - static const WCHAR ext_dll[] = {'.','d','l','l',0}; - TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, debugstr_w(pszManifestFilePath), pRefData);
@@ -382,6 +403,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, if (FAILED(hr)) goto done;
+ cache_lock( cache ); + get_assembly_directory(asmdir, MAX_PATH, assembly_get_architecture(assembly));
sprintfW(path, format, asmdir, name, version, token); @@ -404,6 +427,7 @@ done: HeapFree(GetProcessHeap(), 0, version); HeapFree(GetProcessHeap(), 0, asmpath); assembly_release(assembly); + cache_unlock( cache ); return hr; }
@@ -438,9 +462,13 @@ HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved
cache->IAssemblyCache_iface.lpVtbl = &AssemblyCacheVtbl; cache->ref = 1; - + cache->lock = CreateMutexW( NULL, FALSE, cache_mutex_nameW ); + if (!cache->lock) + { + HeapFree( GetProcessHeap(), 0, cache ); + return HRESULT_FROM_WIN32( GetLastError() ); + } *ppAsmCache = &cache->IAssemblyCache_iface; - return S_OK; }