Alexandre Julliard : rpcrt4: Allocate the delegated stubs vtbl only once it is really needed.

Alexandre Julliard julliard at winehq.org
Tue Jun 2 08:44:29 CDT 2009


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jun  1 16:55:14 2009 +0200

rpcrt4: Allocate the delegated stubs vtbl only once it is really needed.

---

 dlls/rpcrt4/cpsf.c  |    8 +------
 dlls/rpcrt4/cpsf.h  |    2 -
 dlls/rpcrt4/cstub.c |   55 ++++++++++++++++++++++++--------------------------
 3 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/dlls/rpcrt4/cpsf.c b/dlls/rpcrt4/cpsf.c
index 9b91466..5d7ffe7 100644
--- a/dlls/rpcrt4/cpsf.c
+++ b/dlls/rpcrt4/cpsf.c
@@ -160,7 +160,6 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
   *ppv = NULL;
   if (!pPSFactoryBuffer->lpVtbl) {
     const ProxyFileInfo **pProxyFileList2;
-    DWORD max_delegating_vtbl_size = 0;
     pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl;
     pPSFactoryBuffer->RefCount = 0;
     pPSFactoryBuffer->pProxyFileList = pProxyFileList;
@@ -173,19 +172,14 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
         void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl;
         unsigned int j;
 
-        if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) {
+        if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i])
           pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl;
-          if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size)
-            max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount;
-        }
 
         for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++)
           if (!pRpcStubVtbl[j])
             pRpcStubVtbl[j] = pSrcRpcStubVtbl[j];
       }
     }
-    if(max_delegating_vtbl_size > 0)
-      create_delegating_vtbl(max_delegating_vtbl_size);
   }
   if (pclsid && IsEqualGUID(rclsid, pclsid))
     return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
diff --git a/dlls/rpcrt4/cpsf.h b/dlls/rpcrt4/cpsf.h
index 9b401b8..58645fb 100644
--- a/dlls/rpcrt4/cpsf.h
+++ b/dlls/rpcrt4/cpsf.h
@@ -38,8 +38,6 @@ const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
 const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
 const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl;
 
-void create_delegating_vtbl(DWORD num_methods);
-
 HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
 
 #endif  /* __WINE_CPSF_H */
diff --git a/dlls/rpcrt4/cstub.c b/dlls/rpcrt4/cstub.c
index b9ff153..8e947f2 100644
--- a/dlls/rpcrt4/cstub.c
+++ b/dlls/rpcrt4/cstub.c
@@ -117,10 +117,7 @@ typedef struct
     /* remaining entries in vtbl */
 } ref_counted_vtbl;
 
-static struct
-{
-    ref_counted_vtbl *table;
-} current_vtbl;
+static ref_counted_vtbl *current_vtbl;
 
 
 static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
@@ -225,38 +222,38 @@ static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num)
 
 #endif  /* __i386__ */
 
-void create_delegating_vtbl(DWORD num_methods)
+static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods)
 {
-    TRACE("%d\n", num_methods);
-    if(num_methods <= 3)
-    {
-        ERR("should have more than %d methods\n", num_methods);
-        return;
-    }
+    IUnknownVtbl *ret;
+
+    if (num_methods < 256) num_methods = 256;  /* avoid frequent reallocations */
 
     EnterCriticalSection(&delegating_vtbl_section);
-    if(!current_vtbl.table || num_methods > current_vtbl.table->size)
+
+    if(!current_vtbl || num_methods > current_vtbl->size)
     {
-        if(current_vtbl.table && current_vtbl.table->ref == 0)
+        ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0,
+                                            FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*));
+        if (!table)
+        {
+            LeaveCriticalSection(&delegating_vtbl_section);
+            return NULL;
+        }
+
+        table->ref = 0;
+        table->size = num_methods;
+        fill_delegated_stub_table(&table->vtbl, num_methods);
+
+        if (current_vtbl && current_vtbl->ref == 0)
         {
             TRACE("freeing old table\n");
-            HeapFree(GetProcessHeap(), 0, current_vtbl.table);
+            HeapFree(GetProcessHeap(), 0, current_vtbl);
         }
-        current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*));
-        current_vtbl.table->ref = 0;
-        current_vtbl.table->size = num_methods;
-        fill_delegated_stub_table(&current_vtbl.table->vtbl, num_methods);
+        current_vtbl = table;
     }
-    LeaveCriticalSection(&delegating_vtbl_section);
-}
 
-static IUnknownVtbl *get_delegating_vtbl(void)
-{
-    IUnknownVtbl *ret;
-
-    EnterCriticalSection(&delegating_vtbl_section);
-    current_vtbl.table->ref++;
-    ret = &current_vtbl.table->vtbl;
+    current_vtbl->ref++;
+    ret = &current_vtbl->vtbl;
     LeaveCriticalSection(&delegating_vtbl_section);
     return ret;
 }
@@ -268,7 +265,7 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl)
     EnterCriticalSection(&delegating_vtbl_section);
     table->ref--;
     TRACE("ref now %d\n", table->ref);
-    if(table->ref == 0 && table != current_vtbl.table)
+    if(table->ref == 0 && table != current_vtbl)
     {
         TRACE("... and we're not current so free'ing\n");
         HeapFree(GetProcessHeap(), 0, table);
@@ -308,7 +305,7 @@ HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid,
         return E_OUTOFMEMORY;
     }
 
-    This->base_obj = get_delegating_vtbl();
+    This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount );
     r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub);
     if(FAILED(r))
     {




More information about the wine-cvs mailing list