thread: Introduce thread_new and thread_free to cover handle leaks on WIN32
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 @@
 #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 @@
 	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 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 @@
 	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 @@
 	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 @@
  * @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 @@
 	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 @@
 			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 @@
 	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 @@
 		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 @@
 			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 @@
 	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 @@
 		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 @@
 		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 @@
 
 	/* 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 @@
 
 	/* join other thread to allow it to stop */
 	thread_join(dtoc);
+	thread_free(dtoc);
 
 	return NULL;
 }
@@ -200,12 +201,13 @@
 
 	/* 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 @@
 
 		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__);