fix: memory leak of geos

This commit is contained in:
kailixu 2024-08-28 19:12:23 +08:00
parent c301fe3940
commit 8b2af4f09d
5 changed files with 77 additions and 19 deletions

View File

@ -22,8 +22,12 @@
extern "C" { extern "C" {
#endif #endif
#if defined(WINDOWS) && !defined(__USE_PTHREAD) #if defined(WINDOWS)
#include <tlhelp32.h>
#include <windows.h> #include <windows.h>
#endif
#if defined(WINDOWS) && !defined(__USE_PTHREAD)
#define __USE_WIN_THREAD #define __USE_WIN_THREAD
// https://learn.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers // https://learn.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers
// #ifndef _WIN32_WINNT // #ifndef _WIN32_WINNT
@ -275,6 +279,10 @@ int32_t taosThreadSpinUnlock(TdThreadSpinlock *lock);
void taosThreadTestCancel(void); void taosThreadTestCancel(void);
void taosThreadClear(TdThread *thread); void taosThreadClear(TdThread *thread);
#ifdef WINDOWS
bool taosThreadIsMain();
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -320,20 +320,26 @@ void geomIoFuncTestAsTextFunction() {
callAsTextWrapper2(TSDB_DATA_TYPE_GEOMETRY, strInput, valTypeArray, 1, TSDB_CODE_FUNC_FUNTION_PARA_VALUE); callAsTextWrapper2(TSDB_DATA_TYPE_GEOMETRY, strInput, valTypeArray, 1, TSDB_CODE_FUNC_FUNTION_PARA_VALUE);
} }
static void *geomIoFuncTest(void *arg) { static void geomIoFuncTestImpl() {
geomIoFuncTestMakePointFunctionTwoColumns(); geomIoFuncTestMakePointFunctionTwoColumns();
geomIoFuncTestMakePointFunctionConstant(); geomIoFuncTestMakePointFunctionConstant();
geomIoFuncTestMakePointFunctionWithNull(); geomIoFuncTestMakePointFunctionWithNull();
geomIoFuncTestGeomFromTextFunction(); geomIoFuncTestGeomFromTextFunction();
geomIoFuncTestAsTextFunction(); geomIoFuncTestAsTextFunction();
return NULL;
} }
TEST(GeomIoFuncTest, summary) { static void *geomIoFuncTestFunc(void *arg) {
TdThread threadId; geomIoFuncTestImpl();
int32_t ret = taosThreadCreate(&threadId, NULL, geomIoFuncTest, 0); return nullptr;
ASSERT_EQ(ret, 0); }
ret = taosThreadJoin(threadId, NULL);
ASSERT_EQ(ret, 0); static void geomIoFuncTestInThread() {
TdThread thread;
ASSERT_EQ(taosThreadCreate(&thread, nullptr, geomIoFuncTestFunc, NULL), 0);
ASSERT_EQ(taosThreadJoin(thread, nullptr), 0);
}
TEST(threadGeomFuncTest, threadFuncTest) {
geomIoFuncTestImpl();
geomIoFuncTestInThread();
} }

View File

@ -238,21 +238,27 @@ void geomRelationFuncTestContainsProperlyFunction() {
geomRelationFuncTest(containsProperlyFunction, expectedResults); geomRelationFuncTest(containsProperlyFunction, expectedResults);
} }
static void *geomRelationFuncTest(void *arg) { static void geomRelationFuncTestImpl() {
geomRelationFuncTestIntersectsFunction(); geomRelationFuncTestIntersectsFunction();
geomRelationFuncTestEqualsFunction(); geomRelationFuncTestEqualsFunction();
geomRelationFuncTestTouchesFunction(); geomRelationFuncTestTouchesFunction();
geomRelationFuncTestCoversFunction(); geomRelationFuncTestCoversFunction();
geomRelationFuncTestContainsFunction(); geomRelationFuncTestContainsFunction();
geomRelationFuncTestContainsProperlyFunction(); geomRelationFuncTestContainsProperlyFunction();
return NULL;
} }
TEST(GeomRelationFuncTest, summary) { static void *geomRelationFuncTestFunc(void *arg) {
TdThread threadId; geomRelationFuncTestImpl();
int32_t ret = taosThreadCreate(&threadId, NULL, geomRelationFuncTest, 0); return nullptr;
ASSERT_EQ(ret, 0);
ret = taosThreadJoin(threadId, NULL);
ASSERT_EQ(ret, 0);
} }
static void geomRelationFuncTestInThread() {
TdThread thread;
ASSERT_EQ(taosThreadCreate(&thread, nullptr, geomRelationFuncTestFunc, NULL), 0);
ASSERT_EQ(taosThreadJoin(thread, nullptr), 0);
}
TEST(threadGeomRelationFuncTest, threadGeomRelationFuncTest) {
geomRelationFuncTestImpl();
geomRelationFuncTestInThread();
}

View File

@ -841,3 +841,35 @@ void taosThreadTestCancel(void) {
void taosThreadClear(TdThread *thread) { void taosThreadClear(TdThread *thread) {
(void)memset(thread, 0, sizeof(TdThread)); (void)memset(thread, 0, sizeof(TdThread));
} }
#ifdef WINDOWS
bool taosThreadIsMain() {
DWORD curProcessId = GetCurrentProcessId();
DWORD curThreadId = GetCurrentThreadId();
DWORD dwThreadId = -1;
HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnapshot == INVALID_HANDLE_VALUE) {
return false;
}
THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32);
if (!Thread32First(hThreadSnapshot, &te32)) {
CloseHandle(hThreadSnapshot);
return false;
}
do {
if (te32.th32OwnerProcessID == curProcessId) {
dwThreadId = te32.th32ThreadID;
break;
}
} while (Thread32Next(hThreadSnapshot, &te32));
CloseHandle(hThreadSnapshot);
return curThreadId == dwThreadId;
}
#endif

View File

@ -21,6 +21,10 @@ static TdThreadKey tlGeosCtxKey = 0;
static threadlocal SGeosContext *tlGeosCtx = NULL; static threadlocal SGeosContext *tlGeosCtx = NULL;
static void destroyThreadLocalGeosCtx(void *param) { static void destroyThreadLocalGeosCtx(void *param) {
#ifdef WINDOWS
if (taosThreadIsMain()) return;
#endif
SGeosContext *pGeosCtx = (SGeosContext *)param; SGeosContext *pGeosCtx = (SGeosContext *)param;
if (!pGeosCtx) { if (!pGeosCtx) {
return; return;
@ -72,9 +76,11 @@ int32_t getThreadLocalGeosCtx(SGeosContext **ppCtx) {
SGeosContext *tlGeosCtxObj = (SGeosContext *)taosMemoryCalloc(1, sizeof(SGeosContext)); SGeosContext *tlGeosCtxObj = (SGeosContext *)taosMemoryCalloc(1, sizeof(SGeosContext));
if (!tlGeosCtxObj) { if (!tlGeosCtxObj) {
taosThreadKeyDelete(tlGeosCtxKey);
TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY); TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
} }
if ((taosThreadSetSpecific(tlGeosCtxKey, (const void *)tlGeosCtxObj)) != 0) { if ((taosThreadSetSpecific(tlGeosCtxKey, (const void *)tlGeosCtxObj)) != 0) {
taosThreadKeyDelete(tlGeosCtxKey);
taosMemoryFreeClear(tlGeosCtxObj); taosMemoryFreeClear(tlGeosCtxObj);
TAOS_CHECK_EXIT(TAOS_SYSTEM_ERROR(errno)); TAOS_CHECK_EXIT(TAOS_SYSTEM_ERROR(errno));
} }