blob: 962ea075c3d3f0972a8302f582bef97112f7b59f [file] [log] [blame]
From b2829e3b352234dd2b7ddd683dc61b9c24329090 Mon Sep 17 00:00:00 2001
From: DavieV <davidvalleau@gmail.com>
Date: Tue, 17 Apr 2018 15:41:11 -0700
Subject: [PATCH 4/4] Changing unregister_service_thread to deallocate removed
thread params
The service_thread_param parameter for a communication thread was being
unallocated before calling to the thread cleanup handler. This sometimes
would result in an error as the entry in the service_threads list would
become invalid causing problems when attempting to unregister threads.
To fix this problem, the thread cleanup handler
(unregister_service_thread()) has been changed to also take care of
freeing the memory associated with the service_thread_param which was
removed.
---
src/ippusbxd.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/ippusbxd.c b/src/ippusbxd.c
index 5ef5d17..b655eb3 100644
--- a/src/ippusbxd.c
+++ b/src/ippusbxd.c
@@ -143,18 +143,27 @@ static int unregister_service_thread(
int i;
NOTE("Unregistering thread #%u", thread_num);
+ /* Search |service_threads| for an element with a matching thread number. */
for (i = 0; i < *num_service_threads; i ++)
if ((*service_threads)[i]->thread_num == thread_num)
break;
+
if (i >= *num_service_threads) {
ERR("Unregistering thread #%u: Cannot unregister, not found", thread_num);
return -1;
}
+
(*num_service_threads) --;
+ struct service_thread_param *removed_thread = (*service_threads)[i];
+ /* Shift the contents after |removed_thread| down. */
for (; i < *num_service_threads; i ++)
(*service_threads)[i] = (*service_threads)[i + 1];
- *service_threads = realloc(*service_threads,
- *num_service_threads * sizeof(void*));
+
+ free(removed_thread);
+
+ *service_threads =
+ realloc(*service_threads, *num_service_threads * sizeof(void *));
+
if (*num_service_threads == 0)
*service_threads = NULL;
else if (*service_threads == NULL) {
@@ -162,6 +171,7 @@ static int unregister_service_thread(
thread_num);
return -1;
}
+
return 0;
}
@@ -325,6 +335,8 @@ static void *service_connection(void *params_void)
if (setup_communication_thread(&service_printer_connection, printer_params))
goto cleanup;
+ pthread_t printer_params_thread_handle = printer_params->thread_handle;
+
/* This function will run until the socket has been closed. When this function
returns it means that the communication has been completed. */
service_socket_connection(params);
@@ -335,8 +347,8 @@ static void *service_connection(void *params_void)
/* Wait for the printer thread to exit. */
NOTE("Thread #%u: Waiting for thread #%u to complete", thread_num,
- printer_params->thread_num);
- if (pthread_join(printer_params->thread_handle, NULL))
+ thread_num + 1);
+ if (pthread_join(printer_params_thread_handle, NULL))
ERR("Thread #%u: Something went wrong trying to join the printer thread",
thread_num);
@@ -355,7 +367,6 @@ cleanup:
uds_conn_close(params->uds);
else
tcp_conn_close(params->tcp);
- free(params);
/* Execute clean-up handler. */
pthread_cleanup_pop(1);
--
2.17.0.484.g0c8726318c-goog