From 070b22ebb4c4990c54d0e4bb7f91d868d5ac8466 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 27 Jun 2013 13:07:48 +0200 Subject: [PATCH] ole32: Don't call AddConnection for weak references. --- dlls/ole32/stubmanager.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/dlls/ole32/stubmanager.c b/dlls/ole32/stubmanager.c index 822b2994259..57a33b030eb 100644 --- a/dlls/ole32/stubmanager.c +++ b/dlls/ole32/stubmanager.c @@ -219,14 +219,8 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) */ sm->extrefs = 0; - /* - * NOTE: According to tests, creating a stub causes two AddConnection calls followed by - * one ReleaseConnection call (with fLastReleaseCloses=FALSE). - */ hres = IUnknown_QueryInterface(object, &IID_IExternalConnection, (void**)&sm->extern_conn); - if(SUCCEEDED(hres)) - IExternalConnection_AddConnection(sm->extern_conn, EXTCONN_STRONG, 0); - else + if(FAILED(hres)) sm->extern_conn = NULL; EnterCriticalSection(&apt->cs); @@ -253,10 +247,8 @@ static void stub_manager_delete(struct stub_manager *m) stub_manager_delete_ifstub(m, ifstub); } - if(m->extern_conn) { - IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, TRUE); + if(m->extern_conn) IExternalConnection_Release(m->extern_conn); - } CoTaskMemFree(m->oxid_info.psa); IUnknown_Release(m->object); @@ -393,10 +385,13 @@ struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid) /* add some external references (ie from a client that unmarshaled an ifptr) */ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) { + BOOL first_extern_ref; ULONG rc; EnterCriticalSection(&m->lock); + first_extern_ref = refs && !m->extrefs; + /* make sure we don't overflow extrefs */ refs = min(refs, (ULONG_MAX-1 - m->extrefs)); rc = (m->extrefs += refs); @@ -408,12 +403,20 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak TRACE("added %u refs to %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc); + /* + * NOTE: According to tests, creating a stub causes two AddConnection calls followed by + * one ReleaseConnection call (with fLastReleaseCloses=FALSE). + */ + if(first_extern_ref && m->extern_conn) + IExternalConnection_AddConnection(m->extern_conn, EXTCONN_STRONG, 0); + return rc; } /* remove some external references */ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) { + BOOL last_extern_ref; ULONG rc; EnterCriticalSection(&m->lock); @@ -427,10 +430,15 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea if (!last_unlock_releases) rc += m->weakrefs; + last_extern_ref = refs && !m->extrefs; + LeaveCriticalSection(&m->lock); TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc); + if (last_extern_ref && m->extern_conn) + IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, TRUE /* FIXME: Use last_unlock releases? */); + if (rc == 0) stub_manager_int_release(m);