diff options
| author | @syxhe <https://t.me/syxhe> | 2025-05-07 22:32:28 -0500 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2025-05-07 22:32:28 -0500 |
| commit | 8a6d1e4074bbe26685f8c0ca6efef97d99680afb (patch) | |
| tree | 38587a851094c9475e92515de076bebdd2e866d3 /src/main.c | |
| parent | e68bb9339728134d780293bcda34ddbde633342a (diff) | |
Fucking annoying memory leak
Diffstat (limited to 'src/main.c')
| -rwxr-xr-x | src/main.c | 159 |
1 files changed, 157 insertions, 2 deletions
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <sys/types.h> | 12 | #include <sys/types.h> |
| 13 | #include <string.h> | 13 | #include <string.h> |
| 14 | #include <stdio.h> | 14 | #include <stdio.h> |
| 15 | #include <threads.h> | ||
| 15 | 16 | ||
| 16 | 17 | ||
| 17 | void * xcalloc(size_t nmemb, size_t size) { | 18 | void * xcalloc(size_t nmemb, size_t size) { |
| @@ -99,10 +100,24 @@ void stack_free(stack *st) { | |||
| 99 | return; | 100 | return; |
| 100 | } | 101 | } |
| 101 | 102 | ||
| 103 | int stack_getsize(stack * const st) { | ||
| 104 | if(!st) | ||
| 105 | return -1; | ||
| 106 | |||
| 107 | return st->size; | ||
| 108 | } | ||
| 109 | |||
| 110 | int stack_hasroom(stack * const st) { | ||
| 111 | if(!st) | ||
| 112 | return -1; | ||
| 113 | |||
| 114 | return (st->used < st->size); | ||
| 115 | } | ||
| 116 | |||
| 102 | int stack_push(stack *st, gdata *data) { | 117 | int stack_push(stack *st, gdata *data) { |
| 103 | if(!st || !data) | 118 | if(!st || !data) |
| 104 | return -1; | 119 | return -1; |
| 105 | if(st->used == st->size) | 120 | if(!stack_hasroom(st)) |
| 106 | return 0; | 121 | return 0; |
| 107 | 122 | ||
| 108 | st->arr[st->used++] = data; | 123 | st->arr[st->used++] = data; |
| @@ -111,7 +126,17 @@ int stack_push(stack *st, gdata *data) { | |||
| 111 | } | 126 | } |
| 112 | 127 | ||
| 113 | int stack_pushd(stack *st, void *data, fcallback fcb) { | 128 | int stack_pushd(stack *st, void *data, fcallback fcb) { |
| 114 | return stack_push(st, gdata_init(data, fcb)); | 129 | if(!st) |
| 130 | return -1; | ||
| 131 | if(!stack_hasroom(st)) | ||
| 132 | return 0; | ||
| 133 | |||
| 134 | gdata *gd = gdata_init(data, fcb); | ||
| 135 | int retval = stack_push(st, gd); | ||
| 136 | if(!(retval > 0)) | ||
| 137 | gdata_free(gd); | ||
| 138 | |||
| 139 | return retval; | ||
| 115 | } | 140 | } |
| 116 | 141 | ||
| 117 | gdata * stack_pop(stack *st) { | 142 | gdata * stack_pop(stack *st) { |
| @@ -134,6 +159,129 @@ void * stack_popd(stack *st) { | |||
| 134 | 159 | ||
| 135 | 160 | ||
| 136 | 161 | ||
| 162 | typedef struct cstack { | ||
| 163 | stack *stack; | ||
| 164 | mtx_t mutex; | ||
| 165 | cnd_t cond; | ||
| 166 | unsigned char canceled; | ||
| 167 | } cstack; | ||
| 168 | |||
| 169 | cstack * cstack_init(int size) { | ||
| 170 | if(size < 1) | ||
| 171 | return NULL; | ||
| 172 | |||
| 173 | cstack *cs = xcalloc(1, sizeof(*cs)); | ||
| 174 | cs->canceled = 0; | ||
| 175 | cs->stack = stack_init(size); | ||
| 176 | mtx_init(&cs->mutex, mtx_plain); | ||
| 177 | cnd_init(&cs->cond); | ||
| 178 | |||
| 179 | return cs; | ||
| 180 | } | ||
| 181 | |||
| 182 | int cstack_cancel(cstack *cs) { | ||
| 183 | if(!cs) | ||
| 184 | return -1; | ||
| 185 | |||
| 186 | mtx_lock(&cs->mutex); | ||
| 187 | cs->canceled = 1; | ||
| 188 | mtx_unlock(&cs->mutex); | ||
| 189 | cnd_broadcast(&cs->cond); | ||
| 190 | |||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | |||
| 194 | void cstack_free(cstack *cs) { | ||
| 195 | if(!cs) | ||
| 196 | return; | ||
| 197 | |||
| 198 | cstack_cancel(cs); | ||
| 199 | stack_free(cs->stack); | ||
| 200 | mtx_destroy(&cs->mutex); | ||
| 201 | cnd_destroy(&cs->cond); | ||
| 202 | |||
| 203 | return; | ||
| 204 | } | ||
| 205 | |||
| 206 | int cstack_push(cstack *cs, gdata *data) { | ||
| 207 | if(!cs || !data) | ||
| 208 | return -1; | ||
| 209 | |||
| 210 | mtx_lock(&cs->mutex); | ||
| 211 | stack_push(cs->stack, data); | ||
| 212 | mtx_unlock(&cs->mutex); | ||
| 213 | cnd_signal(&cs->cond); | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | int cstack_pushd(cstack *cs, void *data, fcallback fcb) { | ||
| 219 | if(!cs) | ||
| 220 | return -1; | ||
| 221 | |||
| 222 | mtx_lock(&cs->mutex); | ||
| 223 | stack_pushd(cs->stack, data, fcb); | ||
| 224 | mtx_unlock(&cs->mutex); | ||
| 225 | cnd_signal(&cs->cond); | ||
| 226 | |||
| 227 | return 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | gdata * cstack_pop(cstack *cs) { | ||
| 231 | if(!cs) | ||
| 232 | return NULL; | ||
| 233 | |||
| 234 | gdata *gd = NULL; | ||
| 235 | int csize = -1; | ||
| 236 | |||
| 237 | mtx_lock(&cs->mutex); | ||
| 238 | |||
| 239 | // Wait until there's data to pop or the thing gets canceled | ||
| 240 | for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;) | ||
| 241 | cnd_wait(&cs->cond, &cs->mutex); | ||
| 242 | |||
| 243 | // If the stack was canceled, or there's an error, exit | ||
| 244 | if(cs->canceled || csize < 0) | ||
| 245 | thrd_exit(-1); | ||
| 246 | |||
| 247 | // Otherwise, there's data, of which pop it to gd | ||
| 248 | gd = stack_pop(cs->stack); | ||
| 249 | |||
| 250 | mtx_unlock(&cs->mutex); | ||
| 251 | |||
| 252 | return gd; | ||
| 253 | } | ||
| 254 | |||
| 255 | void * cstack_popd(cstack *cs) { | ||
| 256 | if(!cs) | ||
| 257 | return NULL; | ||
| 258 | |||
| 259 | gdata *gd = NULL; | ||
| 260 | int csize = -1; | ||
| 261 | |||
| 262 | mtx_lock(&cs->mutex); | ||
| 263 | |||
| 264 | // Wait until there's data to pop or the thing gets canceled | ||
| 265 | for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;) | ||
| 266 | cnd_wait(&cs->cond, &cs->mutex); | ||
| 267 | |||
| 268 | // If the stack was canceled, or there's an error, exit | ||
| 269 | if(cs->canceled || csize < 0) | ||
| 270 | thrd_exit(-1); | ||
| 271 | |||
| 272 | // Otherwise, there's data, of which pop it to gd | ||
| 273 | gd = stack_pop(cs->stack); | ||
| 274 | |||
| 275 | mtx_unlock(&cs->mutex); | ||
| 276 | |||
| 277 | void *realdata = NULL; | ||
| 278 | gdata_destruct(gd, &realdata); | ||
| 279 | |||
| 280 | return realdata; | ||
| 281 | } | ||
| 282 | |||
| 283 | |||
| 284 | |||
| 137 | int main() { | 285 | int main() { |
| 138 | // stack *st = stack_init(10); | 286 | // stack *st = stack_init(10); |
| 139 | // stack_pushd(st, (void*)10, NULL); | 287 | // stack_pushd(st, (void*)10, NULL); |
| @@ -147,6 +295,13 @@ int main() { | |||
| 147 | 295 | ||
| 148 | // stack_free(st); | 296 | // stack_free(st); |
| 149 | 297 | ||
| 298 | cstack *cst = cstack_init(10); | ||
| 299 | cstack_pushd(cst, (void*)10, NULL); | ||
| 300 | cstack_pushd(cst, (void*)11, NULL); | ||
| 301 | cstack_pushd(cst, (void*)12, NULL); | ||
| 302 | cstack_pushd(cst, (void*)strdup("This is some data"), free); | ||
| 303 | |||
| 304 | cstack_free(cst); | ||
| 150 | 305 | ||
| 151 | return 0; | 306 | return 0; |
| 152 | } \ No newline at end of file | 307 | } \ No newline at end of file |
