I'm trying to get my program compiled but I have problems with some functions returning Iterator or using them.
The program is pretty long, so I will write here only pieces I think are interested. The full program is available at lcs.git -
First, the set of functions
If it compiled, it would mean you could access the interior of the mutex without holding a lock (you can keep the returned reference as long as you want!), which is exactly what Mutex tries to prevent.
The solution would be to make the code slightly less functional, and combine maps and filters into one function:
self.channels.iter()
.filter_map(|arc| {
let channel = arc.lock().unwrap();
if r.is_changed() {
Some(channel.get_ch_val())
} else {
None
}
})
Unfortunately, that would require you to Box the returned iterator or use the -> impl Iterator feature from nightly. I guess you've avoided the closures here, so you can express the iterator's type. You can also put this closure to a function, if you want.
(Alternatively, you can make your functions operate on MutexGuard instead of &Channel, but that would compicate your signatures even more)
Speaking of your second error, the problem is that changed_ch_vals borrows self mutably (I guess that's because of the self.needs_update = false;). Unfortunately, that kind of signature means that the mutable borrow will be held as long as the returned value is alive (the 'a appears both near self and inside a returned value). Since you call that method inside a flat_map, that would mean multiple mutable borrows would occur.
The simplest solution would be just to write a nested for loop instead of the flat_map. The less simple would be to change &mut self to &self, put needs_update into a Cell. The closure inside of the flat_map also needs to be marked as move, so it captures d by value, not reference. (move |d| ...)
Didn't know about filter_map, now I think it's very useful sometimes.
For the second error I found that I was locking a RwLock in read mode, so obviously I couldn't modify it.
Anyway I did a nested for loop and separated the function that returns the iterator from the function that set needs_update to false in order not to hide the mutation.