How to create a complex concurrent datastructure in rust

Viewed 159

I need a struct containing several fields that should be usable in a concurrent context.

struct Foo {
    number: u32,
    collection: Vec<u32>,
}

In C I would add a Mutex to the struct and (un)lock that, but doing this in rust, using a Mutex<()> is not possible, as the struct is located somewhere inside an Arc. This means I need the Mutex around the fields if I want to mutate them.
However this leads to problems if I want to extract functionality into private methods, as Mutex is not reentrant. [Edit] If the fields in question are needed in both the main method and the helper method, locking multiple times is not the solution, as I would like the whole block to be treated as one unit, otherwise it would be possible to change something inbetween from another thread. [/Edit]

In the simeple case like above, the solution would probably be to not make it concurrent at all and let the caller deal with it, i.e. use Mutex<Foo> and deal with the locking every time it is used.

However, in some situations, a CondVar is needed, to wait on the collection being filled or emptied, in which case I need a MutexGuard to wait on. I guess I could move the CondVar to the outside as well, but then I would need to be concerned with the inner workings of my struct on the outside, which I don't like at all.

I don't know if I'm going completely into the wrong direction here, but I couldn't find anything on this by searching the web. Everything only talks about locking simple datatypes.

The approaches mentioned above:

struct Foo {
    lock: Mutex<()>,
    number: u32,
    collection: Vec<u32>,
}
struct Foo {
    number: Mutex<u32>,
    collection: Mutex<Vec<u32>>,
}

impl Foo {
    pub fn add_if_bigger(&self, v: u32) {
        let collection = self.collection.lock().unwrap();
        if self.is_bigger(v) {
            collection.push(v);
        }
    }

    fn is_bigger(&self) -> bool {
        let collection = self.collection.lock().unwrap();
        // already locked by this thread --^
        // ...
    }
}
0 Answers
Related