Hans Leidekker : fusion: Add locking around operations on the assembly cache.

Alexandre Julliard julliard at winehq.org
Mon Apr 30 14:13:07 CDT 2012


Module: wine
Branch: master
Commit: 93f292506c4fefa126474ad323362e2bc9bfd3d0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=93f292506c4fefa126474ad323362e2bc9bfd3d0

Author: Hans Leidekker <hans at 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;
 }
 




More information about the wine-cvs mailing list