pub struct StaticInstancePerThread<T>where
T: Object,{ /* private fields */ }Expand description
This is the real type of variables wrapped in the linked::thread_local_rc! macro.
See macro documentation for more details.
Instances of this type are created by the linked::thread_local_rc! macro,
never directly by user code, which can call .with() or .to_rc()
to work with or obtain a linked instance of T.
Implementations§
Source§impl<T> StaticInstancePerThread<T>where
T: Object,
impl<T> StaticInstancePerThread<T>where
T: Object,
Sourcepub fn with<F, R>(&self, f: F) -> R
pub fn with<F, R>(&self, f: F) -> R
Executes a closure with the current thread’s linked instance from the object family referenced by the static variable.
§Example
use std::thread;
linked::thread_local_rc!(static EVENTS: EventCounter = EventCounter::new());
// Use .with() for efficient access when you do not need to store the Rc
EVENTS.with(|counter| {
counter.record_event();
assert_eq!(counter.local_count(), 1);
assert_eq!(counter.global_count(), 1);
});
// Multiple calls to .with() access the same thread-local instance
EVENTS.with(|counter| {
assert_eq!(counter.local_count(), 1); // Still 1 from previous event
assert_eq!(counter.global_count(), 1); // Still 1 globally
});
// Each thread gets its own instance with fresh local state but shared global state
thread::spawn(|| {
EVENTS.with(|counter| {
assert_eq!(counter.local_count(), 0); // Fresh local count for this thread
assert_eq!(counter.global_count(), 1); // But sees global count from main thread
counter.record_event();
assert_eq!(counter.local_count(), 1); // Local count incremented
assert_eq!(counter.global_count(), 2); // Global count now 2
});
}).join().unwrap();
// Back on main thread: local state unchanged, global state updated
EVENTS.with(|counter| {
assert_eq!(counter.local_count(), 1); // Still 1 locally
assert_eq!(counter.global_count(), 2); // But sees update from other thread
});§Performance
For repeated access to the current thread’s linked instance, prefer reusing an Rc<T>
obtained from .to_rc().
If your code is not in a situation where it can reuse an existing Rc<T>, this method is
the optimal way to access the current thread’s linked instance of T.
Sourcepub fn to_rc(&self) -> Rc<T>
pub fn to_rc(&self) -> Rc<T>
Gets an Rc<T> to the current thread’s linked instance from
the object family referenced by the static variable.
The instance behind this Rc is the same one accessed by all other calls through the static
variable on this thread. Note that it is still possible to create multiple instances on a
single thread, e.g. by cloning the T within. The “one instance per thread” logic only
applies when the instances are accessed through the static variable.
§Example
use std::rc::Rc;
use std::thread;
linked::thread_local_rc!(static WORKER: WorkerStats = WorkerStats::new());
// Get an Rc to reuse across multiple operations
let worker = WORKER.to_rc();
worker.process_task();
worker.process_task();
assert_eq!(worker.local_tasks(), 2);
assert_eq!(worker.total_work(), 2);
// Multiple calls to to_rc() return Rc to the same instance
let worker2 = WORKER.to_rc();
assert_eq!(worker2.local_tasks(), 2); // Same instance as worker
assert_eq!(worker2.total_work(), 2);
// Clone the Rc for efficiency when passing around
let worker_clone = Rc::clone(&worker);
worker_clone.process_task();
assert_eq!(worker.local_tasks(), 3);
assert_eq!(worker.total_work(), 3);
// Each thread gets its own instance with fresh local state but shared global state
thread::spawn(|| {
let thread_worker = WORKER.to_rc();
assert_eq!(thread_worker.local_tasks(), 0); // Fresh local state
assert_eq!(thread_worker.total_work(), 3); // But sees shared global state
thread_worker.process_task();
assert_eq!(thread_worker.local_tasks(), 1); // Local tasks: 1
assert_eq!(thread_worker.total_work(), 4); // Global total: 4
}).join().unwrap();
// Back on main thread: local state unchanged, global state updated
assert_eq!(worker.local_tasks(), 3); // Still 3 locally
assert_eq!(worker.total_work(), 4); // But sees update from other thread§Performance
This function merely clones an Rc, which is relatively fast but still more work than
doing nothing. The most efficient way to access the current thread’s linked instance is
to reuse the Rc<T> returned from this method.
If you are not in a situation where you can reuse the Rc<T> and a shared reference is
satisfactory, prefer calling .with() instead, which does not create an
Rc and thereby saves a few nanoseconds.