summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Christophe Fergeau2014-12-11 09:20:20 +0100
committerGravatar Martin Szulecki2015-01-12 15:51:09 +0100
commit1d9e6e351b51e7401898dde96418c0ee10ad878f (patch)
tree3e7aebd142e5f8341d20494a07c4e8333f778599
parentae637ea04cd63cb98587f9bb290b93c3a476d32b (diff)
downloadlibimobiledevice-1d9e6e351b51e7401898dde96418c0ee10ad878f.tar.gz
libimobiledevice-1d9e6e351b51e7401898dde96418c0ee10ad878f.tar.bz2
Fix overlong blocking in np_client_free()
When using ideviceinstaller, np_client_free() would block for several minutes when ideviceinstaller cleans up after installing the application. This happens because the function is blocking on thread_join(), waiting for the notification watcher thread to finish. It only ends when np_get_notification() returns a negative value after getting a timeout, which takes several minutes. However, the thread loop will also exit early if client->parent gets NULL (the loop is iterated every 500ms), so this commit ensures client->parent gets set to NULL early in np_client_free() so that thread_join() does not block for a long time. Signed-off-by: Martin Szulecki <m.szulecki@libimobiledevice.org>
-rw-r--r--src/notification_proxy.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/notification_proxy.c b/src/notification_proxy.c
index dba42db..4b028f6 100644
--- a/src/notification_proxy.c
+++ b/src/notification_proxy.c
@@ -114,6 +114,7 @@ LIBIMOBILEDEVICE_API np_error_t np_client_start_service(idevice_t device, np_cli
LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client)
{
plist_t dict;
+ property_list_service_client_t parent;
if (!client)
return NP_E_INVALID_ARG;
@@ -123,12 +124,16 @@ LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client)
property_list_service_send_xml_plist(client->parent, dict);
plist_free(dict);
+ parent = client->parent;
+ /* notifies the client->notifier thread that it should terminate */
+ client->parent = NULL;
+
if (client->notifier) {
debug_info("joining np callback");
thread_join(client->notifier);
} else {
dict = NULL;
- property_list_service_receive_plist(client->parent, &dict);
+ property_list_service_receive_plist(parent, &dict);
if (dict) {
#ifndef STRIP_DEBUG_CODE
char *cmd_value = NULL;
@@ -150,8 +155,7 @@ LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client)
}
}
- property_list_service_client_free(client->parent);
- client->parent = NULL;
+ property_list_service_client_free(parent);
mutex_destroy(&client->mutex);
free(client);