bool HandleSystem::TryAndFreeSomeHandles() { IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator(); IPlugin *highest_owner = NULL; unsigned int highest_handle_count = 0; /* Search all plugins */ while (pl_iter->MorePlugins()) { IPlugin *plugin = pl_iter->GetPlugin(); IdentityToken_t *identity = plugin->GetIdentity(); unsigned int handle_count = 0; if (identity == NULL) { continue; } /* Search all handles */ for (unsigned int i = 1; i <= m_HandleTail; i++) { if (m_Handles[i].set != HandleSet_Used) { continue; } if (m_Handles[i].owner == identity) { handle_count++; } } if (handle_count > highest_handle_count) { highest_owner = plugin; highest_handle_count = handle_count; } pl_iter->NextPlugin(); } if (highest_owner == NULL || highest_handle_count == 0) { return false; } g_Logger.LogFatal("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename()); g_Logger.LogFatal("[SM] Unloading plugin to free %d handles.", highest_handle_count); g_Logger.LogFatal("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count); highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak"); return g_PluginSys.UnloadPlugin(highest_owner); }
static void PawnFrameAction(void *pData) { ke::AutoPtr<SMFrameActionData> frame(reinterpret_cast<SMFrameActionData *>(pData)); IPlugin *pPlugin = pluginsys->PluginFromHandle(frame->ownerhandle, NULL); if (!pPlugin) { return; } IChangeableForward *pForward; HandleSecurity sec(pPlugin->GetIdentity(), g_pCoreIdent); if (handlesys->ReadHandle(frame->handle, g_PrivateFwdType, &sec, (void **)&pForward) != HandleError_None) { return; } pForward->PushCell(frame->data); pForward->Execute(NULL); handlesys->FreeHandle(frame->handle, &sec); }
bool HandleSystem::TryAndFreeSomeHandles() { IPlugin *highest_owner = NULL; unsigned int highest_handle_count = 0; /* Search all plugins */ for (IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator(); pl_iter->MorePlugins(); pl_iter->NextPlugin()) { IPlugin *plugin = pl_iter->GetPlugin(); IdentityToken_t *identity = plugin->GetIdentity(); unsigned int handle_count = 0; if (identity == NULL) { continue; } /* Search all handles */ for (unsigned int i = 1; i <= m_HandleTail; i++) { if (m_Handles[i].set != HandleSet_Used) { continue; } if (m_Handles[i].owner == identity) { handle_count++; } } if (handle_count > highest_handle_count) { highest_owner = plugin; highest_handle_count = handle_count; } } if (highest_owner == NULL || highest_handle_count == 0) { return false; } HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename()); HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count); HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count); HANDLE_LOG_VERY_BAD("--------------------------------------------------------------------------"); const IdentityToken_t *pIdentity = highest_owner->GetIdentity(); unsigned int total = 0, highest_index = 0, total_size = 0, size; unsigned int * pCount = new unsigned int[HANDLESYS_TYPEARRAY_SIZE+1]; memset(pCount, 0, ((HANDLESYS_TYPEARRAY_SIZE + 1) * sizeof(unsigned int))); for (unsigned int i = 1; i <= m_HandleTail; ++i) { const QHandle &Handle = m_Handles[i]; if (Handle.set != HandleSet_Used || Handle.owner != pIdentity) { continue; } ++pCount[Handle.type]; ++total; if (Handle.type >= highest_index) { highest_index = ((Handle.type) + 1); } if (Handle.clone != 0) { continue; } if (m_Types[Handle.type].dispatch->GetHandleApproxSize(Handle.type, Handle.object, &size)) { total_size += size; } } const char * pTypeName = NULL; for (unsigned int i = 0; i < highest_index; ++i) { if (pCount[i] == 0) { continue; /* We may have gaps, it's fine. */ } if (m_Types[i].name) pTypeName = m_Types[i].name->chars(); else pTypeName = "ANON"; HANDLE_LOG_VERY_BAD("Type\t%-20.20s|\tCount\t%u", pTypeName, pCount[i]); } HANDLE_LOG_VERY_BAD("-- Approximately %d bytes of memory are in use by (%u) Handles.\n", total_size, total); delete [] pCount; highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak"); return scripts->UnloadPlugin(highest_owner); }