rpcrt4: Allocate the delegated stubs vtbl only once it is really needed.
This commit is contained in:
parent
0357ad0894
commit
6f49023802
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
TRACE("%d\n", num_methods);
|
||||
if(num_methods <= 3)
|
||||
{
|
||||
ERR("should have more than %d methods\n", num_methods);
|
||||
return;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&delegating_vtbl_section);
|
||||
if(!current_vtbl.table || num_methods > current_vtbl.table->size)
|
||||
{
|
||||
if(current_vtbl.table && current_vtbl.table->ref == 0)
|
||||
{
|
||||
TRACE("freeing old table\n");
|
||||
HeapFree(GetProcessHeap(), 0, current_vtbl.table);
|
||||
}
|
||||
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);
|
||||
}
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
}
|
||||
|
||||
static IUnknownVtbl *get_delegating_vtbl(void)
|
||||
static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods)
|
||||
{
|
||||
IUnknownVtbl *ret;
|
||||
|
||||
if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */
|
||||
|
||||
EnterCriticalSection(&delegating_vtbl_section);
|
||||
current_vtbl.table->ref++;
|
||||
ret = ¤t_vtbl.table->vtbl;
|
||||
|
||||
if(!current_vtbl || num_methods > current_vtbl->size)
|
||||
{
|
||||
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);
|
||||
}
|
||||
current_vtbl = table;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue