Bump handle limit to 1MB.
This bumps the handle bits to 20 and reduces the serial/cookie bits to 12. A warning is emitted if a single owner creates more than 100k handles. Tested on mock srcds with sm_dump_handles.
This commit is contained in:
parent
92ce0fe814
commit
cab60f7385
@ -47,6 +47,8 @@
|
||||
#include "sm_invalidparamhandler.h"
|
||||
#endif
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
HandleSystem g_HandleSys;
|
||||
|
||||
QHandle *ignore_handle;
|
||||
@ -299,6 +301,28 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
}
|
||||
}
|
||||
|
||||
if (owner)
|
||||
{
|
||||
owner->num_handles++;
|
||||
if (!owner->warned_handle_usage && owner->num_handles >= HANDLESYS_WARN_USAGE)
|
||||
{
|
||||
owner->warned_handle_usage = true;
|
||||
|
||||
std::string path = "<unknown>";
|
||||
if (auto plugin = scripts->FindPluginByIdentity(owner))
|
||||
{
|
||||
path = "plugin "s + plugin->GetFilename();
|
||||
}
|
||||
else if (auto ext = g_Extensions.GetExtensionFromIdent(owner))
|
||||
{
|
||||
path = "extension "s + ext->GetFilename();
|
||||
}
|
||||
|
||||
logger->LogError("[SM] Warning: %s is using more than %d handles!",
|
||||
path.c_str(), HANDLESYS_WARN_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
QHandle *pHandle = &m_Handles[handle];
|
||||
|
||||
assert(pHandle->set == false);
|
||||
@ -320,7 +344,7 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
|
||||
/* Create the hash value */
|
||||
Handle_t hash = pHandle->serial;
|
||||
hash <<= 16;
|
||||
hash <<= HANDLESYS_HANDLE_BITS;
|
||||
hash |= handle;
|
||||
|
||||
/* Add a reference count to the type */
|
||||
@ -484,7 +508,7 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||
unsigned int *in_index,
|
||||
bool ignoreFree)
|
||||
{
|
||||
unsigned int serial = (handle >> 16);
|
||||
unsigned int serial = (handle >> HANDLESYS_HANDLE_BITS);
|
||||
unsigned int index = (handle & HANDLESYS_HANDLE_MASK);
|
||||
|
||||
if (index == 0 || index > m_HandleTail || index > HANDLESYS_MAX_HANDLES)
|
||||
@ -640,7 +664,7 @@ Handle_t HandleSystem::FastCloneHandle(Handle_t hndl)
|
||||
void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
unsigned int serial = (hndl >> 16);
|
||||
unsigned int serial = (hndl >> HANDLESYS_HANDLE_BITS);
|
||||
#endif
|
||||
index = (hndl & HANDLESYS_HANDLE_MASK);
|
||||
|
||||
@ -664,6 +688,9 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
||||
|
||||
QHandleType *pType = &m_Types[pHandle->type];
|
||||
|
||||
if (pHandle->owner && pHandle->owner->num_handles > 0)
|
||||
pHandle->owner->num_handles--;
|
||||
|
||||
if (pHandle->clone)
|
||||
{
|
||||
/* If we're a clone, decrease the parent reference count */
|
||||
@ -1138,12 +1165,12 @@ void HandleSystem::Dump(const HandleReporter &fn)
|
||||
continue;
|
||||
}
|
||||
/* Get the index */
|
||||
unsigned int index = (m_Handles[i].serial << 16) | i;
|
||||
unsigned int index = (m_Handles[i].serial << HANDLESYS_HANDLE_BITS) | i;
|
||||
/* Determine the owner */
|
||||
const char *owner = "UNKNOWN";
|
||||
if (m_Handles[i].owner)
|
||||
{
|
||||
IdentityToken_t *pOwner = m_Handles[i].owner;
|
||||
IdentityToken_t *pOwner = m_Handles[i].owner;
|
||||
if (pOwner == g_pCoreIdent)
|
||||
{
|
||||
owner = "CORE";
|
||||
|
@ -42,14 +42,17 @@
|
||||
#include <sm_namehashset.h>
|
||||
#include "common_logic.h"
|
||||
|
||||
#define HANDLESYS_MAX_HANDLES (1<<15)
|
||||
#define HANDLESYS_HANDLE_BITS 20
|
||||
#define HANDLESYS_MAX_HANDLES ((1 << HANDLESYS_HANDLE_BITS) - 1)
|
||||
#define HANDLESYS_MAX_TYPES (1<<9)
|
||||
#define HANDLESYS_MAX_SUBTYPES 0xF
|
||||
#define HANDLESYS_SUBTYPE_MASK 0xF
|
||||
#define HANDLESYS_TYPEARRAY_SIZE (HANDLESYS_MAX_TYPES * (HANDLESYS_MAX_SUBTYPES + 1))
|
||||
#define HANDLESYS_MAX_SERIALS 0xFFFF
|
||||
#define HANDLESYS_SERIAL_MASK 0xFFFF0000
|
||||
#define HANDLESYS_HANDLE_MASK 0x0000FFFF
|
||||
#define HANDLESYS_SERIAL_BITS (32 - HANDLESYS_HANDLE_BITS)
|
||||
#define HANDLESYS_MAX_SERIALS (1 << HANDLESYS_SERIAL_BITS)
|
||||
#define HANDLESYS_SERIAL_MASK (((1 << HANDLESYS_SERIAL_BITS) - 1) << HANDLESYS_HANDLE_BITS)
|
||||
#define HANDLESYS_HANDLE_MASK ((1 << HANDLESYS_HANDLE_BITS) - 1)
|
||||
#define HANDLESYS_WARN_USAGE 100000
|
||||
|
||||
#define HANDLESYS_MEMUSAGE_MIN_VERSION 3
|
||||
|
||||
|
@ -49,9 +49,11 @@ namespace SourceMod
|
||||
{
|
||||
struct IdentityToken_t
|
||||
{
|
||||
Handle_t ident;
|
||||
void *ptr;
|
||||
IdentityType_t type;
|
||||
Handle_t ident = 0;
|
||||
void *ptr = nullptr;
|
||||
IdentityType_t type = 0;
|
||||
size_t num_handles = 0;
|
||||
bool warned_handle_usage = false;
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user