diff options
| author | 2014-12-26 12:23:52 +0100 | |
|---|---|---|
| committer | 2015-01-13 00:14:55 +0100 | |
| commit | f3c4db4f30731f6cfc2c37a39d5ce3501d42f45e (patch) | |
| tree | caa0ffcfdd84a31c945408e9e7ccd56b72318e2e | |
| parent | aa14c053bc909c56d31c12799f13013f845ddb71 (diff) | |
| download | libimobiledevice-f3c4db4f30731f6cfc2c37a39d5ce3501d42f45e.tar.gz libimobiledevice-f3c4db4f30731f6cfc2c37a39d5ce3501d42f45e.tar.bz2 | |
thread: Introduce thread_new and thread_free to cover handle leaks on WIN32
| -rw-r--r-- | common/thread.c | 15 | ||||
| -rw-r--r-- | common/thread.h | 3 | ||||
| -rw-r--r-- | dev/afccheck.c | 3 | ||||
| -rw-r--r-- | src/installation_proxy.c | 11 | ||||
| -rw-r--r-- | src/notification_proxy.c | 5 | ||||
| -rw-r--r-- | src/syslog_relay.c | 5 | ||||
| -rw-r--r-- | 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 @@ | |||
| 21 | 21 | ||
| 22 | #include "thread.h" | 22 | #include "thread.h" |
| 23 | 23 | ||
| 24 | int thread_create(thread_t *thread, thread_func_t thread_func, void* data) | 24 | int thread_new(thread_t *thread, thread_func_t thread_func, void* data) |
| 25 | { | 25 | { |
| 26 | #ifdef WIN32 | 26 | #ifdef WIN32 |
| 27 | HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL); | 27 | HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL); |
| 28 | if (th == NULL) { | 28 | if (th == NULL) { |
| 29 | return -1; | 29 | return -1; |
| 30 | } | 30 | } |
| 31 | *thread = th; | 31 | *thread = th; |
| 32 | return 0; | 32 | return 0; |
| 33 | #else | 33 | #else |
| @@ -36,6 +36,13 @@ int thread_create(thread_t *thread, thread_func_t thread_func, void* data) | |||
| 36 | #endif | 36 | #endif |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void thread_free(thread_t thread) | ||
| 40 | { | ||
| 41 | #ifdef WIN32 | ||
| 42 | CloseHandle(thread); | ||
| 43 | #endif | ||
| 44 | } | ||
| 45 | |||
| 39 | void thread_join(thread_t thread) | 46 | void thread_join(thread_t thread) |
| 40 | { | 47 | { |
| 41 | /* wait for thread to complete */ | 48 | /* wait for thread to complete */ |
| @@ -95,5 +102,5 @@ void thread_once(thread_once_t *once_control, void (*init_routine)(void)) | |||
| 95 | InterlockedExchange(&(once_control->lock), 0); | 102 | InterlockedExchange(&(once_control->lock), 0); |
| 96 | #else | 103 | #else |
| 97 | pthread_once(once_control, init_routine); | 104 | pthread_once(once_control, init_routine); |
| 98 | #endif | 105 | #endif |
| 99 | } | 106 | } |
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; | |||
| 43 | 43 | ||
| 44 | typedef void* (*thread_func_t)(void* data); | 44 | typedef void* (*thread_func_t)(void* data); |
| 45 | 45 | ||
| 46 | int thread_create(thread_t* thread, thread_func_t thread_func, void* data); | 46 | int thread_new(thread_t* thread, thread_func_t thread_func, void* data); |
| 47 | void thread_free(thread_t thread); | ||
| 47 | void thread_join(thread_t thread); | 48 | void thread_join(thread_t thread); |
| 48 | 49 | ||
| 49 | void mutex_init(mutex_t* mutex); | 50 | 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[]) | |||
| 132 | for (i = 0; i < NB_THREADS; i++) { | 132 | for (i = 0; i < NB_THREADS; i++) { |
| 133 | data[i].afc = afc; | 133 | data[i].afc = afc; |
| 134 | data[i].id = i + 1; | 134 | data[i].id = i + 1; |
| 135 | thread_create(&threads[i], check_afc, data + i); | 135 | thread_new(&threads[i], check_afc, data + i); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | for (i = 0; i < NB_THREADS; i++) { | 138 | for (i = 0; i < NB_THREADS; i++) { |
| 139 | thread_join(threads[i]); | 139 | thread_join(threads[i]); |
| 140 | thread_free(threads[i]); | ||
| 140 | } | 141 | } |
| 141 | 142 | ||
| 142 | lockdownd_client_free(client); | 143 | 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 | |||
| 120 | if (client->status_updater) { | 120 | if (client->status_updater) { |
| 121 | debug_info("joining status_updater"); | 121 | debug_info("joining status_updater"); |
| 122 | thread_join(client->status_updater); | 122 | thread_join(client->status_updater); |
| 123 | thread_free(client->status_updater); | ||
| 124 | client->status_updater = (thread_t)NULL; | ||
| 123 | } | 125 | } |
| 124 | mutex_destroy(&client->mutex); | 126 | mutex_destroy(&client->mutex); |
| 125 | free(client); | 127 | free(client); |
| @@ -320,7 +322,7 @@ static instproxy_error_t instproxy_perform_operation(instproxy_client_t client, | |||
| 320 | * @return Always NULL. | 322 | * @return Always NULL. |
| 321 | */ | 323 | */ |
| 322 | static void* instproxy_status_updater(void* arg) | 324 | static void* instproxy_status_updater(void* arg) |
| 323 | { | 325 | { |
| 324 | struct instproxy_status_data *data = (struct instproxy_status_data*)arg; | 326 | struct instproxy_status_data *data = (struct instproxy_status_data*)arg; |
| 325 | 327 | ||
| 326 | /* run until the operation is complete or an error occurs */ | 328 | /* run until the operation is complete or an error occurs */ |
| @@ -332,7 +334,10 @@ static void* instproxy_status_updater(void* arg) | |||
| 332 | if (data->operation) { | 334 | if (data->operation) { |
| 333 | free(data->operation); | 335 | free(data->operation); |
| 334 | } | 336 | } |
| 335 | data->client->status_updater = (thread_t)NULL; | 337 | if (data->client->status_updater) { |
| 338 | thread_free(data->client->status_updater); | ||
| 339 | data->client->status_updater = (thread_t)NULL; | ||
| 340 | } | ||
| 336 | instproxy_unlock(data->client); | 341 | instproxy_unlock(data->client); |
| 337 | free(data); | 342 | free(data); |
| 338 | 343 | ||
| @@ -367,7 +372,7 @@ static instproxy_error_t instproxy_create_status_updater(instproxy_client_t clie | |||
| 367 | data->operation = strdup(operation); | 372 | data->operation = strdup(operation); |
| 368 | data->user_data = user_data; | 373 | data->user_data = user_data; |
| 369 | 374 | ||
| 370 | if (thread_create(&client->status_updater, instproxy_status_updater, data) == 0) { | 375 | if (thread_new(&client->status_updater, instproxy_status_updater, data) == 0) { |
| 371 | res = INSTPROXY_E_SUCCESS; | 376 | res = INSTPROXY_E_SUCCESS; |
| 372 | } | 377 | } |
| 373 | } | 378 | } |
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) | |||
| 131 | if (client->notifier) { | 131 | if (client->notifier) { |
| 132 | debug_info("joining np callback"); | 132 | debug_info("joining np callback"); |
| 133 | thread_join(client->notifier); | 133 | thread_join(client->notifier); |
| 134 | thread_free(client->notifier); | ||
| 135 | client->notifier = (thread_t)NULL; | ||
| 134 | } else { | 136 | } else { |
| 135 | dict = NULL; | 137 | dict = NULL; |
| 136 | property_list_service_receive_plist(parent, &dict); | 138 | 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 | |||
| 347 | property_list_service_client_t parent = client->parent; | 349 | property_list_service_client_t parent = client->parent; |
| 348 | client->parent = NULL; | 350 | client->parent = NULL; |
| 349 | thread_join(client->notifier); | 351 | thread_join(client->notifier); |
| 352 | thread_free(client->notifier); | ||
| 350 | client->notifier = (thread_t)NULL; | 353 | client->notifier = (thread_t)NULL; |
| 351 | client->parent = parent; | 354 | client->parent = parent; |
| 352 | } | 355 | } |
| @@ -358,7 +361,7 @@ LIBIMOBILEDEVICE_API np_error_t np_set_notify_callback( np_client_t client, np_n | |||
| 358 | npt->cbfunc = notify_cb; | 361 | npt->cbfunc = notify_cb; |
| 359 | npt->user_data = user_data; | 362 | npt->user_data = user_data; |
| 360 | 363 | ||
| 361 | if (thread_create(&client->notifier, np_notifier, npt) == 0) { | 364 | if (thread_new(&client->notifier, np_notifier, npt) == 0) { |
| 362 | res = NP_E_SUCCESS; | 365 | res = NP_E_SUCCESS; |
| 363 | } | 366 | } |
| 364 | } | 367 | } |
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_ | |||
| 106 | if (client->worker) { | 106 | if (client->worker) { |
| 107 | debug_info("Joining syslog capture callback worker thread"); | 107 | debug_info("Joining syslog capture callback worker thread"); |
| 108 | thread_join(client->worker); | 108 | thread_join(client->worker); |
| 109 | thread_free(client->worker); | ||
| 110 | client->worker = (thread_t)NULL; | ||
| 109 | } | 111 | } |
| 110 | free(client); | 112 | free(client); |
| 111 | 113 | ||
| @@ -190,7 +192,7 @@ LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_start_capture(syslog_rela | |||
| 190 | srwt->cbfunc = callback; | 192 | srwt->cbfunc = callback; |
| 191 | srwt->user_data = user_data; | 193 | srwt->user_data = user_data; |
| 192 | 194 | ||
| 193 | if (thread_create(&client->worker, syslog_relay_worker, srwt) == 0) { | 195 | if (thread_new(&client->worker, syslog_relay_worker, srwt) == 0) { |
| 194 | res = SYSLOG_RELAY_E_SUCCESS; | 196 | res = SYSLOG_RELAY_E_SUCCESS; |
| 195 | } | 197 | } |
| 196 | } | 198 | } |
| @@ -206,6 +208,7 @@ LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_stop_capture(syslog_relay | |||
| 206 | client->parent = NULL; | 208 | client->parent = NULL; |
| 207 | /* join thread to make it exit */ | 209 | /* join thread to make it exit */ |
| 208 | thread_join(client->worker); | 210 | thread_join(client->worker); |
| 211 | thread_free(client->worker); | ||
| 209 | client->worker = (thread_t)NULL; | 212 | client->worker = (thread_t)NULL; |
| 210 | client->parent = parent; | 213 | client->parent = parent; |
| 211 | } | 214 | } |
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) | |||
| 139 | 139 | ||
| 140 | /* spawn server to client thread */ | 140 | /* spawn server to client thread */ |
| 141 | socket_info->stop_dtoc = 0; | 141 | socket_info->stop_dtoc = 0; |
| 142 | if (thread_create(&dtoc, thread_device_to_client, data) != 0) { | 142 | if (thread_new(&dtoc, thread_device_to_client, data) != 0) { |
| 143 | fprintf(stderr, "Failed to start device to client thread...\n"); | 143 | fprintf(stderr, "Failed to start device to client thread...\n"); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| @@ -187,6 +187,7 @@ static void *thread_client_to_device(void *data) | |||
| 187 | 187 | ||
| 188 | /* join other thread to allow it to stop */ | 188 | /* join other thread to allow it to stop */ |
| 189 | thread_join(dtoc); | 189 | thread_join(dtoc); |
| 190 | thread_free(dtoc); | ||
| 190 | 191 | ||
| 191 | return NULL; | 192 | return NULL; |
| 192 | } | 193 | } |
| @@ -200,12 +201,13 @@ static void* connection_handler(void* data) | |||
| 200 | 201 | ||
| 201 | /* spawn client to device thread */ | 202 | /* spawn client to device thread */ |
| 202 | socket_info->stop_ctod = 0; | 203 | socket_info->stop_ctod = 0; |
| 203 | if (thread_create(&ctod, thread_client_to_device, data) != 0) { | 204 | if (thread_new(&ctod, thread_client_to_device, data) != 0) { |
| 204 | fprintf(stderr, "Failed to start client to device thread...\n"); | 205 | fprintf(stderr, "Failed to start client to device thread...\n"); |
| 205 | } | 206 | } |
| 206 | 207 | ||
| 207 | /* join the fun */ | 208 | /* join the fun */ |
| 208 | thread_join(ctod); | 209 | thread_join(ctod); |
| 210 | thread_free(ctod); | ||
| 209 | 211 | ||
| 210 | /* shutdown client socket */ | 212 | /* shutdown client socket */ |
| 211 | socket_shutdown(socket_info->client_fd, SHUT_RDWR); | 213 | socket_shutdown(socket_info->client_fd, SHUT_RDWR); |
| @@ -348,11 +350,15 @@ int main(int argc, char *argv[]) | |||
| 348 | 350 | ||
| 349 | debug("%s: Handling new client connection...\n", __func__); | 351 | debug("%s: Handling new client connection...\n", __func__); |
| 350 | 352 | ||
| 351 | if (thread_create(&th, connection_handler, (void*)&socket_info) != 0) { | 353 | if (thread_new(&th, connection_handler, (void*)&socket_info) != 0) { |
| 352 | fprintf(stderr, "Could not start connection handler.\n"); | 354 | fprintf(stderr, "Could not start connection handler.\n"); |
| 353 | socket_shutdown(socket_info.server_fd, SHUT_RDWR); | 355 | socket_shutdown(socket_info.server_fd, SHUT_RDWR); |
| 354 | socket_close(socket_info.server_fd); | 356 | socket_close(socket_info.server_fd); |
| 357 | continue; | ||
| 355 | } | 358 | } |
| 359 | |||
| 360 | /* we do not need it anymore */ | ||
| 361 | thread_free(th); | ||
| 356 | } | 362 | } |
| 357 | 363 | ||
| 358 | debug("%s: Shutting down debugserver proxy...\n", __func__); | 364 | debug("%s: Shutting down debugserver proxy...\n", __func__); |
