| 999 | logger->LogError(message, ##__VA_ARGS__); |
| 1000 | |
| 1001 | bool HandleSystem::TryAndFreeSomeHandles() |
| 1002 | { |
| 1003 | IPlugin *highest_owner = NULL; |
| 1004 | unsigned int highest_handle_count = 0; |
| 1005 | |
| 1006 | /* Search all plugins */ |
| 1007 | for (IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator(); pl_iter->MorePlugins(); pl_iter->NextPlugin()) |
| 1008 | { |
| 1009 | IPlugin *plugin = pl_iter->GetPlugin(); |
| 1010 | IdentityToken_t *identity = plugin->GetIdentity(); |
| 1011 | unsigned int handle_count = 0; |
| 1012 | |
| 1013 | if (identity == NULL) |
| 1014 | { |
| 1015 | continue; |
| 1016 | } |
| 1017 | |
| 1018 | /* Search all handles */ |
| 1019 | for (unsigned int i = 1; i <= m_HandleTail; i++) |
| 1020 | { |
| 1021 | if (m_Handles[i].set != HandleSet_Used) |
| 1022 | { |
| 1023 | continue; |
| 1024 | } |
| 1025 | if (m_Handles[i].owner == identity) |
| 1026 | { |
| 1027 | handle_count++; |
| 1028 | } |
| 1029 | } |
| 1030 | |
| 1031 | if (handle_count > highest_handle_count) |
| 1032 | { |
| 1033 | highest_owner = plugin; |
| 1034 | highest_handle_count = handle_count; |
| 1035 | } |
| 1036 | } |
| 1037 | |
| 1038 | if (highest_owner == NULL || highest_handle_count == 0) |
| 1039 | { |
| 1040 | return false; |
| 1041 | } |
| 1042 | |
| 1043 | HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename()); |
| 1044 | HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count); |
| 1045 | HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count); |
| 1046 | HANDLE_LOG_VERY_BAD("--------------------------------------------------------------------------"); |
| 1047 | |
| 1048 | const IdentityToken_t *pIdentity = highest_owner->GetIdentity(); |
| 1049 | unsigned int total = 0, highest_index = 0, total_size = 0, size; |
| 1050 | unsigned int * pCount = new unsigned int[HANDLESYS_TYPEARRAY_SIZE+1]; |
| 1051 | memset(pCount, 0, ((HANDLESYS_TYPEARRAY_SIZE + 1) * sizeof(unsigned int))); |
| 1052 | |
| 1053 | const QHandle *oldest = nullptr; |
| 1054 | const QHandle *newest = nullptr; |
| 1055 | for (unsigned int i = 1; i <= m_HandleTail; ++i) |
| 1056 | { |
| 1057 | const QHandle &Handle = m_Handles[i]; |
| 1058 | if (Handle.set != HandleSet_Used || Handle.owner != pIdentity) |
nothing calls this directly
no test coverage detected