From: Christian Gagneraud <chris(a)techworks.ie>
gr-osmosdr uses the driver in a multi-thread context, as a side effect the
cancel_async() can be called before read_async(), in such a case the cancel is
"forgotten". This patch fixed that by being a bit more relaxed with
state machine transitions.
This patch doesn't fix any race conditions, it just make an anoying one less
likely to happen.
This patch goes along this one [1]
[1]
http://lists.osmocom.org/pipermail/osmocom-sdr/2012-August/000201.html
Signed-off-by: Christian Gagneraud <chris(a)techworks.ie>
---
src/librtlsdr.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/librtlsdr.c b/src/librtlsdr.c
index 4e54d8e..d83010d 100644
--- a/src/librtlsdr.c
+++ b/src/librtlsdr.c
@@ -1256,6 +1256,12 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb,
void *ctx,
if (!dev)
return -1;
+ /* It can happen if cancel_async is called before read_async */
+ if (dev->async_status != RTLSDR_INACTIVE)
+ return -1;
+
+ dev->async_status = RTLSDR_RUNNING;
+
dev->cb = cb;
dev->cb_ctx = ctx;
@@ -1284,8 +1290,6 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb,
void *ctx,
libusb_submit_transfer(dev->xfer[i]);
}
- dev->async_status = RTLSDR_RUNNING;
-
while (RTLSDR_INACTIVE != dev->async_status) {
r = libusb_handle_events_timeout(dev->ctx, &tv);
if (r < 0) {
@@ -1326,7 +1330,7 @@ int rtlsdr_cancel_async(rtlsdr_dev_t *dev)
if (!dev)
return -1;
- if (RTLSDR_RUNNING == dev->async_status) {
+ if (RTLSDR_CANCELING != dev->async_status) {
dev->async_status = RTLSDR_CANCELING;
return 0;
}
--
1.7.7