Jacek Caban : ole32: Don't call AddConnection for weak references.

Alexandre Julliard julliard at winehq.org
Thu Jun 27 13:39:09 CDT 2013


Module: wine
Branch: master
Commit: 070b22ebb4c4990c54d0e4bb7f91d868d5ac8466
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=070b22ebb4c4990c54d0e4bb7f91d868d5ac8466

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Jun 27 13:07:48 2013 +0200

ole32: Don't call AddConnection for weak references.

---

 dlls/ole32/stubmanager.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/dlls/ole32/stubmanager.c b/dlls/ole32/stubmanager.c
index 822b299..57a33b0 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);
 




More information about the wine-cvs mailing list