[PATCH 7/7] quartz: Implement proper DLL refcounting.

Zebediah Figura z.figura12 at gmail.com
Thu Mar 12 21:34:12 CDT 2020


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48734
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/quartz/acmwrapper.c     | 2 ++
 dlls/quartz/avidec.c         | 2 ++
 dlls/quartz/dsoundrender.c   | 2 ++
 dlls/quartz/filesource.c     | 2 ++
 dlls/quartz/filtergraph.c    | 2 ++
 dlls/quartz/filtermapper.c   | 4 ++++
 dlls/quartz/main.c           | 9 +++++----
 dlls/quartz/memallocator.c   | 2 ++
 dlls/quartz/passthrough.c    | 2 ++
 dlls/quartz/quartz_private.h | 2 ++
 dlls/quartz/systemclock.c    | 2 ++
 dlls/quartz/videorenderer.c  | 2 ++
 dlls/quartz/vmr9.c           | 2 ++
 13 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index b354ae4009a..7c511471ff0 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -493,6 +493,8 @@ static void acm_wrapper_destroy(struct strmbase_filter *iface)
     IUnknown_Release(filter->seeking);
     strmbase_filter_cleanup(&filter->filter);
     free(filter);
+
+    InterlockedDecrement(&object_locks);
 }
 
 static HRESULT acm_wrapper_init_stream(struct strmbase_filter *iface)
diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c
index 7b6838e466d..0837ae2b8da 100644
--- a/dlls/quartz/avidec.c
+++ b/dlls/quartz/avidec.c
@@ -489,6 +489,8 @@ static void avi_decompressor_destroy(struct strmbase_filter *iface)
     IUnknown_Release(filter->seeking);
     strmbase_filter_cleanup(&filter->filter);
     free(filter);
+
+    InterlockedDecrement(&object_locks);
 }
 
 static HRESULT avi_decompressor_init_stream(struct strmbase_filter *iface)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index 8dc93abd628..84b31930a5c 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -500,6 +500,8 @@ static void dsound_render_destroy(struct strmbase_renderer *iface)
 
     strmbase_renderer_cleanup(&filter->renderer);
     CoTaskMemFree(filter);
+
+    InterlockedDecrement(&object_locks);
 }
 
 static HRESULT dsound_render_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 09ab5e51fea..72e52dd01c7 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -353,6 +353,8 @@ static void async_reader_destroy(struct strmbase_filter *iface)
 
     strmbase_filter_cleanup(&filter->filter);
     free(filter);
+
+    InterlockedDecrement(&object_locks);
 }
 
 static HRESULT async_reader_query_interface(struct strmbase_filter *iface, REFIID iid, void **out)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index dfda734d8a9..c659cf96e4c 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -518,6 +518,8 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface)
         }
 	DeleteCriticalSection(&This->cs);
 	CoTaskMemFree(This);
+
+        InterlockedDecrement(&object_locks);
     }
     return ref;
 }
diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c
index 0d1403b5168..db162c01339 100644
--- a/dlls/quartz/filtermapper.c
+++ b/dlls/quartz/filtermapper.c
@@ -193,8 +193,12 @@ static ULONG WINAPI Inner_Release(IUnknown *iface)
     TRACE("(%p)->(): new ref = %d\n", This, ref);
 
     if (ref == 0)
+    {
         CoTaskMemFree(This);
 
+        InterlockedDecrement(&object_locks);
+    }
+
     return ref;
 }
 
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c
index 89c7fe9bb15..4acb4f1a795 100644
--- a/dlls/quartz/main.c
+++ b/dlls/quartz/main.c
@@ -27,7 +27,7 @@ extern HRESULT WINAPI QUARTZ_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLS
 extern HRESULT WINAPI QUARTZ_DllCanUnloadNow(void) DECLSPEC_HIDDEN;
 extern BOOL WINAPI QUARTZ_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
 
