diff options
| -rw-r--r-- | src/libirecovery.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c index 84f0b32..39f6f88 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c | |||
| @@ -2127,11 +2127,22 @@ static int _irecv_usb_hotplug_cb(libusb_context *ctx, libusb_device *device, lib | |||
| 2127 | #endif /* !HAVE_IOKIT */ | 2127 | #endif /* !HAVE_IOKIT */ |
| 2128 | #endif /* !WIN32 */ | 2128 | #endif /* !WIN32 */ |
| 2129 | 2129 | ||
| 2130 | static void *_irecv_event_handler(void* unused) | 2130 | struct _irecv_event_handler_info { |
| 2131 | cond_t startup_cond; | ||
| 2132 | mutex_t startup_mutex; | ||
| 2133 | }; | ||
| 2134 | |||
| 2135 | static void *_irecv_event_handler(void* data) | ||
| 2131 | { | 2136 | { |
| 2137 | struct _irecv_event_handler_info* info = (struct _irecv_event_handler_info*)data; | ||
| 2132 | #ifdef WIN32 | 2138 | #ifdef WIN32 |
| 2133 | const GUID *guids[] = { &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL }; | 2139 | const GUID *guids[] = { &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL }; |
| 2134 | int running = 1; | 2140 | int running = 1; |
| 2141 | |||
| 2142 | mutex_lock(&(info->startup_mutex)); | ||
| 2143 | cond_signal(&(info->startup_cond)); | ||
| 2144 | mutex_unlock(&(info->startup_mutex)); | ||
| 2145 | |||
| 2135 | do { | 2146 | do { |
| 2136 | SP_DEVICE_INTERFACE_DATA currentInterface; | 2147 | SP_DEVICE_INTERFACE_DATA currentInterface; |
| 2137 | HDEVINFO usbDevices; | 2148 | HDEVINFO usbDevices; |
| @@ -2246,6 +2257,10 @@ static void *_irecv_event_handler(void* unused) | |||
| 2246 | i++; | 2257 | i++; |
| 2247 | } | 2258 | } |
| 2248 | 2259 | ||
| 2260 | mutex_lock(&(info->startup_mutex)); | ||
| 2261 | cond_signal(&(info->startup_cond)); | ||
| 2262 | mutex_unlock(&(info->startup_mutex)); | ||
| 2263 | |||
| 2249 | CFRunLoopRun(); | 2264 | CFRunLoopRun(); |
| 2250 | 2265 | ||
| 2251 | #else /* !HAVE_IOKIT */ | 2266 | #else /* !HAVE_IOKIT */ |
| @@ -2253,6 +2268,11 @@ static void *_irecv_event_handler(void* unused) | |||
| 2253 | static libusb_hotplug_callback_handle usb_hotplug_cb_handle; | 2268 | static libusb_hotplug_callback_handle usb_hotplug_cb_handle; |
| 2254 | libusb_hotplug_register_callback(irecv_hotplug_ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, APPLE_VENDOR_ID, LIBUSB_HOTPLUG_MATCH_ANY, 0, _irecv_usb_hotplug_cb, NULL, &usb_hotplug_cb_handle); | 2269 | libusb_hotplug_register_callback(irecv_hotplug_ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, APPLE_VENDOR_ID, LIBUSB_HOTPLUG_MATCH_ANY, 0, _irecv_usb_hotplug_cb, NULL, &usb_hotplug_cb_handle); |
| 2255 | int running = 1; | 2270 | int running = 1; |
| 2271 | |||
| 2272 | mutex_lock(&(info->startup_mutex)); | ||
| 2273 | cond_signal(&(info->startup_cond)); | ||
| 2274 | mutex_unlock(&(info->startup_mutex)); | ||
| 2275 | |||
| 2256 | do { | 2276 | do { |
| 2257 | struct timeval tv; | 2277 | struct timeval tv; |
| 2258 | tv.tv_sec = tv.tv_usec = 0; | 2278 | tv.tv_sec = tv.tv_usec = 0; |
| @@ -2272,6 +2292,10 @@ static void *_irecv_event_handler(void* unused) | |||
| 2272 | libusb_device **devs; | 2292 | libusb_device **devs; |
| 2273 | int running = 1; | 2293 | int running = 1; |
| 2274 | 2294 | ||
| 2295 | mutex_lock(&(info->startup_mutex)); | ||
| 2296 | cond_signal(&(info->startup_cond)); | ||
| 2297 | mutex_unlock(&(info->startup_mutex)); | ||
| 2298 | |||
| 2275 | do { | 2299 | do { |
| 2276 | cnt = libusb_get_device_list(irecv_hotplug_ctx, &devs); | 2300 | cnt = libusb_get_device_list(irecv_hotplug_ctx, &devs); |
| 2277 | if (cnt < 0) { | 2301 | if (cnt < 0) { |
| @@ -2349,6 +2373,9 @@ IRECV_API irecv_error_t irecv_device_event_subscribe(irecv_device_event_context_ | |||
| 2349 | mutex_unlock(&listener_mutex); | 2373 | mutex_unlock(&listener_mutex); |
| 2350 | 2374 | ||
| 2351 | if (th_event_handler == THREAD_T_NULL || !thread_alive(th_event_handler)) { | 2375 | if (th_event_handler == THREAD_T_NULL || !thread_alive(th_event_handler)) { |
| 2376 | struct _irecv_event_handler_info info; | ||
| 2377 | cond_init(&info.startup_cond); | ||
| 2378 | mutex_init(&info.startup_mutex); | ||
| 2352 | #ifndef WIN32 | 2379 | #ifndef WIN32 |
| 2353 | #ifndef HAVE_IOKIT | 2380 | #ifndef HAVE_IOKIT |
| 2354 | libusb_init(&irecv_hotplug_ctx); | 2381 | libusb_init(&irecv_hotplug_ctx); |
| @@ -2356,7 +2383,13 @@ IRECV_API irecv_error_t irecv_device_event_subscribe(irecv_device_event_context_ | |||
| 2356 | #endif | 2383 | #endif |
| 2357 | collection_init(&devices); | 2384 | collection_init(&devices); |
| 2358 | mutex_init(&device_mutex); | 2385 | mutex_init(&device_mutex); |
| 2359 | thread_new(&th_event_handler, _irecv_event_handler, NULL); | 2386 | mutex_lock(&info.startup_mutex); |
| 2387 | if (thread_new(&th_event_handler, _irecv_event_handler, &info) == 0) { | ||
| 2388 | cond_wait(&info.startup_cond, &info.startup_mutex); | ||
| 2389 | } | ||
| 2390 | mutex_unlock(&info.startup_mutex); | ||
| 2391 | cond_destroy(&info.startup_cond); | ||
| 2392 | mutex_destroy(&info.startup_mutex); | ||
| 2360 | } | 2393 | } |
| 2361 | 2394 | ||
| 2362 | *context = _context; | 2395 | *context = _context; |
| @@ -2378,10 +2411,11 @@ IRECV_API irecv_error_t irecv_device_event_unsubscribe(irecv_device_event_contex | |||
| 2378 | int num = collection_count(&listeners); | 2411 | int num = collection_count(&listeners); |
| 2379 | mutex_unlock(&listener_mutex); | 2412 | mutex_unlock(&listener_mutex); |
| 2380 | 2413 | ||
| 2381 | if (num == 0) { | 2414 | if (num == 0 && th_event_handler != THREAD_T_NULL && thread_alive(th_event_handler)) { |
| 2382 | #ifdef HAVE_IOKIT | 2415 | #ifdef HAVE_IOKIT |
| 2383 | if (iokit_runloop) { | 2416 | if (iokit_runloop) { |
| 2384 | CFRunLoopStop(iokit_runloop); | 2417 | CFRunLoopStop(iokit_runloop); |
| 2418 | iokit_runloop = NULL; | ||
| 2385 | } | 2419 | } |
| 2386 | #endif | 2420 | #endif |
| 2387 | thread_join(th_event_handler); | 2421 | thread_join(th_event_handler); |
