Nikolay Sivov : ole32: GIT can be released on process detach only.

Alexandre Julliard julliard at winehq.org
Fri Aug 23 13:49:34 CDT 2013


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Aug 23 10:34:48 2013 +0400

ole32: GIT can be released on process detach only.

---

 dlls/ole32/compobj.c         |    1 +
 dlls/ole32/compobj_private.h |    1 +
 dlls/ole32/git.c             |   50 +++++++++++++++++++----------------------
 dlls/ole32/tests/marshal.c   |   11 +++++++++
 4 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 45376d1..4d708c4 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -4590,6 +4590,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
 
     case DLL_PROCESS_DETACH:
         if (reserved) break;
+        release_std_git();
         COMPOBJ_UninitProcess();
         RPC_UnregisterAllChannelHooks();
         COMPOBJ_DllList_Free();
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 6352553..0f4519b 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -174,6 +174,7 @@ struct oletls
 
 /* Global Interface Table Functions */
 extern IGlobalInterfaceTable *get_std_git(void) DECLSPEC_HIDDEN;
+extern void release_std_git(void) DECLSPEC_HIDDEN;
 extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) DECLSPEC_HIDDEN;
 
 HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key) DECLSPEC_HIDDEN;
diff --git a/dlls/ole32/git.c b/dlls/ole32/git.c
index f0be9ee..4d44e39 100644
--- a/dlls/ole32/git.c
+++ b/dlls/ole32/git.c
@@ -66,7 +66,6 @@ typedef struct StdGlobalInterfaceTableImpl
 {
   IGlobalInterfaceTable IGlobalInterfaceTable_iface;
 
-  ULONG ref;
   struct list list;
   ULONG nextCookie;
   
@@ -89,16 +88,6 @@ static inline StdGlobalInterfaceTableImpl *impl_from_IGlobalInterfaceTable(IGlob
   return CONTAINING_RECORD(iface, StdGlobalInterfaceTableImpl, IGlobalInterfaceTable_iface);
 }
 
-/** This destroys it again. It should revoke all the held interfaces first **/
-static void StdGlobalInterfaceTable_Destroy(void* This)
-{
-  TRACE("(%p)\n", This);
-  FIXME("Revoke held interfaces here\n");
-  
-  HeapFree(GetProcessHeap(), 0, This);
-  std_git = NULL;
-}
-
 /***
  * A helper function to traverse the list and find the entry that matches the cookie.
  * Returns NULL if not found. Must be called inside git_section critical section.
@@ -147,25 +136,13 @@ StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
 static ULONG WINAPI
 StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface)
 {
-  StdGlobalInterfaceTableImpl* const This = impl_from_IGlobalInterfaceTable(iface);
-
-  /* InterlockedIncrement(&This->ref); */
-  return This->ref;
+  return 1;
 }
 
 static ULONG WINAPI
 StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface)
 {
-  StdGlobalInterfaceTableImpl* const This = impl_from_IGlobalInterfaceTable(iface);
-
-  /* InterlockedDecrement(&This->ref); */
-  if (This->ref == 0) {
-    /* Hey ho, it's time to go, so long again 'till next weeks show! */
-    StdGlobalInterfaceTable_Destroy(This);
-    return 0;
-  }
-
-  return This->ref;
+  return 1;
 }
 
 /***
@@ -387,13 +364,12 @@ IGlobalInterfaceTable* get_std_git(void)
     if (!newGIT) return NULL;
 
     newGIT->IGlobalInterfaceTable_iface.lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
-    newGIT->ref = 1;
     list_init(&newGIT->list);
     newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
 
     if (InterlockedCompareExchangePointer((void**)&std_git, &newGIT->IGlobalInterfaceTable_iface, NULL))
     {
-      StdGlobalInterfaceTable_Destroy(newGIT);
+      HeapFree(GetProcessHeap(), 0, newGIT);
     }
     else
       TRACE("Created the GIT at %p\n", newGIT);
@@ -401,3 +377,23 @@ IGlobalInterfaceTable* get_std_git(void)
 
   return std_git;
 }
+
+void release_std_git(void)
+{
+  StdGlobalInterfaceTableImpl *git;
+  StdGITEntry *entry, *entry2;
+
+  if (!std_git) return;
+
+  git = impl_from_IGlobalInterfaceTable(std_git);
+  LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &git->list, StdGITEntry, entry)
+  {
+      list_remove(&entry->entry);
+
+      CoReleaseMarshalData(entry->stream);
+      IStream_Release(entry->stream);
+      HeapFree(GetProcessHeap(), 0, entry);
+  }
+
+  HeapFree(GetProcessHeap(), 0, git);
+}
diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c
index 9566de3..383e5b0 100644
--- a/dlls/ole32/tests/marshal.c
+++ b/dlls/ole32/tests/marshal.c
@@ -2806,6 +2806,7 @@ static void test_globalinterfacetable(void)
 	DWORD ret;
         IUnknown *object;
         IClassFactory *cf;
+        ULONG ref;
 
         trace("test_globalinterfacetable\n");
 	cLocks = 0;
@@ -2821,6 +2822,16 @@ static void test_globalinterfacetable(void)
 	hr = CoCreateInstance(&CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, &IID_IGlobalInterfaceTable, (void **)&git);
 	ok_ole_success(hr, CoCreateInstance);
 
+	ref = IGlobalInterfaceTable_AddRef(git);
+	ok(ref == 1, "ref=%d\n", ref);
+	ref = IGlobalInterfaceTable_AddRef(git);
+	ok(ref == 1, "ref=%d\n", ref);
+
+	ref = IGlobalInterfaceTable_Release(git);
+	ok(ref == 1, "ref=%d\n", ref);
+	ref = IGlobalInterfaceTable_Release(git);
+	ok(ref == 1, "ref=%d\n", ref);
+
 	hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, (IUnknown *)&Test_ClassFactory, &IID_IClassFactory, &cookie);
 	ok_ole_success(hr, IGlobalInterfaceTable_RegisterInterfaceInGlobal);
 




More information about the wine-cvs mailing list