-static LONG server_locks = 0;
+LONG object_locks = 0;
 
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
 {
@@ -124,6 +124,7 @@ static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter
 
     if (SUCCEEDED(hres = This->create_instance(pOuter, &punk)))
     {
+        InterlockedIncrement(&object_locks);
         hres = IUnknown_QueryInterface(punk, riid, ppobj);
         IUnknown_Release(punk);
     }
@@ -135,9 +136,9 @@ static HRESULT WINAPI DSCF_LockServer(IClassFactory *iface, BOOL dolock)
     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
     FIXME("(%p)->(%d),stub!\n",This,dolock);
     if(dolock)
-        InterlockedIncrement(&server_locks);
+        InterlockedIncrement(&object_locks);
     else
-        InterlockedDecrement(&server_locks);
+        InterlockedDecrement(&object_locks);
     return S_OK;
 }
 
@@ -200,7 +201,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
  */
 HRESULT WINAPI DllCanUnloadNow(void)
 {
-    if(server_locks == 0 && QUARTZ_DllCanUnloadNow() == S_OK)
+    if (!object_locks && QUARTZ_DllCanUnloadNow() == S_OK)
         return S_OK;
     return S_FALSE;
 }
diff --git a/dlls/quartz/memallocator.c b/dlls/quartz/memallocator.c
index 531fbe874cf..cc13f776cfb 100644
--- a/dlls/quartz/memallocator.c
+++ b/dlls/quartz/memallocator.c
@@ -911,6 +911,8 @@ static void StdMemAllocator_Destroy(IMemAllocator *iface)
     DeleteCriticalSection(&This->csState);
 
     CoTaskMemFree(This);
+
+    InterlockedDecrement(&object_locks);
 }
 
 HRESULT mem_allocator_create(IUnknown *lpUnkOuter, IUnknown **out)
diff --git a/dlls/quartz/passthrough.c b/dlls/quartz/passthrough.c
index 2f8fe9dc370..7f81ae8a1be 100644
--- a/dlls/quartz/passthrough.c
+++ b/dlls/quartz/passthrough.c
@@ -80,6 +80,8 @@ static ULONG WINAPI seeking_passthrough_Release(IUnknown *iface)
     {
         strmbase_passthrough_cleanup(&passthrough->passthrough);
         free(passthrough);
+
+        InterlockedDecrement(&object_locks);
     }
     return refcount;
 }
diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h
index 55385379085..1812b1c37ef 100644
--- a/dlls/quartz/quartz_private.h
+++ b/dlls/quartz/quartz_private.h
@@ -56,6 +56,8 @@ static inline const char *debugstr_time(REFERENCE_TIME time)
     return wine_dbg_sprintf("%s", rev);
 }
 
+extern LONG object_locks;
+
 /* see IAsyncReader::Request on MSDN for the explanation of this */
 #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
 #define BYTES_FROM_MEDIATIME(time) ((time) / 10000000)
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c
index 8ccd6df47ce..24d8651aaba 100644
--- a/dlls/quartz/systemclock.c
+++ b/dlls/quartz/systemclock.c
@@ -105,6 +105,8 @@ static ULONG WINAPI system_clock_inner_Release(IUnknown *iface)
         clock->cs.DebugInfo->Spare[0] = 0;
         DeleteCriticalSection(&clock->cs);
         heap_free(clock);
+
+        InterlockedDecrement(&object_locks);
     }
     return refcount;
 }
diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index 1b5e68e7d5b..37227bfa210 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -248,6 +248,8 @@ static void video_renderer_destroy(struct strmbase_renderer *iface)
     CloseHandle(filter->run_event);
     strmbase_renderer_cleanup(&filter->renderer);
     CoTaskMemFree(filter);
+
+    InterlockedDecrement(&object_locks);
 }
 
 static HRESULT video_renderer_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index b8cf0698ecd..e7a588e28a0 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -519,6 +519,8 @@ static void vmr_destroy(struct strmbase_renderer *iface)
     BaseControlWindow_Destroy(&filter->baseControlWindow);
     strmbase_renderer_cleanup(&filter->renderer);
     CoTaskMemFree(filter);
+
+    InterlockedDecrement(&object_locks);
 }
 
 static HRESULT vmr_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
-- 
2.25.1




More information about the wine-devel mailing list