#include #include #include #include #include "arena.h" #include "arena_thread.h" #define TEST_FILE "/etc/os-release" void foo(arena_t *ar, const char *str) { ARENA_SCRATCH(arena, ar); arena_push(arena, 11); printf("Got: %s\n", str); } void test(void) { ARENA_SCRATCH(arena); foo(arena, arena_strdup(arena, "hello world")); } void arena_defer_test(arena_t *arena, void *data) { (void)data; (void)arena; printf("Cleanup!\n"); } void arena_defer_close_fn(arena_t *arena, void *data) { int fd = (intptr_t)data; printf("Closing file descriptor: %d\n", fd); close(fd); } bool arena_defer_close(arena_t *arena, int fd) { return arena_defer(arena, arena_defer_close_fn, (void *)(uintptr_t)fd); } void arena_defer_fclose_fn(arena_t *arena, void *data) { printf("Closing file: %p\n", data); fclose((FILE *)data); } bool arena_defer_fclose(arena_t *arena, FILE *f) { return arena_defer(arena, arena_defer_fclose_fn, f); } char *get_file(arena_t *arena, const char *path) { FILE *f; char *rc; size_t nr; char *buf; if ((f = fopen(path, "r")) == NULL) { return NULL; } if (!arena_defer_fclose(arena, f)) { return NULL; } buf = rc = arena_push(arena, 16); while ((nr = fread(buf, 1, 16, f)) >= 16) { buf = arena_push(arena, 16); } buf[nr] = '\0'; return rc; } void cleanup(void *p) { (void)p; printf("THREAD CLEANUP!\n"); } pthread_key_t key; void thr_defer_test(arena_t *a, void *t) { (void)t; printf("DEFER WORKS\n"); } void *thr_main(void *p) { arena_t *sc = arena_scratch(); arena_defer(sc, thr_defer_test, NULL); printf("> Going out of thread\n"); return NULL; } int main(void) { char *file; ARENA_SCRATCH(scratch); file = get_file(scratch, TEST_FILE); if (file == NULL) { printf("Error reading file: %s\n", TEST_FILE); } printf("FILE: %s\n", file); printf("NEW thread\n"); pthread_t thr; pthread_create(&thr, NULL, thr_main, NULL); printf("Joining thread ...\n"); pthread_join(thr, NULL); printf("THREAD EXIT!\n"); arena_t *sc = arena_scratch(scratch); arena_defer(sc, thr_defer_test, NULL); return 0; }