summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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
commit8a6d1e4074bbe26685f8c0ca6efef97d99680afb (patch)
tree38587a851094c9475e92515de076bebdd2e866d3 /src
parente68bb9339728134d780293bcda34ddbde633342a (diff)
Fucking annoying memory leak
Diffstat (limited to 'src')
-rwxr-xr-xsrc/main.c159
1 files 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 @@
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
17void * xcalloc(size_t nmemb, size_t size) { 18void * xcalloc(size_t nmemb, size_t size) {
@@ -99,10 +100,24 @@ void stack_free(stack *st) {
99 return; 100 return;
100} 101}
101 102
103int stack_getsize(stack * const st) {
104 if(!st)
105 return -1;
106
107 return st->size;
108}
109
110int stack_hasroom(stack * const st) {
111 if(!st)
112 return -1;
113
114 return (st->used < st->size);
115}
116
102int stack_push(stack *st, gdata *data) { 117int 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
113int stack_pushd(stack *st, void *data, fcallback fcb) { 128int 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
117gdata * stack_pop(stack *st) { 142gdata * stack_pop(stack *st) {
@@ -134,6 +159,129 @@ void * stack_popd(stack *st) {
134 159
135 160
136 161
162typedef struct cstack {
163 stack *stack;
164 mtx_t mutex;
165 cnd_t cond;
166 unsigned char canceled;
167} cstack;
168
169cstack * 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
182int 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
194void 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
206int 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
218int 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
230gdata * 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
255void * 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
137int main() { 285int 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