From c5aec6bd678cddfab87df35de2c133f51bc8cce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20G=C3=BCrtler?= Date: Mon, 3 Apr 2023 16:00:37 +0200 Subject: Fix #1263 by acquiring the waiters lock while calling transfer callbacks and swapping the order of operations in sync_transfer_cb Fixes #1267, #1263 Signed-off-by: Nathan Hjelm --- libusb/io.c | 5 ++++- libusb/sync.c | 9 +++++++-- libusb/version_nano.h | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libusb/io.c b/libusb/io.c index 7c20a7e..36e0b81 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1719,8 +1719,11 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, transfer->actual_length = itransfer->transferred; usbi_dbg(ctx, "transfer %p has callback %p", (void *) transfer, transfer->callback); - if (transfer->callback) + if (transfer->callback) { + libusb_lock_event_waiters (ctx); transfer->callback(transfer); + libusb_unlock_event_waiters(ctx); + } /* transfer might have been freed by the above call, do not use from * this point. */ if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) diff --git a/libusb/sync.c b/libusb/sync.c index 27b5951..146cce2 100644 --- a/libusb/sync.c +++ b/libusb/sync.c @@ -34,10 +34,15 @@ static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer) { + usbi_dbg(TRANSFER_CTX(transfer), "actual_length=%d", transfer->actual_length); + int *completed = transfer->user_data; *completed = 1; - usbi_dbg(TRANSFER_CTX(transfer), "actual_length=%d", transfer->actual_length); - /* caller interprets result and frees transfer */ + /* + * Right after setting 'completed', another thread might free the transfer, so don't + * access it beyond this point. The instantiating thread (not necessarily the + * current one) interprets the result and frees the transfer. + */ } static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer) diff --git a/libusb/version_nano.h b/libusb/version_nano.h index cb1eb95..ea168c3 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11792 +#define LIBUSB_NANO 11793 -- cgit v1.2.1