Module: wine Branch: master Commit: 98f3ecc32a06c97272cdf75bc95692024ce185b4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=98f3ecc32a06c97272cdf75bc9...
Author: Nikolay Sivov nsivov@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);