]> sigrok.org Git - libsigrok.git/commitdiff
sr: fx2lafw: Abort pending transfers when sampling is stopped
authorLars-Peter Clausen <redacted>
Tue, 3 Jul 2012 21:58:38 +0000 (23:58 +0200)
committerBert Vermeulen <redacted>
Tue, 3 Jul 2012 23:11:50 +0000 (01:11 +0200)
The recent reworks of the fx2lafw made sure that the total buffer size is large
enough hold 500ms of data. This was done to improve performance and stability.
That the timeout value for a transfer was also increased to over 500ms, a side
effect of this is that when sampling is stopped there will be a additional delay
of 500ms. This is because the driver waits for all transfers to be freed
before it sends a SR_DF_END packet. Once sampling has stopped this will only
happen once a transfer times out. This patch cancels all pending transfers when
sampling is stopped, this will cause them to be freed almost immediately and the
additional delay will disappear.

Also make sure, that if we know, that we just have received the last transfer to
not resubmit this transfer again.

Signed-off-by: Lars-Peter Clausen <redacted>
hardware/fx2lafw/fx2lafw.c
hardware/fx2lafw/fx2lafw.h

index 53a2e09f025c03f0563fa1b9e75e75b20c5f6a57..28866133962ec6d3eb5e3b7883d34b770068e95f 100644 (file)
@@ -662,7 +662,14 @@ static int receive_data(int fd, int revents, void *cb_data)
 
 static void abort_acquisition(struct context *ctx)
 {
+       unsigned int i;
+
        ctx->num_samples = -1;
+
+       for (i = 0; i < ctx->num_transfers; i++) {
+               if (ctx->transfers[i])
+                       libusb_cancel_transfer(ctx->transfers[i]);
+       }
 }
 
 static void finish_acquisition(struct context *ctx)
@@ -680,16 +687,27 @@ static void finish_acquisition(struct context *ctx)
        for (i = 0; lupfd[i]; i++)
                sr_source_remove(lupfd[i]->fd);
        free(lupfd); /* NOT g_free()! */
+
+       ctx->num_transfers = 0;
+       g_free(ctx->transfers);
 }
 
 static void free_transfer(struct libusb_transfer *transfer)
 {
        struct context *ctx = transfer->user_data;
+       unsigned int i;
 
        g_free(transfer->buffer);
        transfer->buffer = NULL;
        libusb_free_transfer(transfer);
 
+       for (i = 0; i < ctx->num_transfers; i++) {
+               if (ctx->transfers[i] == transfer) {
+                       ctx->transfers[i] = NULL;
+                       break;
+               }
+       }
+
        ctx->submitted_transfers--;
        if (ctx->submitted_transfers == 0)
                finish_acquisition(ctx);
@@ -833,6 +851,8 @@ static void receive_transfer(struct libusb_transfer *transfer)
                if (ctx->limit_samples &&
                        (unsigned int)ctx->num_samples > ctx->limit_samples) {
                        abort_acquisition(ctx);
+                       free_transfer(transfer);
+                       return;
                }
        } else {
                /*
@@ -906,6 +926,12 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data)
        const unsigned int num_transfers = get_number_of_transfers(ctx);
        const size_t size = get_buffer_size(ctx);
 
+       ctx->transfers = g_try_malloc0(sizeof(*ctx->transfers) * num_transfers);
+       if (!ctx->transfers)
+               return SR_ERR;
+
+       ctx->num_transfers = num_transfers;
+
        for (i = 0; i < num_transfers; i++) {
                if (!(buf = g_try_malloc(size))) {
                        sr_err("fx2lafw: %s: buf malloc failed.", __func__);
@@ -921,7 +947,7 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data)
                        g_free(buf);
                        return SR_ERR;
                }
-
+               ctx->transfers[i] = transfer;
                ctx->submitted_transfers++;
        }
 
index 727c0fa6d8b9147ba692bf808f0296cfc29c125c..ae3ed1bc31753664ed9b8e345447ad56468db799 100644 (file)
@@ -89,6 +89,9 @@ struct context {
        void *session_dev_id;
 
        struct sr_usb_dev_inst *usb;
+
+       unsigned int num_transfers;
+       struct libusb_transfer **transfers;
 };
 
 #endif