AnsweredAssumed Answered

Efficiently terminating iio_buffer_dequeue_block

Question asked by davidspencerward on Apr 3, 2015
Latest reply on Apr 7, 2015 by larsc

Zynq architecture.

We have a need to terminate an existing call to iio_buffer_dequeue_block() so that we can efficiently stop our sample receive. There have been other discussions about this and they suggest using a signal (e.g., SIG_USR1) to terminate the iio_buffer_dequeue_block(). However, that is like using a sledgehammer to drive a nail since signals are process level events and this is a threading problem.

I'm assuming that the iio_buffer_dequeue_block() call is waiting on the line ret = wait_event_interruptible(buffer->pollq, iio_buffer_data_available(buffer) || indio_dev->info == NULL). There already is a iio_buffer_wakeup_poll() method that will call wake_up on the wait queue.

It would seem much simpler to call iio_buffer_wakeup_poll() from another thread and this will cause wait_event_interruptible() to check its condition. If we add a new flag to the condition, this should work simply and without the use of signals:

Change the current code:

    ret = wait_event_interruptible(buffer->pollq, iio_buffer_data_available(buffer) || indio_dev->info == NULL);
    if (ret) return ret;
    if (indio_dev->info == NULL) return -ENODEV;

to:

    ret = wait_event_interruptible(buffer->pollq, iio_buffer_data_available(buffer) || indio_dev->info == NULL || cancelFlag);
    if (ret) return ret;
    if (indio_dev->info == NULL)return -ENODEV;
    if (cancelFlag) return -EINTR;

 

Then just have iio_buffer_wakup_poll() set the cancelFlag to true and then call wake_up().

 

Your thoughts?

 

David

Outcomes