containers minimum elements, windows memory leaks

This commit is contained in:
2022-04-25 21:43:57 +03:00
parent 90afc369f0
commit 5f8c04a78e
7 changed files with 81 additions and 22 deletions

View File

@@ -0,0 +1,34 @@
/*
PIP - Platform Independent Primitives
Base macros for generic containers
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "picontainers.h"
const ssize_t minAlloc = 64;
ssize_t _PIContainerConstantsBase::calcMinCountPoT(ssize_t szof) {
ssize_t ret = 0, elc = 1;
while (elc * szof < minAlloc) {
elc *= 2;
++ret;
}
//printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, ret);
return ret;
}

View File

@@ -63,6 +63,18 @@ private:
}; };
class PIP_EXPORT _PIContainerConstantsBase {
public:
static ssize_t calcMinCountPoT(ssize_t szof);
};
template<typename T>
class _PIContainerConstants {
public:
static ssize_t minCountPoT() {static ssize_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); return ret;}
};
//! \brief //! \brief
//! \~english Template reverse wrapper over any container //! \~english Template reverse wrapper over any container
//! \~russian Шаблонная функция обертки любого контейнера для обратного доступа через итераторы //! \~russian Шаблонная функция обертки любого контейнера для обратного доступа через итераторы

View File

@@ -2280,10 +2280,9 @@ private:
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) { if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) {
return pid_rsize + pid_rsize; return pid_rsize + pid_rsize;
} }
ssize_t t = 0, s_ = s - 1; ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
while (s_ >> t) { while (s_ >> t)
++t; ++t;
}
return (1 << t); return (1 << t);
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<

View File

@@ -2205,8 +2205,9 @@ private:
if (piv_rsize + piv_rsize >= s && piv_rsize < s) { if (piv_rsize + piv_rsize >= s && piv_rsize < s) {
return piv_rsize + piv_rsize; return piv_rsize + piv_rsize;
} }
ssize_t t = 0, s_ = s - 1; ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
while (s_ >> t) ++t; while (s_ >> t)
++t;
return (1 << t); return (1 << t);
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<

View File

@@ -64,10 +64,16 @@ void errorClear() {
PIString errorString() { PIString errorString() {
#ifdef WINDOWS #ifdef WINDOWS
char * msg; char * msg = nullptr;
int err = GetLastError(); int err = GetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL); FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
return "code " + PIString::fromNumber(err) + " - " + PIString(msg); PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
if (msg) {
ret += PIString::fromSystem(msg).trim();
LocalFree(msg);
} else
ret += '?';
return ret;
#else #else
int e = errno; int e = errno;
return PIString("code ") + PIString::fromNumber(e) + " - " + PIString(strerror(e)); return PIString("code ") + PIString::fromNumber(e) + " - " + PIString(strerror(e));

View File

@@ -1001,24 +1001,23 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
ci.index = -1; ci.index = -1;
ci.mtu = 1500; ci.mtu = 1500;
#ifdef WINDOWS #ifdef WINDOWS
PIP_ADAPTER_INFO pAdapterInfo, pAdapter = 0;
int ret = 0; int ret = 0;
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO); ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO * ) HeapAlloc(GetProcessHeap(), 0, (sizeof (IP_ADAPTER_INFO))); PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == 0) { if (!pAdapterInfo) {
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo"; piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersInfo";
return il; return il;
} }
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
HeapFree(GetProcessHeap(), 0, (pAdapterInfo)); HeapFree(GetProcessHeap(), 0, pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) HeapAlloc(GetProcessHeap(), 0, (ulOutBufLen)); pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, ulOutBufLen);
if (pAdapterInfo == 0) { if (!pAdapterInfo) {
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersinfo"; piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersInfo";
return il; return il;
} }
} }
if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo; PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) { while (pAdapter) {
ci.name = PIString(pAdapter->AdapterName); ci.name = PIString(pAdapter->AdapterName);
ci.index = pAdapter->Index; ci.index = pAdapter->Index;
@@ -1031,8 +1030,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
IP_ADDR_STRING * as = &(pAdapter->IpAddressList); IP_ADDR_STRING * as = &(pAdapter->IpAddressList);
while (as) { while (as) {
// piCout << "[pAdapter]" << ci.name << PIString(as->IpAddress.String); // piCout << "[pAdapter]" << ci.name << PIString(as->IpAddress.String);
ci.address = PIString(as->IpAddress.String); ci.address = PIStringAscii(as->IpAddress.String);
ci.netmask = PIString(as->IpMask.String); ci.netmask = PIStringAscii(as->IpMask.String);
if (ci.address == "0.0.0.0") { if (ci.address == "0.0.0.0") {
as = as->Next; as = as->Next;
continue; continue;
@@ -1053,7 +1052,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
} }
} }
if (pAdapterInfo) if (pAdapterInfo)
HeapFree(GetProcessHeap(), 0, (pAdapterInfo)); HeapFree(GetProcessHeap(), 0, pAdapterInfo);
#else #else
#ifdef MICRO_PIP #ifdef MICRO_PIP
#else #else
@@ -1213,10 +1212,16 @@ int PIEthernet::ethErrorCore() {
PIString PIEthernet::ethErrorString() { PIString PIEthernet::ethErrorString() {
#ifdef WINDOWS #ifdef WINDOWS
char * msg; char * msg = nullptr;
int err = WSAGetLastError(); int err = WSAGetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL); FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
return "code " + PIString::fromNumber(err) + " - " + PIString(msg); PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
if (msg) {
ret += PIString::fromSystem(msg).trim();
LocalFree(msg);
} else
ret += '?';
return ret;
#else #else
return errorString(); return errorString();
#endif #endif

View File

@@ -356,6 +356,7 @@ void PISystemMonitor::run() {
void PISystemMonitor::gatherThread(llong id) { void PISystemMonitor::gatherThread(llong id) {
PISystemMonitor::ThreadStats ts; PISystemMonitor::ThreadStats ts;
if (id == 0) return;
ts.id = id; ts.id = id;
#ifdef MICRO_PIP #ifdef MICRO_PIP
ts.name = tbid.value(id, "<PIThread>"); ts.name = tbid.value(id, "<PIThread>");
@@ -386,11 +387,12 @@ void PISystemMonitor::gatherThread(llong id) {
PISystemTime ct = PISystemTime::current(); PISystemTime ct = PISystemTime::current();
FILETIME times[4]; FILETIME times[4];
HANDLE thdl = OpenThread(THREAD_QUERY_INFORMATION, FALSE, DWORD(id)); HANDLE thdl = OpenThread(THREAD_QUERY_INFORMATION, FALSE, DWORD(id));
if (thdl == NULL) { if (!thdl) {
piCout << "[PISystemMonitor] gatherThread(" << id << "):: OpenThread() error:" << errorString(); piCout << "[PISystemMonitor] gatherThread(" << id << "):: OpenThread() error:" << errorString();
return; return;
} }
if (GetThreadTimes(thdl, &(times[0]), &(times[1]), &(times[2]), &(times[3])) == 0) { if (GetThreadTimes(thdl, &(times[0]), &(times[1]), &(times[2]), &(times[3])) == 0) {
CloseHandle(thdl);
piCout << "[PISystemMonitor] gatherThread(" << id << "):: GetThreadTimes() error:" << errorString(); piCout << "[PISystemMonitor] gatherThread(" << id << "):: GetThreadTimes() error:" << errorString();
return; return;
} }