From f3c4db4f30731f6cfc2c37a39d5ce3501d42f45e Mon Sep 17 00:00:00 2001 From: Martin Szulecki Date: Fri, 26 Dec 2014 12:23:52 +0100 Subject: thread: Introduce thread_new and thread_free to cover handle leaks on WIN32 --- common/thread.c | 15 +++++++++++---- common/thread.h | 3 ++- dev/afccheck.c | 3 ++- src/installation_proxy.c | 11 ++++++++--- src/notification_proxy.c | 5 ++++- src/syslog_relay.c | 5 ++++- tools/idevicedebugserverproxy.c | 12 +++++++++--- 7 files changed, 40 insertions(+), 14 deletions(-) diff --git a/common/thread.c b/common/thread.c index d6d6c1a..f4a00cf 100644 --- a/common/thread.c +++ b/common/thread.c @@ -21,13 +21,13 @@ #include "thread.h" -int thread_create(thread_t *thread, thread_func_t thread_func, void* data) +int thread_new(thread_t *thread, thread_func_t thread_func, void* data) { #ifdef WIN32 HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL); - if (th == NULL) { + if (th == NULL) { return -1; - } + } *thread = th; return 0; #else @@ -36,6 +36,13 @@ int thread_create(thread_t *thread, thread_func_t thread_func, void* data) #endif } +void thread_free(thread_t thread) +{ +#ifdef WIN32 + CloseHandle(thread); +#endif +} + void thread_join(thread_t thread) { /* wait for thread to complete */ @@ -95,5 +102,5 @@ void thread_once(thread_once_t *once_control, void (*init_routine)(void)) InterlockedExchange(&(once_control->lock), 0); #else pthread_once(once_control, init_routine); -#endif +#endif } diff --git a/common/thread.h b/common/thread.h index 9b15cc4..d0eebdf 100644 --- a/common/thread.h +++ b/common/thread.h @@ -43,7 +43,8 @@ typedef pthread_once_t thread_once_t; typedef void* (*thread_func_t)(void* data); -int thread_create(thread_t* thread, thread_func_t thread_func, void* data); +int thread_new(thread_t* thread, thread_func_t thread_func, void* data); +void thread_free(thread_t thread); void thread_join(thread_t thread); void mutex_init(mutex_t* mutex); diff --git a/dev/afccheck.c b/dev/afccheck.c index 3eb53c8..c534000 100644 --- a/dev/afccheck.c +++ b/dev/afccheck.c @@ -132,11 +132,12 @@ int main(int argc, char *argv[]) for (i = 0; i < NB_THREADS; i++) { data[i].afc = afc; data[i].id = i + 1; - thread_create(&threads[i], check_afc, data + i); + thread_new(&threads[i], check_afc, data + i); } for (i = 0; i < NB_THREADS; i++) { thread_join(threads[i]); + thread_free(threads[i]); } lockdownd_client_free(client); diff --git a/src/installation_proxy.c b/src/installation_proxy.c index d17d6c5..9a11e36 100644 --- a/src/installation_proxy.c +++ b/src/installation_proxy.c @@ -120,6 +120,8 @@ LIBIMOBILEDEVICE_API instproxy_error_t instproxy_client_free(instproxy_client_t if (client->status_updater) { debug_info("joining status_updater"); thread_join(client->status_updater); + thread_free(client->status_updater); + client->status_updater = (thread_t)NULL; } mutex_destroy(&client->mutex); free(client); @@ -320,7 +322,7 @@ static instproxy_error_t instproxy_perform_operation(instproxy_client_t client, * @return Always NULL. */ static void* instproxy_status_updater(void* arg) -{ +{ struct instproxy_status_data *data = (struct instproxy_status_data*)arg; /* run until the operation is complete or an error occurs */ @@ -332,7 +334,10 @@ static void* instproxy_status_updater(void* arg) if (data->operation) { free(data->operation); } - data->client->status_updater = (thread_t)NULL; + if (data->client->status_updater) { + thread_free(data->client->status_updater); + data->client->status_updater = (thread_t)NULL; + } instproxy_unlock(data->client); free(data); @@ -367,7 +372,7 @@ static instproxy_error_t instproxy_create_status_updater(instproxy_client_t clie data->operation = strdup(operation); data->user_data = user_data; - if (thread_create(&client->status_updater, instproxy_status_updater, data) == 0) { + if (thread_new(&client->status_updater, instproxy_status_updater, data) == 0) { res = INSTPROXY_E_SUCCESS; } } diff --git a/src/notification_proxy.c b/src/notification_proxy.c index 4b028f6..b22448d 100644 --- a/src/notification_proxy.c +++ b/src/notification_proxy.c @@ -131,6 +131,8 @@ LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client) if (client->notifier) { debug_info("joining np callback"); thread_join(client->notifier); + thread_free(client->notifier); + client->notifier = (thread_t)NULL; } else { dict = NULL; property_list_service_receive_plist(parent, &dict); @@ -347,6 +349,7 @@ LIBIMOBILEDEVICE_API np_error_t np_set_notify_callback( np_client_t client, np_n property_list_service_client_t parent = client->parent; client->parent = NULL; thread_join(client->notifier); + thread_free(client->notifier); client->notifier = (thread_t)NULL; client->parent = parent; } @@ -358,7 +361,7 @@ LIBIMOBILEDEVICE_API np_error_t np_set_notify_callback( np_client_t client, np_n npt->cbfunc = notify_cb; npt->user_data = user_data; - if (thread_create(&client->notifier, np_notifier, npt) == 0) { + if (thread_new(&client->notifier, np_notifier, npt) == 0) { res = NP_E_SUCCESS; } } diff --git a/src/syslog_relay.c b/src/syslog_relay.c index 44006ce..5ef64cd 100644 --- a/src/syslog_relay.c +++ b/src/syslog_relay.c @@ -106,6 +106,8 @@ LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_client_free(syslog_relay_ if (client->worker) { debug_info("Joining syslog capture callback worker thread"); thread_join(client->worker); + thread_free(client->worker); + client->worker = (thread_t)NULL; } free(client); @@ -190,7 +192,7 @@ LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_start_capture(syslog_rela srwt->cbfunc = callback; srwt->user_data = user_data; - if (thread_create(&client->worker, syslog_relay_worker, srwt) == 0) { + if (thread_new(&client->worker, syslog_relay_worker, srwt) == 0) { res = SYSLOG_RELAY_E_SUCCESS; } } @@ -206,6 +208,7 @@ LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_stop_capture(syslog_relay client->parent = NULL; /* join thread to make it exit */ thread_join(client->worker); + thread_free(client->worker); client->worker = (thread_t)NULL; client->parent = parent; } diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c index 9ccb3c3..475749f 100644 --- a/tools/idevicedebugserverproxy.c +++ b/tools/idevicedebugserverproxy.c @@ -139,7 +139,7 @@ static void *thread_client_to_device(void *data) /* spawn server to client thread */ socket_info->stop_dtoc = 0; - if (thread_create(&dtoc, thread_device_to_client, data) != 0) { + if (thread_new(&dtoc, thread_device_to_client, data) != 0) { fprintf(stderr, "Failed to start device to client thread...\n"); } @@ -187,6 +187,7 @@ static void *thread_client_to_device(void *data) /* join other thread to allow it to stop */ thread_join(dtoc); + thread_free(dtoc); return NULL; } @@ -200,12 +201,13 @@ static void* connection_handler(void* data) /* spawn client to device thread */ socket_info->stop_ctod = 0; - if (thread_create(&ctod, thread_client_to_device, data) != 0) { + if (thread_new(&ctod, thread_client_to_device, data) != 0) { fprintf(stderr, "Failed to start client to device thread...\n"); } /* join the fun */ thread_join(ctod); + thread_free(ctod); /* shutdown client socket */ socket_shutdown(socket_info->client_fd, SHUT_RDWR); @@ -348,11 +350,15 @@ int main(int argc, char *argv[]) debug("%s: Handling new client connection...\n", __func__); - if (thread_create(&th, connection_handler, (void*)&socket_info) != 0) { + if (thread_new(&th, connection_handler, (void*)&socket_info) != 0) { fprintf(stderr, "Could not start connection handler.\n"); socket_shutdown(socket_info.server_fd, SHUT_RDWR); socket_close(socket_info.server_fd); + continue; } + + /* we do not need it anymore */ + thread_free(th); } debug("%s: Shutting down debugserver proxy...\n", __func__); -- cgit v1.1-32-gdbae