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(¤t_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 = ¤t_vtbl.table->vtbl;
+ current_vtbl->ref++;
+ ret = ¤t_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