Skip to content

Commit f9cd43a

Browse files
committed
Handling race condition for list/queues and iterators.
Locking pending_transfers_ when canceling transfers.
1 parent 1ef08ee commit f9cd43a

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

examples/protonect/include/libfreenect2/usb/transfer_pool.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <deque>
3131
#include <libusb.h>
32+
#include <libfreenect2/threading.h>
3233

3334
#include <libfreenect2/data_callback.h>
3435

@@ -70,6 +71,8 @@ class TransferPool
7071
libusb_device_handle *device_handle_;
7172
unsigned char device_endpoint_;
7273

74+
mutex pending_transfers_lock_;
75+
mutex idle_transfers_lock_;
7376
TransferQueue idle_transfers_, pending_transfers_;
7477
unsigned char *buffer_;
7578
size_t buffer_size_;

examples/protonect/src/transfer_pool.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ void TransferPool::disableSubmission()
6060

6161
void TransferPool::deallocate()
6262
{
63+
idle_transfers_lock_.lock();
6364
for(TransferQueue::iterator it = idle_transfers_.begin(); it != idle_transfers_.end(); ++it)
6465
{
6566
libusb_free_transfer(*it);
6667
}
68+
idle_transfers_lock_.unlock();
69+
6770
idle_transfers_.clear();
6871

6972
if(buffer_ != 0)
@@ -86,6 +89,7 @@ void TransferPool::submit(size_t num_parallel_transfers)
8689
{
8790
std::cerr << "[TransferPool::submit] too few idle transfers!" << std::endl;
8891
}
92+
pending_transfers_lock_.lock();
8993

9094
for(size_t i = 0; i < num_parallel_transfers; ++i)
9195
{
@@ -105,10 +109,14 @@ void TransferPool::submit(size_t num_parallel_transfers)
105109
std::cerr << "[TransferPool::submit] failed to submit transfer" << std::endl;
106110
}
107111
}
112+
113+
pending_transfers_lock_.unlock();
108114
}
109115

110116
void TransferPool::cancel()
111117
{
118+
pending_transfers_lock_.lock();
119+
112120
for(TransferQueue::iterator it = pending_transfers_.begin(); it != pending_transfers_.end(); ++it)
113121
{
114122
int r = libusb_cancel_transfer(*it);
@@ -119,6 +127,8 @@ void TransferPool::cancel()
119127
}
120128
}
121129

130+
pending_transfers_lock_.unlock();
131+
122132
//idle_transfers_.insert(idle_transfers_.end(), pending_transfers_.begin(), pending_transfers_.end());
123133
}
124134

@@ -160,6 +170,7 @@ void TransferPool::onTransferCompleteStatic(libusb_transfer* transfer)
160170

161171
void TransferPool::onTransferComplete(libusb_transfer* transfer)
162172
{
173+
pending_transfers_lock_.lock();
163174
// remove transfer from pending queue - should be fast as it is somewhere at the front
164175
TransferQueue::iterator it = std::find(pending_transfers_.begin(), pending_transfers_.end(), transfer);
165176

@@ -170,6 +181,8 @@ void TransferPool::onTransferComplete(libusb_transfer* transfer)
170181

171182
pending_transfers_.erase(it);
172183

184+
pending_transfers_lock_.unlock();
185+
173186
// process data
174187
processTransfer(transfer);
175188

0 commit comments

Comments
 (0)