Skip to content

Commit

Permalink
iiod: Avoid race between buffer destroy and set buffers count
Browse files Browse the repository at this point in the history
The client might call iio_device_set_kernel_buffers_count() right after
destroying the device's buffer with iio_buffer_destroy(). Since the
first operation cannot work if the buffer is enabled, we must wait until
the buffer has been effectively disabled before the setting can be
applied.

Signed-off-by: Paul Cercueil <[email protected]>
  • Loading branch information
pcercuei committed Aug 3, 2021
1 parent e2ba5d4 commit 02527e6
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions iiod/ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1363,16 +1363,33 @@ int set_timeout(struct parser_pdata *pdata, unsigned int timeout)
int set_buffers_count(struct parser_pdata *pdata,
struct iio_device *dev, long value)
{
unsigned int i, nb = (unsigned int) value;
struct timespec wait;
int ret = -EINVAL;

if (!dev) {
ret = -ENODEV;
goto err_print_value;
}

if (value >= 1)
ret = iio_device_set_kernel_buffers_count(
dev, (unsigned int) value);
if (nb >= 1) {
/*
* Avoid the same race condition described in open_dev_helper().
* We must be sure that the buffer has not been enabled in order
* to set the number of kernel buffers.
*/
for (i = 0; i < 500; i++) {
ret = iio_device_set_kernel_buffers_count(dev, nb);
if (ret != -EBUSY)
break;

wait.tv_sec = 0;
wait.tv_nsec = (100 * 1000);
do {
ret = nanosleep(&wait, &wait);
} while (ret == -1 && errno == EINTR);
}
}
err_print_value:
print_value(pdata, ret);
return ret;
Expand Down

0 comments on commit 02527e6

Please sign in to comment.