Skip to main content

starnix_rcu/
rcu_string.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fuchsia_rcu::{RcuCell, RcuReadScope};
6use starnix_types::string::{FsStr, FsString};
7
8/// An RCU-protected string.
9///
10/// This type wraps an `RcuCell<FsString>` and provides a convenient API for reading
11/// the string as an `FsStr` within an `RcuReadScope`.
12#[derive(Debug, Default)]
13pub struct RcuString {
14    cell: RcuCell<FsString>,
15}
16
17impl RcuString {
18    /// Create a new `RcuString`.
19    pub fn new(value: impl Into<FsString>) -> Self {
20        Self { cell: RcuCell::new(value.into()) }
21    }
22
23    /// Read the string value.
24    ///
25    /// The returned `FsStr` is valid for the duration of the `RcuReadScope`.
26    pub fn read<'a>(&self, scope: &'a RcuReadScope) -> &'a FsStr {
27        self.cell.as_ref(scope).as_ref()
28    }
29
30    /// Update the string value.
31    ///
32    /// This will replace the underlying `FsString` with a new one. Readers holding
33    /// an `RcuReadScope` will continue to see the old value until they drop the scope.
34    pub fn update(&self, value: impl Into<FsString>) {
35        self.cell.update(value.into());
36    }
37}
38
39impl From<FsString> for RcuString {
40    fn from(value: FsString) -> Self {
41        Self::new(value)
42    }
43}
44
45impl From<&FsStr> for RcuString {
46    fn from(value: &FsStr) -> Self {
47        Self::new(value)
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_rcu_string_read() {
57        let s = RcuString::new("hello");
58        let scope = RcuReadScope::new();
59        assert_eq!(s.read(&scope), "hello");
60    }
61
62    #[test]
63    fn test_rcu_string_update() {
64        let s = RcuString::new("initial");
65
66        // Read initial value
67        {
68            let scope = RcuReadScope::new();
69            assert_eq!(s.read(&scope), "initial");
70        }
71
72        // Update value
73        s.update("updated");
74
75        // Read new value
76        {
77            let scope = RcuReadScope::new();
78            assert_eq!(s.read(&scope), "updated");
79        }
80    }
81}