Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread safety #16

Open
pcercuei opened this issue Sep 10, 2021 · 4 comments
Open

Thread safety #16

pcercuei opened this issue Sep 10, 2021 · 4 comments

Comments

@pcercuei
Copy link

The readme states that "the contexts and devices in the underlying libiio are not thread safe."

They actually are, though. You can't obviously access some resources at the same time (e.g. trying to refill a buffer in two different threads at the same time), but you can read/write attributes in one thread and manipulate the buffer in another thread, it works just fine.

@tomstokes
Copy link

Analog doesn't guarantee thread-safety of the libiio functions, even if some of them happen to be usable across threads in their current implementation ( https://ez.analog.com/linux-software-drivers/f/q-a/90775/safe-to-assume-that-libiio-calls-are-thread-safe/197587#197587 )

The unreleased master branch exposes iio_context_clone to allow cloning contexts across threads: 14de9c2#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5

@pcercuei
Copy link
Author

Thread safety is guaranteed in the libiio functions. Libiio has been developed from the ground up with the idea that it should be thread-safe.

@fpagliughi
Copy link
Owner

fpagliughi commented Sep 12, 2021

@pcercuei Thanks for bringing this up! I have been in the same boat as @tomstokes; after reading some old blog posts, etc, was under the assumption that the library was not thread safe.

The problem with Rust (oops... I mean the great thing about Rust) is that it requires you to be completely explicit about things in regard to thread safety. So the statement "you can't access ... some resources at the same time" gets a little tricky. But I will definitely look into it for the next version.

@fpagliughi
Copy link
Owner

fpagliughi commented Jan 28, 2022

Having thought about this for a while, I'll likely split the difference...

Having believed that the contexts were not thread-safe, I made all the Rust objects !Send and !Sync, meaning that individual objects can not be shared across threads (!Sync) and they can not even be moved from one thread to another (!Send). This means that all objects derived from a context are forced to live in the same thread as that context.

Ha! Try that in C. 😄

But, with this new information, I'll start relaxing those constraints, starting by making Device movable across threads (i.e. Send). This would mean that the Context needs to be shared across those threads, and thus needs to be Sync.

As a first step, it would mean that a Device still couldn't be shared across threads, and that a Buffer object would still need to live in the same thread as the Device. With some further information about what's thread safe and not, I assume that this could also be relaxed.

But certainly it sounds like the Buffer::refill() function should take a mutable reference to self which would prevent it from being called by two threads simultaneously even if it were shared between them.

I'll take these one step at a time, with a release in between to try and get it right.

...and I'll update the README.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants