Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

801 lines
22 KiB

/*==========================================================================
*
* Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
*
* File: Pools.cpp
* Content: Fixed Pool Wrappers
*@@BEGIN_MSINTERNAL
* History:
* Date By Reason
* ==== == ======
* 01/12/00 mjn Created
* 01/19/00 mjn Added SyncEventNew()
* 01/31/00 mjn Added Internal FPM's for RefCountBuffers
* 02/29/00 mjn Added ConnectionNew()
* 04/08/00 mjn Added AsyncOpNew()
* 07/28/00 mjn Track outstanding CConnection objects
* 07/30/00 mjn Added PendingDeletionNew()
* 07/31/00 mjn Added QueuedMsgNew()
* 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
* 08/06/00 mjn Added CWorkerJob
* 08/23/00 mjn Added CNameTableOp
* 04/04/01 mjn CConnection list off DirectNetObject guarded by proper critical section
*@@END_MSINTERNAL
*
***************************************************************************/
#include "dncorei.h"
//**********************************************************************
// Constant definitions
//**********************************************************************
//**********************************************************************
// Macro definitions
//**********************************************************************
//**********************************************************************
// Structure definitions
//**********************************************************************
//**********************************************************************
// Variable definitions
//**********************************************************************
//**********************************************************************
// Function prototypes
//**********************************************************************
//**********************************************************************
// Function definitions
//**********************************************************************
//**********************************************************************
// ------------------------------
// RefCountBufferNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
// const DWORD dwBufferSize - Size of buffer (may be 0)
// pointer to allocation function
// pointer to free function
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "RefCountBufferNew"
HRESULT RefCountBufferNew(DIRECTNETOBJECT *const pdnObject,
const DWORD dwBufferSize,
PFNALLOC_REFCOUNT_BUFFER pfnAlloc,
PFNFREE_REFCOUNT_BUFFER pfnFree,
CRefCountBuffer **const ppNewRefCountBuffer)
{
CRefCountBuffer *pRCBuffer;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: dwBufferSize [%ld], pfnAlloc [0x%p], pfnFree [0x%p], ppNewRefCountBuffer [0x%p]",
dwBufferSize,pfnAlloc,pfnFree,ppNewRefCountBuffer);
pRCBuffer = (CRefCountBuffer*)g_RefCountBufferPool.Get(pdnObject); // Context passed in as param
if (pRCBuffer != NULL)
{
if ((hResultCode = pRCBuffer->Initialize(&g_RefCountBufferPool,
pfnAlloc,pfnFree,dwBufferSize)) != DPN_OK)
{
DPFERR("Could not initialize");
DisplayDNError(0,hResultCode);
pRCBuffer->Release();
hResultCode = DPNERR_OUTOFMEMORY;
}
else
{
*ppNewRefCountBuffer = pRCBuffer;
hResultCode = DPN_OK;
}
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pRCBuffer);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// SyncEventNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "SyncEventNew"
HRESULT SyncEventNew(DIRECTNETOBJECT *const pdnObject,
CSyncEvent **const ppNewSyncEvent)
{
CSyncEvent *pSyncEvent;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewSyncEvent [0x%p]",ppNewSyncEvent);
pSyncEvent = (CSyncEvent*)g_SyncEventPool.Get(pdnObject->pIDPThreadPoolWork);
if (pSyncEvent != NULL)
{
*ppNewSyncEvent = pSyncEvent;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pSyncEvent);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// ConnectionNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "ConnectionNew"
HRESULT ConnectionNew(DIRECTNETOBJECT *const pdnObject,
CConnection **const ppNewConnection)
{
CConnection *pConnection;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewConnection [0x%p]",ppNewConnection);
pConnection = (CConnection*)g_ConnectionPool.Get(pdnObject);
if (pConnection != NULL)
{
*ppNewConnection = pConnection;
hResultCode = DPN_OK;
//
// Add this to the bilink of outstanding CConnections
//
DNEnterCriticalSection(&pdnObject->csConnectionList);
pConnection->m_bilinkConnections.InsertBefore(&pdnObject->m_bilinkConnections);
DNLeaveCriticalSection(&pdnObject->csConnectionList);
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pConnection);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// GroupConnectionNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GroupConnectionNew"
HRESULT GroupConnectionNew(DIRECTNETOBJECT *const pdnObject,
CGroupConnection **const ppNewGroupConnection)
{
CGroupConnection *pGroupConnection;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewGroupConnection [0x%p]",ppNewGroupConnection);
pGroupConnection = (CGroupConnection*)g_GroupConnectionPool.Get(pdnObject);
if (pGroupConnection != NULL)
{
*ppNewGroupConnection = pGroupConnection;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pGroupConnection);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// GroupMemberNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GroupMemberNew"
HRESULT GroupMemberNew(DIRECTNETOBJECT *const pdnObject,
CGroupMember **const ppNewGroupMember)
{
CGroupMember *pGroupMember;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewGroupMember [0x%p]",ppNewGroupMember);
pGroupMember = (CGroupMember*)g_GroupMemberPool.Get(pdnObject);
if (pGroupMember != NULL)
{
*ppNewGroupMember = pGroupMember;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pGroupMember);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// NameTableEntryNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "NameTableEntryNew"
HRESULT NameTableEntryNew(DIRECTNETOBJECT *const pdnObject,
CNameTableEntry **const ppNewNameTableEntry)
{
CNameTableEntry *pNewNameTableEntry;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewNameTableEntry [0x%p]",ppNewNameTableEntry);
pNewNameTableEntry = (CNameTableEntry*)g_NameTableEntryPool.Get(pdnObject);
if (pNewNameTableEntry != NULL)
{
*ppNewNameTableEntry = pNewNameTableEntry;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pNewNameTableEntry);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// AsyncOpNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "AsyncOpNew"
HRESULT AsyncOpNew(DIRECTNETOBJECT *const pdnObject,
CAsyncOp **const ppNewAsyncOp)
{
CAsyncOp *pAsyncOp;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewAsyncOp [0x%p]",ppNewAsyncOp);
DNASSERT(pdnObject != NULL);
DNASSERT(ppNewAsyncOp != NULL);
pAsyncOp = (CAsyncOp*)g_AsyncOpPool.Get(pdnObject);
if (pAsyncOp != NULL)
{
*ppNewAsyncOp = pAsyncOp;
hResultCode = DPN_OK;
#ifdef DBG
//
// Add this to the bilink of outstanding AsyncOps
//
DNEnterCriticalSection(&pdnObject->csAsyncOperations);
pAsyncOp->m_bilinkAsyncOps.InsertBefore(&pdnObject->m_bilinkAsyncOps);
DNLeaveCriticalSection(&pdnObject->csAsyncOperations);
#endif // DBG
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pAsyncOp);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// PendingDeletionNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "PendingDeletionNew"
HRESULT PendingDeletionNew(DIRECTNETOBJECT *const pdnObject,
CPendingDeletion **const ppNewPendingDeletion)
{
CPendingDeletion *pPendingDeletion;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewPendingDeletion [0x%p]",ppNewPendingDeletion);
DNASSERT(pdnObject != NULL);
DNASSERT(ppNewPendingDeletion != NULL);
pPendingDeletion = (CPendingDeletion*)g_PendingDeletionPool.Get(pdnObject);
if (pPendingDeletion != NULL)
{
*ppNewPendingDeletion = pPendingDeletion;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pPendingDeletion);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// QueuedMsgNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "QueuedMsgNew"
HRESULT QueuedMsgNew(DIRECTNETOBJECT *const pdnObject,
CQueuedMsg **const ppNewQueuedMsg)
{
CQueuedMsg *pQueuedMsg;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewQueuedMsg [0x%p]",ppNewQueuedMsg);
DNASSERT(pdnObject != NULL);
DNASSERT(ppNewQueuedMsg != NULL);
pQueuedMsg = (CQueuedMsg*)g_QueuedMsgPool.Get(pdnObject);
if (pQueuedMsg != NULL)
{
*ppNewQueuedMsg = pQueuedMsg;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pQueuedMsg);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// WorkerJobNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "WorkerJobNew"
HRESULT WorkerJobNew(DIRECTNETOBJECT *const pdnObject,
CWorkerJob **const ppNewWorkerJob)
{
CWorkerJob *pWorkerJob;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewWorkerJob [0x%p]",ppNewWorkerJob);
DNASSERT(pdnObject != NULL);
DNASSERT(ppNewWorkerJob != NULL);
pWorkerJob = (CWorkerJob*)g_WorkerJobPool.Get(pdnObject);
if (pWorkerJob != NULL)
{
*ppNewWorkerJob = pWorkerJob;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pWorkerJob);
return(hResultCode);
}
//**********************************************************************
// ------------------------------
// NameTableOpNew
//
// Entry: DIRECTNETOBJECT *const pdnObject
//
// Exit: Error Code: DN_OK
// DNERR_OUTOFMEMORY
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "NameTableOpNew"
HRESULT NameTableOpNew(DIRECTNETOBJECT *const pdnObject,
CNameTableOp **const ppNewNameTableOp)
{
CNameTableOp *pNameTableOp;
HRESULT hResultCode;
DPFX(DPFPREP, 8,"Parameters: ppNewNameTableOp [0x%p]",ppNewNameTableOp);
DNASSERT(pdnObject != NULL);
DNASSERT(ppNewNameTableOp != NULL);
pNameTableOp = (CNameTableOp*)g_NameTableOpPool.Get(pdnObject);
if (pNameTableOp != NULL)
{
*ppNewNameTableOp = pNameTableOp;
hResultCode = DPN_OK;
}
else
{
hResultCode = DPNERR_OUTOFMEMORY;
}
DPFX(DPFPREP, 8,"Returning: [0x%lx] (object = 0x%p)",hResultCode,pNameTableOp);
return(hResultCode);
}
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
//**********************************************************************
// ------------------------------
// EnumReplyMemoryBlockAlloc
//
// Entry: DWORD dwSize
//
// Exit: PVOID NULL or pointer to memory block
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "EnumReplyMemoryBlockAlloc"
PVOID EnumReplyMemoryBlockAlloc(void *const pvContext,
const DWORD dwSize )
{
DIRECTNETOBJECT *pdnObject;
PVOID pv;
DPFX(DPFPREP, 8,"Parameters: pvContext [0x%p], dwSize [%ld]",pvContext,dwSize);
pdnObject = static_cast<DIRECTNETOBJECT*>(pvContext);
pv = pdnObject->EnumReplyMemoryBlockPool.Get(NULL);
DPFX(DPFPREP, 8,"Returning: [0x%p]",pv);
return(pv);
}
//**********************************************************************
// ------------------------------
// EnumReplyMemoryBlockFree
//
// Entry: PVOID pvMemoryBlock
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "EnumReplyMemoryBlockFree"
void EnumReplyMemoryBlockFree(void *const pvContext,
void *const pvMemoryBlock)
{
DIRECTNETOBJECT *pdnObject;
DPFX(DPFPREP, 8,"Parameters: pvContext [0x%p], pvMemoryBlock [0x%p]",
pvContext,pvMemoryBlock);
pdnObject = static_cast<DIRECTNETOBJECT*>(pvContext);
pdnObject->EnumReplyMemoryBlockPool.Release(pvMemoryBlock);
DPFX(DPFPREP, 8,"Returning: (nothing)");
}
#undef DPF_MODNAME
#define DPF_MODNAME "DN_PopulateCorePools"
HRESULT DN_PopulateCorePools( DIRECTNETOBJECT *const pdnObject,
const XDP8CREATE_PARAMS * const pDP8CreateParams )
{
DWORD dwSizeToAllocate;
DWORD dwNumToAllocate;
DWORD dwAllocated;
BOOL fEnumReplyPoolInitted = FALSE;
DPFX(DPFPREP, 3,"Parameters: pDP8CreateParams [0x%p]",pDP8CreateParams);
DNASSERT(DNMemoryTrackAreAllocationsAllowed());
dwNumToAllocate = pDP8CreateParams->dwMaxSendsPerPlayer
* pDP8CreateParams->dwMaxReceivesPerPlayer
* pDP8CreateParams->dwMaxNumPlayers;
dwAllocated = g_RefCountBufferPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested ref count buffers!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxSendsPerPlayer
* pDP8CreateParams->dwMaxNumPlayers;
dwNumToAllocate += 2; // 1 for protocol and thread pool shutdown events
dwAllocated = g_SyncEventPool.Preallocate(dwNumToAllocate, pdnObject->pIDPThreadPoolWork);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested sync event pools!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers;
dwAllocated = g_ConnectionPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested connections!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers
* pDP8CreateParams->dwMaxNumGroups;
dwAllocated = g_GroupConnectionPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested group connections!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers
* pDP8CreateParams->dwMaxNumGroups;
dwAllocated = g_GroupMemberPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested group members!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers
+ pDP8CreateParams->dwMaxNumGroups;
dwAllocated = g_NameTableEntryPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested name table entries!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxSendsPerPlayer
* pDP8CreateParams->dwMaxReceivesPerPlayer
* pDP8CreateParams->dwMaxNumPlayers;
dwNumToAllocate += pDP8CreateParams->dwNumSimultaneousEnumHosts;
dwNumToAllocate += 1; // one for the Host/Connect operation
dwAllocated = g_AsyncOpPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested async operations!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers;
dwAllocated = g_PendingDeletionPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested pending deletions!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxReceivesPerPlayer
* pDP8CreateParams->dwMaxNumPlayers;
dwAllocated = g_QueuedMsgPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested queued messages!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = 5 * pDP8CreateParams->dwMaxNumPlayers;
dwAllocated = g_WorkerJobPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested worker jobs!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers
+ pDP8CreateParams->dwMaxNumGroups;
dwAllocated = g_NameTableOpPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested name table operations!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
//
// Build a pool to handle enum replies.
//
dwSizeToAllocate = sizeof(DN_ENUM_RESPONSE_PAYLOAD)
+ sizeof(DPN_APPLICATION_DESC_INFO)
+ pDP8CreateParams->dwMaxAppDescSessionNameLength
+ pDP8CreateParams->dwMaxAppDescAppReservedDataSize
+ pDP8CreateParams->dwMaxEnumHostsResponseDataSize;
if (! pdnObject->EnumReplyMemoryBlockPool.Initialize(dwSizeToAllocate, NULL, NULL, NULL, NULL))
{
goto Failure;
}
fEnumReplyPoolInitted = TRUE;
//
// We only support one enum reply at a time.
//
dwNumToAllocate = 1;
dwAllocated = pdnObject->EnumReplyMemoryBlockPool.Preallocate(dwNumToAllocate, pdnObject);
if (dwAllocated < dwNumToAllocate)
{
DPFX(DPFPREP, 0, "Only allocated %u of %u requested enum reply memory blocks!",
dwAllocated, dwNumToAllocate);
goto Failure;
}
//
// Pre-allocate per-CPU items for the threadpool. We want:
// + 1 work item for RemoveServiceProvider
// + 1 work item per send per player because they might be local sends
// + no timers (the core doesn't have any)
// + no I/O (the core doesn't use I/O directly)
//
dwNumToAllocate = 1 + pDP8CreateParams->dwMaxNumPlayers;
#pragma TODO(vanceo, "Moved from CSPData::Initialize because m_pThreadPool isn't set at point it's needed")
// + one work item for each command
// + one timer per enum hosts operation
// + one I/O operation per simultaneous read
dwNumToAllocate += pDP8CreateParams->dwMaxNumPlayers + pDP8CreateParams->dwNumSimultaneousEnumHosts;
DWORD dwNumTimersToAllocate = pDP8CreateParams->dwNumSimultaneousEnumHosts;
DWORD dwNumIoToAllocate = 1;
if (IDirectPlay8ThreadPoolWork_Preallocate(pdnObject->pIDPThreadPoolWork, dwNumToAllocate, dwNumTimersToAllocate, dwNumIoToAllocate, 0) != DPN_OK)
{
DPFX(DPFPREP, 0, "Couldn't pre-allocate %u work items!",
dwNumToAllocate);
goto Failure;
}
//
// Pre-allocate some address objects. One for each player, plus one for a
// Host/Connect device address.
// Also include a host and device address for each enum.
//
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers + 1;
dwNumToAllocate += 2 * pDP8CreateParams->dwNumSimultaneousEnumHosts;
if (DNAddress_PreallocateInterfaces(dwNumToAllocate) != DPN_OK)
{
DPFX(DPFPREP, 0, "Couldn't pre-allocate %u address objects!",
dwNumToAllocate);
goto Failure;
}
//
// Not really a pool, but should be pre-populated anyway.
//
dwNumToAllocate = pDP8CreateParams->dwMaxNumPlayers
+ pDP8CreateParams->dwMaxNumGroups;
if (pdnObject->NameTable.SetNameTableSize(dwNumToAllocate) != DPN_OK)
{
DPFX(DPFPREP, 0, "Couldn't set name table size to hold %u entries!",
dwNumToAllocate);
goto Failure;
}
pdnObject->fPoolsPrepopulated = TRUE;
DPFX(DPFPREP, 3,"Returning: [DPN_OK]");
return DPN_OK;
Failure:
if (fEnumReplyPoolInitted)
{
pdnObject->EnumReplyMemoryBlockPool.DeInitialize();
fEnumReplyPoolInitted = FALSE;
}
DPFX(DPFPREP, 3,"Returning: [DPNERR_OUTOFMEMORY]");
return DPNERR_OUTOFMEMORY;
}
#endif // DPNBUILD_PREALLOCATEDMEMORYMODEL