When multiple threads are involved receiving completion events in LibUSB

make sure there is always a master polling thread, by setting the "ctx_handler"
field in the context. Else the reception of completion events can stop.
This happens if event threads are created and destroyed during runtime.

Found by:		Ludovic Rousseau <ludovic.rousseau+freebsd@gmail.com>
PR:			231742
MFC after:		1 week
Approved by:		re (kib)
Sponsored by:		Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2018-09-28 10:28:22 +00:00
parent d0addc700e
commit 2682992483

View File

@ -312,6 +312,9 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
if (tv == NULL) { if (tv == NULL) {
pthread_cond_wait(&ctx->ctx_cond, pthread_cond_wait(&ctx->ctx_cond,
&ctx->ctx_lock); &ctx->ctx_lock);
/* try to grab polling of actual events, if any */
if (ctx->ctx_handler == NO_THREAD)
ctx->ctx_handler = pthread_self();
return (0); return (0);
} }
err = clock_gettime(CLOCK_MONOTONIC, &ts); err = clock_gettime(CLOCK_MONOTONIC, &ts);
@ -330,6 +333,9 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
} }
err = pthread_cond_timedwait(&ctx->ctx_cond, err = pthread_cond_timedwait(&ctx->ctx_cond,
&ctx->ctx_lock, &ts); &ctx->ctx_lock, &ts);
/* try to grab polling of actual events, if any */
if (ctx->ctx_handler == NO_THREAD)
ctx->ctx_handler = pthread_self();
if (err == ETIMEDOUT) if (err == ETIMEDOUT)
return (1); return (1);