1

I have this toy structure I'm playing around with:

pub struct Community {
    pub community_contents: RwLock<CommunityContents>,
}

pub struct CommunityContents {
    pub friends: RefCell<HashMap<FriendID, FriendData>>, 
    pub index: RefCell<HashMap<u64, BTreeMap<FriendID, FriendData>>>, 
    pub authenticated: bool,
    pub age: u64,     
    pub height: u64,
}

My theory was to have an Arc around the RwLock of Community and then I could have multiple writers to the RwLock and these writers could independently/concurrently modify the friends and index fields of CommunityContents via Rc<RefCell.

Is this even possible? Will RwLock just not allow more than one writer at a time no matter what - in which case I should just remove the RefCells and simplify the whole structure?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Gman man
  • 475
  • 1
  • 4
  • 8
  • I advice you to read the answer to that question of mine to have the full picture: https://stackoverflow.com/a/45674912/4498831 – Boiethios Aug 05 '19 at 18:38
  • I thought this was a duplicate (of the Q linked above), but on reflection I'm less sure. I think this question is actually too broad to answer, as posed -- can you elaborate on what you mean by "concurrently modify [...] via `Rc`"? Or does the question linked by @FrenchBoiethios answer your question as well? – trent Aug 05 '19 at 18:59
  • @trentcl I mean to have threads modifying the friends and index fields at the same time. One set of threads to modify friends at the same time the index friend is modified by another thread. – Gman man Aug 05 '19 at 19:16
  • 1
    @Gmanman Well, you just have to fine-grain your locks. Don't put the whole community inside a RwLock, but put the friends and index into separate RwLocks – Boiethios Aug 05 '19 at 20:23

1 Answers1

1

No.

Arc does not allow mutation of the type it holds. Only immutable references can be shared, and Arc is no different.

From Arc docs:

Shared references in Rust disallow mutation by default, and Arc is no exception: you cannot generally obtain a mutable reference to something inside an Arc. If you need to mutate through an Arc, use Mutex, RwLock, or one of the Atomic types.

That means that you must store a type that has interior mutability... RwLock is one of those types, and it behaves identically, no matter whether it's wrapped in Arc or not.

From RwLock docs:

This type of lock allows a number of readers or at most one writer at any point in time.

It's impossible to obtain mutable reference in two different places using safe Rust no matter what you do, the only way is using unsafe {}, which results in undefined behaviour anyway, types like RwLock do use unsafe {}, but, they guarantee that the write (mutable access) is exclusive, in fact, it cannot be read if someone is writing to it, and it cannot be written to if someone is reading it, that's what that sentence means.