diff options
author | David Phillips <david@sighup.nz> | 2016-10-26 17:54:11 +1300 |
---|---|---|
committer | David Phillips <david@sighup.nz> | 2016-10-26 17:54:11 +1300 |
commit | 611ab4dc0994d18922b1be9070c33966f394a8e4 (patch) | |
tree | dc8df84142383aad545f774a02f44ffab66e12ca | |
parent | 1c5db4493775822a35aa8cd442e9a633de0b5100 (diff) | |
download | fractal-gen-611ab4dc0994d18922b1be9070c33966f394a8e4.tar.xz |
pthread_create error, attempt better resource free
-rw-r--r-- | fractal-gen.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/fractal-gen.c b/fractal-gen.c index 3dbf505..8ae45d9 100644 --- a/fractal-gen.c +++ b/fractal-gen.c @@ -37,6 +37,7 @@ #include <sys/mman.h> #include <string.h> +pid_t child = -1; struct frame f; static struct section_generator generators[] = { @@ -74,9 +75,46 @@ void return NULL; } +void +handle_signal(int sig) { + switch (sig) { + case SIGSEGV: + /* kill the forked thread and abort */ + if (child > 0) { + kill(child, SIGKILL); + abort(); + } + break; + default: + /* do nothing */ + break; + } +} + +void +install_sigaction(void handler(int)) { + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + sigaction(SIGSEGV, &sa, NULL); +} + +void +destroy_sections(data_section **s, unsigned long count) { + unsigned long i = 0; + + /* free malloced data memory */ + for (i = 0; i < count; i++) { + free((*s)[i].data); + } + + /* unmap mmapped sections */ + munmap(s, sizeof(data_section)*threads); +} + int -main(int argc, char **argv) -{ +main(int argc, char **argv) { unsigned long x = 0; unsigned long width = 0; size_t toalloc = 0; @@ -88,11 +126,13 @@ main(int argc, char **argv) data_section* sections = NULL; data_section *s = NULL; generator_func generator = NULL; - pid_t child = 0; /* who are we? */ argv0 = argv[0]; + /* set up signal handler */ + install_sigaction(handle_signal); + /* Select correct generator for the fractal type */ bname = basename(argv[0]); generator = select_generator(bname); @@ -151,12 +191,8 @@ main(int argc, char **argv) fprintf(stderr, "\nmalloc of %zd bytes failed\n", toalloc); perror("malloc"); - /* Free already allocated chunks of memory */ - i--; - while(i-- + 1) - free(sections[i].data); - - munmap(sections, sizeof(data_section)*threads); + /* free resources allocated to sections array */ + destroy_sections(§ions, i-1); return 1; } /* FIXME repetition */ @@ -168,7 +204,11 @@ main(int argc, char **argv) sections[i].parent_frame.scale = f.scale; sections[i].datasize = toalloc; fprintf(stderr, " -> Thread %lu\r", i); - pthread_create(§ions[i].thread, NULL, generate, &(sections[i])); + if (pthread_create(§ions[i].thread, NULL, generate, &(sections[i])) != 0) { + perror("pthread_create"); + destroy_sections(§ions, i); + return 1; + } } s = &(sections[threads-1]); @@ -224,11 +264,7 @@ main(int argc, char **argv) } } - /* Free the memory we allocated for point data */ - for (i = 0; i < threads; i++) - free(sections[i].data); - - munmap(sections, sizeof(data_section)*threads); + destroy_sections(§ions, threads); return 0; } |