ole32: Fix an apartment reference count leak on error path.

Dmitry Timoshkov dmitry at baikal.ru
Thu Mar 28 04:46:22 CDT 2013


Found while investigating why an application compiled with Intel C++ compiler
hangs on exit.

It appears that libiomp5md.dll (Intel OpenMP runtime library) adds each
thread handle it receives via THREAD_ATTACH notification to its internal
tracking list, and removes handles from that list in THREAD_DETACH handler.
When libiomp5md.dll receives PROCESS_DETACH notification it does approximately
the following:

while (thread_count > 0)
{
    for (i = 0; i < thread_count; i++)
    {
        GetExitCodeThread(thread_list[i], &exit_code);
        if (exit_code != STILL_ACTIVE) remove_thread(thread_list[i]);
    }
}

I.e. it while at least single thread (except the main one) is still alive
(no matter how and by whom created) libiomp5md.dll will never return from
its PROCESS_DETACH handler. A simple hack that sets thread return code to -1
instead of STILL_ACTIVE (259) in GetExitCodeThread() allows an application
linked with libiomp5md.dll successfully exit.

Probably it's time for Wine DLLs (ole32 is the worst one) to start at least
terminate the threads they create for internal tasks.

---
 dlls/ole32/marshal.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c
index a8df28c..ddaaa53 100644
--- a/dlls/ole32/marshal.c
+++ b/dlls/ole32/marshal.c
@@ -1437,6 +1437,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
 
     if (!(stubmgr = get_stub_manager(apt, stdobjref.oid)))
     {
+        apartment_release(apt);
         ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n",
             wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid));
         return RPC_E_INVALID_OBJREF;
-- 
1.8.2




More information about the wine-patches mailing list