summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2014-12-26 12:23:52 +0100
committerGravatar Martin Szulecki2015-01-13 00:14:55 +0100
commitf3c4db4f30731f6cfc2c37a39d5ce3501d42f45e (patch)
treecaa0ffcfdd84a31c945408e9e7ccd56b72318e2e
parentaa14c053bc909c56d31c12799f13013f845ddb71 (diff)
downloadlibimobiledevice-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.c15
-rw-r--r--common/thread.h3
-rw-r--r--dev/afccheck.c3
-rw-r--r--src/installation_proxy.c11
-rw-r--r--src/notification_proxy.c5
-rw-r--r--src/syslog_relay.c5
-rw-r--r--tools/idevicedebugserverproxy.c12
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
24int thread_create(thread_t *thread, thread_func_t thread_func, void* data) 24int 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
39void thread_free(thread_t thread)
40{
41#ifdef WIN32
42 CloseHandle(thread);
43#endif
44}
45
39void thread_join(thread_t thread) 46void 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
44typedef void* (*thread_func_t)(void* data); 44typedef void* (*thread_func_t)(void* data);
45 45
46int thread_create(thread_t* thread, thread_func_t thread_func, void* data); 46int thread_new(thread_t* thread, thread_func_t thread_func, void* data);
47void thread_free(thread_t thread);
47void thread_join(thread_t thread); 48void thread_join(thread_t thread);
48 49
49void mutex_init(mutex_t* mutex); 50void 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 */
322static void* instproxy_status_updater(void* arg) 324static 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__);