Problem about Rc

I had read a lot about how to create a tree structure in rust, so many implementation use Rc to save the parent pointer.
for example [this post] (Implementing a Binary Tree in Rust for fun)

My problem is , if I had create a tree structure use Rc, But i want create a singleton in lazy_static just for read operation on tree. There is no way , because Rc not implement Sync .

lazy_static! {
    static ref TREE: Mutex<Tree> = create_tree(..)
}

another example, if i use a xml crate which use Rc to implement Dom Tree, So i can't create a Sync Dom ? if Dom isn't thread safe is ok , but add a mutex not work yet.
how to solve this problem except use another xml lib instead.
thank you i neead your help

Indeed, a Mutex won’t help making an Rc thread-safe. The thread-safe alternative would be to use Arc. When using a library that cannot support Arc, that’s unfortunate… if your use-case only involves single-threaded access anyways, then perhaps using a thread_local could be a way around the problem. If it’s accessed from multiple threads, then such a thread-local variable would be re-created once for each thread, so even that might not be too bad, depending on the use-case. If the xml crate you’re using is open-source, feel free to link it if you want someone take a second look on whether that really forces Rc the way it sounds from your description.

5 Likes

thank you , i use xml5ever in repo GitHub - servo/html5ever: High-performance browser-grade HTML5 parser it's use Rc html5ever/rcdom/lib.rs at master · servo/html5ever · GitHub . I had try thread_local which can solve my problem .

Try passing the Tree as argument to functions, or store it as a field in an object, instead of using a global variable. This makes dealing with Rc easier, and you won't need special crates and macros.

3 Likes

Another alternative approach for putting it into a static, still assuming that access is only from a single thread, is to use SendWrapper, which would do a run-time check that you only ever access the static from the same thread that initialized it.

lazy_static! {
    static ref TREE: SendWrapper<Tree> = SendWrapper::new(create_tree(..));
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.