Ticket #103 (closed defect: duplicate)

Opened 2 years ago

Last modified 2 years ago

libusb_control_transfer sometimes hangs for 60 seconds

Reported by: rickyepoderi Owned by:
Milestone: Component: libusb-1.0
Keywords: Cc:
Blocked By: Blocks:

Description

Hi all,

My issue could be similar to #69 but in this bug nothing is explained so I have decided to open a new one. After an upgrade of the ccid library my smart-card began to work incredibly slow, after some testing I have just realized that your libusb is the guilty one (it seems ccid is using libusb since 1.4.x versions).

Inside the libusb_control_transfer the following code is executed:

        libusb_fill_control_transfer(transfer, dev_handle, buffer,
                ctrl_transfer_cb, &completed, timeout);
        transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
        r = libusb_submit_transfer(transfer);
        if (r < 0) {
                libusb_free_transfer(transfer);
                return r;
        }

        while (!completed) {
                r = libusb_handle_events(HANDLE_CTX(dev_handle));

If you see when the transfer is submitted the complete variable is immediately checked and, if it is not completed, libusb_handle_events is called which waits 60 seconds. I suppose that generally this is not a problem but with my card completed is false sometimes and 60 seconds is a lot of time (it is absolutely useless).

I successfully patched the function with the following patch:

--- sync.c.ORIG	2011-03-19 00:00:49.776084642 +0100
+++ sync.c	2011-03-19 00:00:53.587794164 +0100
@@ -171,8 +171,12 @@
 		return r;
 	}
 
+        struct timeval tv;
+        tv.tv_sec = 1;
+        tv.tv_usec = 0;
 	while (!completed) {
-		r = libusb_handle_events(HANDLE_CTX(dev_handle));
+                r = libusb_handle_events_timeout(HANDLE_CTX(dev_handle), &tv);
+                tv.tv_usec = tv.tv_usec * 2;
 		if (r < 0) {
 			if (r == LIBUSB_ERROR_INTERRUPTED)
 				continue;

My solution is very straight forward, the waiting is 1 second the first time, 2 seconds the second time, 4 the third and so on. It is just a simple solution.

I have also noticed the function libusb_control_transfer does exactly the same.

Cheerio!

Change History

comment:1 Changed 2 years ago by ludovicrousseau

This is not new. I already reported the problem by mail in June last year http://libusb.6.n5.nabble.com/sync-API-is-not-thread-safe-td511637.html

I opened bug #56 "[PATCH] Fix a race condition in io.c libusb_handle_events_timeout()". With a patch included.

The other patch 0002-Handle-early-complete-of-multi-URB-transfer-on-Linux.patch may be already included in GIT http://git.libusb.org/?p=libusb.git;a=commit;h=3b6d9ac82e2599cad7817d21e909a42275ddc4c4;js=1

Bug #56 is still open. So it may not be fixed in version 1.0.9 and may have to wait for version 1.0.10 planned for year 2019 or something like that.

comment:2 Changed 2 years ago by rickyepoderi

Whoa! Thank you Ludovic. Sorry but I didn't see #56 was my issue, as soon as I saw the 60 seconds value I stopped looking at the code. I just want to point out that this happens to me in any application which uses opensc-pkcs11 library (firefox, thunderbird or whatever) making them absolutely useless (I had to start opensc in debug mode to see it wasn't completely hanged).

Than you again. Please close the issue as duplicated.

comment:3 Changed 2 years ago by stuge

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #56. See there for further comments.

Note: See TracTickets for help on using tickets.