[PATCH 2/2] comsvcs: Create an implicit MTA thread in RegisterDispenser().

Zebediah Figura z.figura12 at gmail.com
Thu Feb 7 11:02:39 CST 2019


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46581
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/comsvcs/main.c            | 27 ++++++++++++++++++++++++---
 dlls/comsvcs/tests/dispenser.c |  1 -
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c
index d7831cff6c..af9487b314 100644
--- a/dlls/comsvcs/main.c
+++ b/dlls/comsvcs/main.c
@@ -40,7 +40,7 @@ typedef struct dispensermanager
 {
     IDispenserManager IDispenserManager_iface;
     LONG ref;
-
+    HANDLE mta_thread, mta_stop_event;
 } dispensermanager;
 
 typedef struct holder
@@ -264,12 +264,27 @@ static ULONG WINAPI dismanager_Release(IDispenserManager *iface)
 
     if (!ref)
     {
-       heap_free(This);
+        if (This->mta_thread)
+        {
+            SetEvent(This->mta_stop_event);
+            WaitForSingleObject(This->mta_thread, INFINITE);
+            CloseHandle(This->mta_stop_event);
+            CloseHandle(This->mta_thread);
+        }
+        heap_free(This);
     }
 
     return ref;
 }
 
+static DWORD WINAPI mta_thread_proc(void *arg)
+{
+    CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    WaitForSingleObject(arg, INFINITE);
+    CoUninitialize();
+    return 0;
+}
+
 static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDispenserDriver *driver,
                         LPCOLESTR name, IHolder **dispenser)
 {
@@ -283,6 +298,12 @@ static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDi
 
     hr = create_holder(driver, dispenser);
 
+    if (!This->mta_thread)
+    {
+        This->mta_stop_event = CreateEventA(NULL, TRUE, FALSE, NULL);
+        This->mta_thread = CreateThread(NULL, 0, mta_thread_proc, This->mta_stop_event, 0, NULL);
+    }
+
     TRACE("<-- 0x%08x, %p\n", hr, *dispenser);
 
     return hr;
@@ -313,7 +334,7 @@ static HRESULT WINAPI comsvcscf_CreateInstance(IClassFactory *cf,IUnknown* outer
 
     TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), object);
 
-    dismanager = heap_alloc(sizeof(*dismanager));
+    dismanager = heap_alloc_zero(sizeof(*dismanager));
     if (!dismanager)
     {
         *object = NULL;
diff --git a/dlls/comsvcs/tests/dispenser.c b/dlls/comsvcs/tests/dispenser.c
index c6d85ead14..b18a590c44 100644
--- a/dlls/comsvcs/tests/dispenser.c
+++ b/dlls/comsvcs/tests/dispenser.c
@@ -185,7 +185,6 @@ static void create_dispenser(void)
     thread = CreateThread(NULL, 0, com_thread, NULL, 0, NULL);
     ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
     GetExitCodeThread(thread, &ret);
-todo_wine
     ok(ret == S_OK, "got unexpected hr %#x\n", ret);
 
     hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool0, &holder2);
-- 
2.20.1




More information about the wine-devel mailing list