Skip to main content

low_latency_data_structures/seqlock/
reader.rs

1use std::sync::Arc;
2
3use crate::seqlock::lock::SeqLock;
4
5/// A reading handle of a [`SeqLock`](crate::seqlock).
6///
7/// Cheap to clone: multiple readers may share the same lock. [`Reader`] is
8/// both [`Send`] and [`Sync`]; concurrent reads do not interfere because the
9/// underlying validation protocol is wait-free for readers in the absence of
10/// a concurrent writer and lock-free in its presence.
11pub struct Reader<T>
12where
13    T: bytemuck::AnyBitPattern,
14{
15    inner: Arc<SeqLock<T>>,
16}
17
18impl<T> std::fmt::Debug for Reader<T>
19where
20    T: bytemuck::AnyBitPattern,
21{
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        f.debug_struct("Reader").finish_non_exhaustive()
24    }
25}
26
27impl<T> Clone for Reader<T>
28where
29    T: bytemuck::AnyBitPattern,
30{
31    fn clone(&self) -> Self {
32        Self {
33            inner: self.inner.clone(),
34        }
35    }
36}
37
38impl<T> Reader<T>
39where
40    T: bytemuck::AnyBitPattern,
41{
42    pub(super) fn new(seqlock: Arc<SeqLock<T>>) -> Self {
43        Self { inner: seqlock }
44    }
45
46    /// Reads the latest stable value.
47    ///
48    /// Spin-loops while the writer is mid-write or while a torn read is
49    /// observed; returns once a consistent value has been observed.
50    ///
51    /// # Examples
52    ///
53    /// ```
54    /// use low_latency_data_structures::seqlock::new;
55    ///
56    /// let (writer, reader) = new(0u64);
57    /// writer.write(42);
58    /// assert_eq!(reader.read(), 42);
59    /// ```
60    #[inline]
61    #[must_use]
62    pub fn read(&self) -> T {
63        self.inner.read()
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    // There may be multiple readers as they only read and don't mutate anything.
72    // In case someone removes unsafe impl on SeqLock
73    static_assertions::assert_impl_all!(Reader<u32>: Send, Sync);
74    static_assertions::assert_impl_all!(Arc<Reader<u32>>: Send, Clone);
75}