I'm currently using the thread_local!
macro:
thread_local!(static FOO: RefCell<Foo> = RefCell::new(Foo::new()));
I only ever need immutable references to FOO - it's read only. Its purpose is to cache the result of an expensive calculation, so that the result can be used in many places in the rest of the program, without being explicitly passed through many levels of function and method invocations.
Rust allows multiple readers, if there is no writer.
Is there a way that I can create a read-only global variable FOO at the start of main()
(or before) and get read-only access to it from multiple threads (which are all spawned after FOO is initialised)?
I've looked at lazy_static
but that has lazy initialisation, which implies that there are runtime checks to see if it has been initialised yet. I'm looking for something which compiles to just a memory address (in the code which uses it) where the content of that memory is initialised at (or before) the start of main()
and is never changed.
This really feels like it's unnecessary except in the absolute rarest of performance-critical situations.
There are crates (e.g. ctor
) that let you do computations before main
, but most of std
cannot be used before main
, so you'll be extremely limited in what you can do. If we're going to do this, then lets do it as the first thing in main
:
// result of expensive calculation
#[derive(Debug)]
pub struct Foo(String);
static mut FOO: *const Foo = std::ptr::null();
fn init_foo() {
// expensive calculation
let foo = Box::new(Foo(String::from("expensive!")));
unsafe {
// leak the value, so it will never be dropped or freed
FOO = Box::leak(foo) as *const Foo;
}
}
// public accessor for Foo
pub fn get_foo() -> &'static Foo {
unsafe {
&*FOO
}
}
fn main() {
// better remember to do this or it's UB!
init_foo();
println!("foo = {:?}", get_foo());
}