Fix memory leak when nb sends fail

master
Nick Krichevsky 2019-09-26 12:23:24 -04:00
parent ff1c70f0dd
commit 14705bb277
2 changed files with 18 additions and 9 deletions

View File

@ -13,10 +13,10 @@
*/ */
void *adder(void *raw_mailbox_id) { void *adder(void *raw_mailbox_id) {
int mailbox_id = *(int*)(raw_mailbox_id); int mailbox_id = *(int*)(raw_mailbox_id);
int *ret_val = malloc(sizeof(int));
// If we're thread 0, we shouldn't be running adder. // If we're thread 0, we shouldn't be running adder.
// Any thread id below 0 is invalid. // Any thread id below 0 is invalid.
if (mailbox_id <= 0) { if (mailbox_id <= 0) {
int *ret_val = malloc(sizeof(int));
*ret_val = -1; *ret_val = -1;
return ret_val; return ret_val;
} }
@ -28,6 +28,7 @@ void *adder(void *raw_mailbox_id) {
while (true) { while (true) {
int recv_result = RecvMsg(mailbox_id, &message); int recv_result = RecvMsg(mailbox_id, &message);
if (recv_result != 0) { if (recv_result != 0) {
int *ret_val = malloc(sizeof(int));
*ret_val = -1; *ret_val = -1;
return ret_val; return ret_val;
} }
@ -52,10 +53,12 @@ void *adder(void *raw_mailbox_id) {
int send_result = SendMsg(0, &res_mesage); int send_result = SendMsg(0, &res_mesage);
if (send_result < 0) { if (send_result < 0) {
int *ret_val = malloc(sizeof(int));
*ret_val = -1; *ret_val = -1;
return ret_val; return ret_val;
} }
int *ret_val = malloc(sizeof(int));
*ret_val = 0; *ret_val = 0;
return ret_val; return ret_val;
} }

22
main.c
View File

@ -79,10 +79,15 @@ static int get_input(int num_threads, struct input **res) {
* Kills the given thread. Should only be used in exceptional circumstances. * Kills the given thread. Should only be used in exceptional circumstances.
* *
* @param thread The thread to kill. * @param thread The thread to kill.
* @param free_ret If true, the memory associated with the return value will be freed.
*/ */
static void kill_thread(pthread_t thread) { static void kill_thread(pthread_t thread, bool free_ret) {
pthread_cancel(thread); pthread_cancel(thread);
pthread_join(thread, NULL); void *ret;
pthread_join(thread, free_ret ? &ret : NULL);
if (free_ret && ret != PTHREAD_CANCELED) {
free(ret);
}
} }
/** /**
@ -90,10 +95,11 @@ static void kill_thread(pthread_t thread) {
* *
* @param threads An array of threads to kill. * @param threads An array of threads to kill.
* @param num_threads The number of threads to kill. * @param num_threads The number of threads to kill.
* @param free_ret If true, the memory associated with the return value will be freed.
*/ */
static void kill_threads(pthread_t *threads, int num_threads) { static void kill_threads(pthread_t *threads, int num_threads, bool free_ret) {
for (int i = 0; i < num_threads; i++) { for (int i = 0; i < num_threads; i++) {
kill_thread(threads[i]); kill_thread(threads[i], free_ret);
} }
} }
@ -142,7 +148,7 @@ static int start_adder_threads(int *thread_ids, int num_threads, pthread_t *thre
int create_result = pthread_create(&threads[i], NULL, adder, &thread_ids[i]); int create_result = pthread_create(&threads[i], NULL, adder, &thread_ids[i]);
if (create_result != 0) { if (create_result != 0) {
// Kill the i threads that we have spawned. // Kill the i threads that we have spawned.
kill_threads(threads, i); kill_threads(threads, i, true);
return -1; return -1;
} }
@ -426,7 +432,7 @@ int main(int argc, char *argv[]) {
if (spawn_result != 0) { if (spawn_result != 0) {
printf("Failed to spawn collection thread.\n"); printf("Failed to spawn collection thread.\n");
free(inputs); free(inputs);
kill_threads(adder_threads, num_adder_threads); kill_threads(adder_threads, num_adder_threads, true);
free_mailboxes(); free_mailboxes();
return 1; return 1;
} }
@ -440,8 +446,8 @@ int main(int argc, char *argv[]) {
free(inputs); free(inputs);
if (send_result != 0) { if (send_result != 0) {
kill_threads(adder_threads, num_adder_threads); kill_threads(adder_threads, num_adder_threads, true);
kill_thread(collect_thread); kill_thread(collect_thread, false);
free_mailboxes(); free_mailboxes();
return 1; return 1;
} }