> >> > impl AddressSpace { > >> > pub fn get_flatview(&self, rcu: &'g Guard) -> &'g FlatView { > >> > >> IIUC, this lifetime is using the "branded type" pattern as ParentInit. > >> > > > > No, it's much simpler (that one uses the combination of for<'identity> and > > PhantomData as explained in the comment). It says that the lifetime of the > > returned reference cannot exceed the guard. It's just like > > > > pub fn get_item(&self, array: &'g [u8]) -> &'g u8 { > > &array[self.0] > > } > > > > Except that the guard is only there to limit the lifetime and not to hold > > data.
I see. It's clear for me now. Thank you! > > In addition, about rcu_read_lock_held(), I thought at C side, there're > >> so many comments are saying "Called within RCU critical section" but > >> without any check. > >> > >> So I wonder whether we should do some check for RCU critical section, > >> just like bql check via `assert!(bql_locked())`. Maybe we can have a > >> Rcu debug feature to cover all these checks. > >> > > > > In Rust you would just pass a &RcuGuard into the function (or store it in > > a struct) for a zero-cost assertion that you are in the RCU critical > > section. > > > > Agreed. You could put debug_asserts for sanity check for good measure. Thanks! Then I see, the most RCU critical part is accessing FlatView through AddressSpace. Here, require RCU by function signature (&RcuGuard) is very convenient: pub fn get_flatview<'g>(&self, rcu: &'g RcuGuard) -> &'g FlatView; As for the methods of FlatView itself and the lower-level interfaces (e.g., the write & read detail methods), although RCU critical sections are also required, there is no need to worry about them because the upper-level access already ensures RCU lock is held. Of course, it would be better to add &RcuGuard to some structures and check them with debug_assert/assert. Regards, Zhao