fix: memory leak of geos

This commit is contained in:
kailixu 2024-08-20 10:10:42 +08:00
parent 2f4d081592
commit 66878fd040
1 changed files with 31 additions and 14 deletions

View File

@ -14,14 +14,16 @@
*/ */
#include "tgeosctx.h" #include "tgeosctx.h"
#include "tarray.h"
#include "tdef.h" #include "tdef.h"
#include "tlockfree.h" #include "tlockfree.h"
#include "tlog.h" #include "tlog.h"
#define GEOS_POOL_CAPACITY 64
typedef struct { typedef struct {
SGeosContext *pool; SArray *poolArray; // totalSize: (GEOS_POOL_CAPACITY * (taosArrayGetSize(poolArray) - 1)) + size
int32_t capacity; SGeosContext *pool; // current SGeosContext pool
int32_t size; int32_t size; // size of current SGeosContext pool, size <= GEOS_POOL_CAPACITY
SRWLatch lock; SRWLatch lock;
} SGeosContextPool; } SGeosContextPool;
@ -34,16 +36,26 @@ SGeosContext *getThreadLocalGeosCtx() {
if (tlGeosCtx) return tlGeosCtx; if (tlGeosCtx) return tlGeosCtx;
taosWLockLatch(&sGeosPool.lock); taosWLockLatch(&sGeosPool.lock);
if (sGeosPool.size >= sGeosPool.capacity) { if (!sGeosPool.pool || sGeosPool.size >= GEOS_POOL_CAPACITY) {
sGeosPool.capacity += 128; if (!(sGeosPool.pool = (SGeosContext *)taosMemoryCalloc(GEOS_POOL_CAPACITY, sizeof(SGeosContext)))) {
void *tmp = taosMemoryRealloc(sGeosPool.pool, sGeosPool.capacity * sizeof(SGeosContext));
if (!tmp) {
taosWUnLockLatch(&sGeosPool.lock); taosWUnLockLatch(&sGeosPool.lock);
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL; return NULL;
} }
sGeosPool.pool = tmp; if (!sGeosPool.poolArray) {
TAOS_MEMSET(sGeosPool.pool + sGeosPool.size, 0, (sGeosPool.capacity - sGeosPool.size) * sizeof(SGeosContext)); if (!(sGeosPool.poolArray = taosArrayInit(16, POINTER_BYTES))) {
taosMemoryFree(sGeosPool.pool);
sGeosPool.pool = NULL;
taosWUnLockLatch(&sGeosPool.lock);
return NULL;
}
}
if (!taosArrayPush(sGeosPool.poolArray, &sGeosPool.pool)) {
taosMemoryFree(sGeosPool.pool);
sGeosPool.pool = NULL;
taosWUnLockLatch(&sGeosPool.lock);
return NULL;
}
sGeosPool.size = 0;
} }
tlGeosCtx = sGeosPool.pool + sGeosPool.size; tlGeosCtx = sGeosPool.pool + sGeosPool.size;
++sGeosPool.size; ++sGeosPool.size;
@ -91,9 +103,14 @@ static void destroyGeosCtx(SGeosContext *pCtx) {
void taosGeosDestroy() { void taosGeosDestroy() {
uInfo("geos is cleaned up"); uInfo("geos is cleaned up");
if (!sGeosPool.pool) return; int32_t size = taosArrayGetSize(sGeosPool.poolArray);
for (int32_t i = 0; i < sGeosPool.size; ++i) { for (int32_t i = 0; i < size; ++i) {
destroyGeosCtx(sGeosPool.pool + i); SGeosContext *pool = *(SGeosContext **)TARRAY_GET_ELEM(sGeosPool.poolArray, i);
for (int32_t j = 0; j < GEOS_POOL_CAPACITY; ++j) {
destroyGeosCtx(pool + j);
} }
taosMemoryFreeClear(sGeosPool.pool); taosMemoryFree(pool);
}
taosArrayDestroy(sGeosPool.poolArray);
sGeosPool.poolArray = NULL;
} }