From 8a6d1e4074bbe26685f8c0ca6efef97d99680afb Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Wed, 7 May 2025 22:32:28 -0500 Subject: Fucking annoying memory leak --- src/main.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index e08b964..c885c5e 100755 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,7 @@ #include #include #include +#include void * xcalloc(size_t nmemb, size_t size) { @@ -99,10 +100,24 @@ void stack_free(stack *st) { return; } +int stack_getsize(stack * const st) { + if(!st) + return -1; + + return st->size; +} + +int stack_hasroom(stack * const st) { + if(!st) + return -1; + + return (st->used < st->size); +} + int stack_push(stack *st, gdata *data) { if(!st || !data) return -1; - if(st->used == st->size) + if(!stack_hasroom(st)) return 0; st->arr[st->used++] = data; @@ -111,7 +126,17 @@ int stack_push(stack *st, gdata *data) { } int stack_pushd(stack *st, void *data, fcallback fcb) { - return stack_push(st, gdata_init(data, fcb)); + if(!st) + return -1; + if(!stack_hasroom(st)) + return 0; + + gdata *gd = gdata_init(data, fcb); + int retval = stack_push(st, gd); + if(!(retval > 0)) + gdata_free(gd); + + return retval; } gdata * stack_pop(stack *st) { @@ -134,6 +159,129 @@ void * stack_popd(stack *st) { +typedef struct cstack { + stack *stack; + mtx_t mutex; + cnd_t cond; + unsigned char canceled; +} cstack; + +cstack * cstack_init(int size) { + if(size < 1) + return NULL; + + cstack *cs = xcalloc(1, sizeof(*cs)); + cs->canceled = 0; + cs->stack = stack_init(size); + mtx_init(&cs->mutex, mtx_plain); + cnd_init(&cs->cond); + + return cs; +} + +int cstack_cancel(cstack *cs) { + if(!cs) + return -1; + + mtx_lock(&cs->mutex); + cs->canceled = 1; + mtx_unlock(&cs->mutex); + cnd_broadcast(&cs->cond); + + return 0; +} + +void cstack_free(cstack *cs) { + if(!cs) + return; + + cstack_cancel(cs); + stack_free(cs->stack); + mtx_destroy(&cs->mutex); + cnd_destroy(&cs->cond); + + return; +} + +int cstack_push(cstack *cs, gdata *data) { + if(!cs || !data) + return -1; + + mtx_lock(&cs->mutex); + stack_push(cs->stack, data); + mtx_unlock(&cs->mutex); + cnd_signal(&cs->cond); + + return 0; +} + +int cstack_pushd(cstack *cs, void *data, fcallback fcb) { + if(!cs) + return -1; + + mtx_lock(&cs->mutex); + stack_pushd(cs->stack, data, fcb); + mtx_unlock(&cs->mutex); + cnd_signal(&cs->cond); + + return 0; +} + +gdata * cstack_pop(cstack *cs) { + if(!cs) + return NULL; + + gdata *gd = NULL; + int csize = -1; + + mtx_lock(&cs->mutex); + + // Wait until there's data to pop or the thing gets canceled + for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;) + cnd_wait(&cs->cond, &cs->mutex); + + // If the stack was canceled, or there's an error, exit + if(cs->canceled || csize < 0) + thrd_exit(-1); + + // Otherwise, there's data, of which pop it to gd + gd = stack_pop(cs->stack); + + mtx_unlock(&cs->mutex); + + return gd; +} + +void * cstack_popd(cstack *cs) { + if(!cs) + return NULL; + + gdata *gd = NULL; + int csize = -1; + + mtx_lock(&cs->mutex); + + // Wait until there's data to pop or the thing gets canceled + for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;) + cnd_wait(&cs->cond, &cs->mutex); + + // If the stack was canceled, or there's an error, exit + if(cs->canceled || csize < 0) + thrd_exit(-1); + + // Otherwise, there's data, of which pop it to gd + gd = stack_pop(cs->stack); + + mtx_unlock(&cs->mutex); + + void *realdata = NULL; + gdata_destruct(gd, &realdata); + + return realdata; +} + + + int main() { // stack *st = stack_init(10); // stack_pushd(st, (void*)10, NULL); @@ -147,6 +295,13 @@ int main() { // stack_free(st); + cstack *cst = cstack_init(10); + cstack_pushd(cst, (void*)10, NULL); + cstack_pushd(cst, (void*)11, NULL); + cstack_pushd(cst, (void*)12, NULL); + cstack_pushd(cst, (void*)strdup("This is some data"), free); + + cstack_free(cst); return 0; } \ No newline at end of file -- cgit v1.2.3