diff options
| author | 2013-12-27 01:55:08 +0100 | |
|---|---|---|
| committer | 2013-12-27 01:55:08 +0100 | |
| commit | 82e5f5764422393eff28aaa8ed35b3ea3db74490 (patch) | |
| tree | 0f2aafe75e8233e522af5dc58d6e2d498e4bf501 /src | |
| parent | eb9415e18fda0bf394afe8439319a69bbcb196f4 (diff) | |
| download | usbmuxd-82e5f5764422393eff28aaa8ed35b3ea3db74490.tar.gz usbmuxd-82e5f5764422393eff28aaa8ed35b3ea3db74490.tar.bz2 | |
preflight: replace idevice_event_* with thread safe implementation
idevice_event_subscribe() calls usbmuxd_subscribe() which will
start a thread waiting for device add/remove events. But this
implementation is not able to handle more than one "subscription".
However the preflight worker will start a thread for _each_ device
resulting in a really messed up situation if more than one device
is attached at the same time. This fix will use usbmuxd's internal
device_remove function calling a preflight callback to make this
implementation thread safe.
Diffstat (limited to 'src')
| -rw-r--r-- | src/device.c | 17 | ||||
| -rw-r--r-- | src/device.h | 1 | ||||
| -rw-r--r-- | src/preflight.c | 24 | ||||
| -rw-r--r-- | src/preflight.h | 1 |
4 files changed, 31 insertions, 12 deletions
diff --git a/src/device.c b/src/device.c index b6cc32a..1e3cc83 100644 --- a/src/device.c +++ b/src/device.c | |||
| @@ -112,6 +112,7 @@ struct mux_device | |||
| 112 | uint16_t next_sport; | 112 | uint16_t next_sport; |
| 113 | unsigned char *pktbuf; | 113 | unsigned char *pktbuf; |
| 114 | uint32_t pktlen; | 114 | uint32_t pktlen; |
| 115 | void *preflight_cb_data; | ||
| 115 | }; | 116 | }; |
| 116 | 117 | ||
| 117 | static struct collection device_list; | 118 | static struct collection device_list; |
| @@ -648,6 +649,7 @@ int device_add(struct usb_device *usbdev) | |||
| 648 | dev->next_sport = 1; | 649 | dev->next_sport = 1; |
| 649 | dev->pktbuf = malloc(DEV_MRU); | 650 | dev->pktbuf = malloc(DEV_MRU); |
| 650 | dev->pktlen = 0; | 651 | dev->pktlen = 0; |
| 652 | dev->preflight_cb_data = NULL; | ||
| 651 | struct version_header vh; | 653 | struct version_header vh; |
| 652 | vh.major = htonl(1); | 654 | vh.major = htonl(1); |
| 653 | vh.minor = htonl(0); | 655 | vh.minor = htonl(0); |
| @@ -674,6 +676,9 @@ void device_remove(struct usb_device *usbdev) | |||
| 674 | client_device_remove(dev->id); | 676 | client_device_remove(dev->id); |
| 675 | collection_free(&dev->connections); | 677 | collection_free(&dev->connections); |
| 676 | } | 678 | } |
| 679 | if (dev->preflight_cb_data) { | ||
| 680 | preflight_device_remove_cb(dev->preflight_cb_data); | ||
| 681 | } | ||
| 677 | collection_remove(&device_list, dev); | 682 | collection_remove(&device_list, dev); |
| 678 | free(dev->pktbuf); | 683 | free(dev->pktbuf); |
| 679 | free(dev); | 684 | free(dev); |
| @@ -690,7 +695,17 @@ void device_set_visible(int device_id) | |||
| 690 | dev->visible = 1; | 695 | dev->visible = 1; |
| 691 | break; | 696 | break; |
| 692 | } | 697 | } |
| 693 | } ENDFOREACH | 698 | } ENDFOREACH |
| 699 | } | ||
| 700 | |||
| 701 | void device_set_preflight_cb_data(int device_id, void* data) | ||
| 702 | { | ||
| 703 | FOREACH(struct mux_device *dev, &device_list) { | ||
| 704 | if(dev->id == device_id) { | ||
| 705 | dev->preflight_cb_data = data; | ||
| 706 | break; | ||
| 707 | } | ||
| 708 | } ENDFOREACH | ||
| 694 | } | 709 | } |
| 695 | 710 | ||
| 696 | int device_get_count(int include_hidden) | 711 | int device_get_count(int include_hidden) |
diff --git a/src/device.h b/src/device.h index d7c82ca..95d470e 100644 --- a/src/device.h +++ b/src/device.h | |||
| @@ -41,6 +41,7 @@ void device_client_process(int device_id, struct mux_client *client, short event | |||
| 41 | void device_abort_connect(int device_id, struct mux_client *client); | 41 | void device_abort_connect(int device_id, struct mux_client *client); |
| 42 | 42 | ||
| 43 | void device_set_visible(int device_id); | 43 | void device_set_visible(int device_id); |
| 44 | void device_set_preflight_cb_data(int device_id, void* data); | ||
| 44 | 45 | ||
| 45 | int device_get_count(int include_hidden); | 46 | int device_get_count(int include_hidden); |
| 46 | int device_get_list(int include_hidden, struct device_info *p); | 47 | int device_get_list(int include_hidden, struct device_info *p); |
diff --git a/src/preflight.c b/src/preflight.c index 283c6d9..b011344 100644 --- a/src/preflight.c +++ b/src/preflight.c | |||
| @@ -30,11 +30,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 30 | 30 | ||
| 31 | #include <sys/time.h> | 31 | #include <sys/time.h> |
| 32 | 32 | ||
| 33 | #ifdef HAVE_LIBIMOBILEDEVICE | ||
| 33 | #include <libimobiledevice/libimobiledevice.h> | 34 | #include <libimobiledevice/libimobiledevice.h> |
| 34 | #include <libimobiledevice/lockdown.h> | 35 | #include <libimobiledevice/lockdown.h> |
| 35 | #include <libimobiledevice/notification_proxy.h> | 36 | #include <libimobiledevice/notification_proxy.h> |
| 37 | #endif | ||
| 36 | 38 | ||
| 37 | #include "preflight.h" | 39 | #include "preflight.h" |
| 40 | #include "device.h" | ||
| 38 | #include "client.h" | 41 | #include "client.h" |
| 39 | #include "conf.h" | 42 | #include "conf.h" |
| 40 | #include "log.h" | 43 | #include "log.h" |
| @@ -65,15 +68,12 @@ static void lockdownd_set_untrusted_host_buid(lockdownd_client_t lockdown) | |||
| 65 | free(system_buid); | 68 | free(system_buid); |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | static void idevice_callback(const idevice_event_t* event, void* userdata) | 71 | void preflight_device_remove_cb(void *data) |
| 69 | { | 72 | { |
| 70 | struct cb_data *cbdata = (struct cb_data*)userdata; | 73 | if (!data) |
| 71 | idevice_t dev = cbdata->dev; | 74 | return; |
| 72 | struct idevice_private *_dev = (struct idevice_private*)dev; | 75 | struct cb_data *cbdata = (struct cb_data*)data; |
| 73 | 76 | cbdata->is_device_connected = 0; | |
| 74 | if (event->event == IDEVICE_DEVICE_REMOVE && !strcmp(_dev->udid, event->udid)) { | ||
| 75 | cbdata->is_device_connected = 0; | ||
| 76 | } | ||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static void np_callback(const char* notification, void* userdata) | 79 | static void np_callback(const char* notification, void* userdata) |
| @@ -246,7 +246,7 @@ retry: | |||
| 246 | cbdata.is_device_connected = 1; | 246 | cbdata.is_device_connected = 1; |
| 247 | 247 | ||
| 248 | np_set_notify_callback(np, np_callback, (void*)&cbdata); | 248 | np_set_notify_callback(np, np_callback, (void*)&cbdata); |
| 249 | idevice_event_subscribe(idevice_callback, (void*)&cbdata); | 249 | device_set_preflight_cb_data(info->id, (void*)&cbdata); |
| 250 | 250 | ||
| 251 | const char* spec[] = { | 251 | const char* spec[] = { |
| 252 | "com.apple.mobile.lockdown.request_pair", | 252 | "com.apple.mobile.lockdown.request_pair", |
| @@ -267,8 +267,6 @@ retry: | |||
| 267 | } | 267 | } |
| 268 | usbmuxd_log(LL_INFO, "%s: Finished waiting for notification from device %s, is_device_connected %d", __func__, _dev->udid, cbdata.is_device_connected); | 268 | usbmuxd_log(LL_INFO, "%s: Finished waiting for notification from device %s, is_device_connected %d", __func__, _dev->udid, cbdata.is_device_connected); |
| 269 | 269 | ||
| 270 | idevice_event_unsubscribe(); | ||
| 271 | |||
| 272 | if (cbdata.np) { | 270 | if (cbdata.np) { |
| 273 | np_client_free(cbdata.np); | 271 | np_client_free(cbdata.np); |
| 274 | } | 272 | } |
| @@ -326,6 +324,10 @@ leave: | |||
| 326 | 324 | ||
| 327 | return NULL; | 325 | return NULL; |
| 328 | } | 326 | } |
| 327 | #else | ||
| 328 | void preflight_device_remove_cb(void *data) | ||
| 329 | { | ||
| 330 | } | ||
| 329 | #endif | 331 | #endif |
| 330 | 332 | ||
| 331 | void preflight_worker_device_add(struct device_info* info) | 333 | void preflight_worker_device_add(struct device_info* info) |
diff --git a/src/preflight.h b/src/preflight.h index 62349d1..4c8aa60 100644 --- a/src/preflight.h +++ b/src/preflight.h | |||
| @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 26 | extern void userpref_get_system_buid(char **systembuid); | 26 | extern void userpref_get_system_buid(char **systembuid); |
| 27 | extern void userpref_device_record_get_host_id(const char *udid, char **host_id); | 27 | extern void userpref_device_record_get_host_id(const char *udid, char **host_id); |
| 28 | 28 | ||
| 29 | void preflight_device_remove_cb(void *data); | ||
| 29 | void preflight_worker_device_add(struct device_info* info); | 30 | void preflight_worker_device_add(struct device_info* info); |
| 30 | 31 | ||
| 31 | #endif | 32 | #endif |
