event_handles supposed just run at a thread.
There are re-entry check at begin.
1: if (usbi_handling_events(ctx))
2: return LIBUSB_ERROR_BUSY;
3: usbi_stat_event_handle(ctx);
this code is hold any lock
it is possible two thread check 1 at the same time, then
go through to 3. So two threads will run event_handles.
above 3 line code should hold event_data_lock to avoid above
race condition.
1: usbi_mutex_lock($ctx->event_data_lock);
2: r = 0;
3: if (usbi_handling_events(ctx))
4: r = LIBUSB_ERROR_BUSY;
5: else
6: usbi_start_event_handling(ctx);
7: usbi_mutex_unlock($ctx->event_data_lock);
8: if(r)
9: return r;
check and set in an atomic operations.
Closes #520
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Nathan Hjelm <hjelmn@me.com>
/* prevent attempts to recursively handle events (e.g. calling into
* libusb_handle_events() from within a hotplug or transfer callback) */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ r = 0;
if (usbi_handling_events(ctx))
- return LIBUSB_ERROR_BUSY;
- usbi_start_event_handling(ctx);
+ r = LIBUSB_ERROR_BUSY;
+ else
+ usbi_start_event_handling(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ if (r)
+ return r;
/* there are certain fds that libusb uses internally, currently:
*
-#define LIBUSB_NANO 11342
+#define LIBUSB_NANO 11343