Closed skrap closed 5 years ago
Wow. Thanks. As you probably noticed, I've left this project sitting for a few months, but coincidentally, I am about to start working on it again to get a production-quality release in the next few weeks. I will look at this shortly.
Sorry for the long delay. I'm finally getting back to this project.
The updates look good, and are definitely necessary. I am worried about the breaking change to the meaning of Context::clone()
, however. The iio_context_clone()
call creates a copy of the context that is safe to use from another thread.
In Rust Embedded Linux crates, it seems that Clone is commonly used to increment the reference count to the same object rather than making a deep copy. But I believe that it's also quite common to use clone to make a copy of a thing that can then be sent to another thread - either via Arc or deep copy.
Due to the library call, an existing IIO user might have an opinion on the meaning of cloning a context that assumes creating a copy in the library which is save to use in another thread.
So we have two competing ideas of what "clone" means, and I see them as equally valid. And we should implement both. But how do we do that without being totally confusing?
Good question... I think clone
is more fundamental to Rust than it is to IIO. (I never even knew cloning a IIO context was something which could be done, and I've been using IIO for years!) However, it's nearly impossible to do anything of consequence in Rust without using clone(). So I'd favor clone
staying with its Rusty meaning, and clone_inner
or clone_context
or maybe iio_clone
to be the name of the callthrough to the underlying library. If the name was clone_context
then someone autocompleting with RLS or looking through the docs would see both listed next to each other, and would hopefully be curious enough to disambiguate them.
OK. Nevermind. If the Context is not Send
, then we can't clone it using the library and then move it into another thread anyway. It would be a useless trap! I suppose a Context could only be Send
if it is newly-constructed and hasn't been used to create a Device yet. But I don't know how to police that.
So we'll go with the "rustier" definition of Clone and increment the ref count.
I cherry-picked out the rustfmt commit, as it's clashing with a local branch I haven't pushed yet. At some point, I'll format and push. I also renamed RawContext
as InnerContext
as that seems more of a convention I've seen in other crates. Embedded Linux ones, anyway.
Thanks again! I hope to have a new release ready targeting v0.18 in a few weeks, possibly doing a better job at generating auto-building the C lib, etc.
Awesome! I left the rustfmt in a separate commit for just this reason. Glad it worked out! And thanks for your work on this crate. Very useful! :balloon: :tada:
Hello! I have been using this crate for some prototype work. Thanks! I ran into issues with runtime crashes due to Context structs being dropped while there were still Device and Channel structs alive which (internally within libiio) still referred to the iio_context. I took some time to do some internal refactoring to add reference counting so that this crash would be impossible. I think it slightly improves the ergonomics as well, as the user need not keep around a Context object if they don't want it. I removed some APIs which were not immediately easy to port to this new scheme. See the commit comments for more info. I hope this is useful!