-
Notifications
You must be signed in to change notification settings - Fork 769
Handling race condition for pending_transfers_ and its iterators. #212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Bisection confirms a886bb0 is the commit that breaks the current libfreenect2. Your patch did not fix the problem in my testing. I did not get any "failed to submit transfer" error, but the errors were a lot of ISO transfers being lost and depth packets being incomplete. I also found One minor issue, your patch uses std::mutex and will fail to build if the user does not enable C++11. |
Hi @xlz The runtime error I get is that the iterator is invalid - nothing to do about failed to submit transfers :) You might be right that its the same thread that executes onTransferCompleteStatic, but its the main thread that adds and removes transfers at startup and on close. But as soon as one transfer is submitted, libusb spawns a thread and that one will eventually be using a iterator on the collections, while the main thread is adding or removing transfers too. This will make the iterator invalid. Instead of using std::mutex I guess we can use a mutex from tinythread or another synchronization way. |
Then my error from a886bb0 is different from yours. I did not get any invalid iterator errors.
What I did was printing the thread id at the position where you put the locks. Apparently |
I just figured that I can only get the error to happened when I run it in debug mode - probably because all the transfers get submitted before the first transfer is complete in release mode. Did you try in debug mode? |
Agreed. What you found is true even before a886bb0. With the current libusbx-winiso, and with this line removed in
I got "deque iterator not incrementable" error using Debug build, and hang-up using Release build when exiting Protonect. The problem is exactly during initialization and deinitialization. Either you have to put locks everywhere, or have to consider reimplementing the transfer pool. |
It seems on Windows a886bb0 improves performance, but on Linux a886bb0 really breaks the original transfer_pool.cpp. Can you try https://github.com/xlz/libfreenect2/commit/c6f6e57df3671285812e5ae3ac9ceedd49258d42 from my transfer-pool branch? (This commit did not fix the problem on Linux.) |
Further testing shows a886bb0 introduces regression on Linux. Only one out of 60 ISO transfers actually completes and the data received is corrupted. |
Just to clarify, this works on Windows & Linux now and can be merged? |
This can't be merged in the current form. There are two issues: use of C++11 feature std::mutex, and race condition of iterators of |
Well, write access to |
@xlz Would a semaphore then be more appropriate for handling that scenario? |
Pending_transfers_lock_.lock() and unlock() are needed in TransferPool::cancel(). It works well on my Mac. Without this, BAD ACCESS will occur when you push ESC key to quit the Protonect. |
@hanyazou I have added the lock - can you see/test if it works? |
@larshg it works. thank you for your quick response. |
In the current patch, |
@RyanGordon https://github.com/xlz/libfreenect2/commit/c6f6e57df3671285812e5ae3ac9ceedd49258d42 is my proposal to fix this bug. It refactors |
Locking pending_transfers_ when canceling transfers.
Superseded by lock-less variant in #275, closing. |
I tried updating libusb to the newest master, which due to this commit:
libusb/libusb@a886bb0
Made a lot more errors on the transfer submitting than I experienced before. After investigating it a bit, I came to the conclusion that there is thread unsafe adding and removing going on, which occasionally made the iterators invalid, since the underlying list/queue had changed.
This pull request adds a mutex to allow only one thread at a time to access the pending_transfer_ list.
Can you verify this @christiankerl?
There might be more places to handle this problem, but for now I'm not experiencing the errors anymore.
I tested with the "older" version of libusb and this addition doesn't seem to break it, nor make any performance loss.
This might be related to the error in #185.