Module: wine Branch: master Commit: 6f4902380278fbcdedc8d78228cf3b41fc5429e1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=6f4902380278fbcdedc8d78228...
Author: Alexandre Julliard julliard@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)) {