canic_memory/macros/
runtime.rs

1/// Run `$body` during process start-up using `ctor`.
2///
3/// The macro expands to a `ctor` hook so eager TLS initializers can register
4/// their work before any canister lifecycle hooks execute. Prefer wrapping
5/// the body in a separate function for larger initializers to keep the hook
6/// simple.
7#[macro_export]
8macro_rules! eager_init {
9    ($body:block) => {
10        #[ $crate::export::ctor::ctor(anonymous, crate_path = $crate::export::ctor) ]
11        fn __canic_eager_init() {
12            $body
13        }
14    };
15}
16
17/// Declare a thread-local static and schedule an eager initialization touch.
18///
19/// Expands to a `thread_local!` block and ensures the TLS slot is accessed
20/// during the eager-init phase so subsequent calls observe a fully
21/// initialized value. Use this for caches that must exist before canister
22/// entry points run.
23#[macro_export]
24macro_rules! eager_static {
25    ($vis:vis static $name:ident : $ty:ty = $init:expr;) => {
26        thread_local! {
27            $vis static $name: $ty = $init;
28        }
29
30        // A simple wrapper function that forces TLS initialization.
31        fn __touch_tls() {
32            $name.with(|_| {});
33        }
34
35        $crate::eager_init!({
36            $crate::runtime::defer_tls_initializer(__touch_tls);
37        });
38    };
39}