pub struct Local<T> { /* private fields */ }
Expand description
Local
is a custom smart pointer-like structure designed to manage T
in a single-threaded,
non-concurrent context.
This design is aligned with the shared-nothing concurrency model, which avoids shared memory between threads to reduce the complexity of synchronization.
§What does concurrent context mean in single-threaded execution?
§Invalid code (with single-threaded concurrency):
use orengine::Local;
async fn write_and_dump_data_and_return_was_sent(counter: Local<Data>) -> bool {
let mut local_ref = counter.borrow_mut();
if is_valid_data(&*local_ref) {
dump_data(&*local_ref).await; // Here the executor can execute other task, that change the data to invalid
send_data(&*local_ref).await;
return true;
}
false
}
§Safety
Local
is used in one thread;- Before every
await
operation,LocalRef
andLocalRefMut
need to be dropped, if other task can mutate the value and.
It is checked in debug
mode. If you cannot guarantee compliance with the above rules
you should use LocalMutex
or
LocalRWLock
instead. Local synchronization-primitives have
almost the same performance as Local
or Rc<RefCell>
and can be used in single-threaded
concurrency context.
§Shared-Nothing and spawn_local
In Rust, when working with local, task-specific data, you may want to leverage
shared-nothing concurrency by isolating data to specific threads.
Using the Local
struct with spawn_local
(which ensures that a task runs in a local thread) allows you to maintain this isolation.
Since Local
cannot be transferred to another thread, it enforces the
shared-nothing principle, where each every thread holds and manages its own data independently.
§Example
use orengine::local::Local;
use orengine::Executor;
use orengine::local_executor;
Executor::init().run_with_local_future(async {
let local_data = Local::new(42);
println!("The value is: {}", local_data);
*local_data.borrow_mut() += 1;
println!("Updated value: {}", local_data);
// Cloning (increments the internal counter)
let cloned_data = local_data.clone();
local_executor().spawn_local(async move {
assert_eq!(*cloned_data.borrow(), 43);
});
});
Implementations§
Source§impl<T> Local<T>
impl<T> Local<T>
Sourcepub fn new(data: T) -> Self
pub fn new(data: T) -> Self
Creates a new Local
instance, initializing it with the provided data.
§Panics
If the Executor
is not initialized.
Read MSG_LOCAL_EXECUTOR_IS_NOT_INIT
for more details.
Sourcepub fn borrow_mut(&self) -> LocalRefMut<'_, T>
pub fn borrow_mut(&self) -> LocalRefMut<'_, T>
Returns LocalRefMut
that allows mutable access to the data.
Read more in LocalRefMut
.
§Panics
Panics in debug
mode if the value in Local
is currently mutably borrowed or if
Local
has been moved to another thread.
Trait Implementations§
Source§impl<T: Ord> Ord for Local<T>
impl<T: Ord> Ord for Local<T>
Source§fn cmp(&self, other: &Self) -> Ordering
fn cmp(&self, other: &Self) -> Ordering
§Panics
Panics in debug
mode if the value in either Local
is currently mutably borrowed or if
Local
has been moved to another thread.
1.21.0 · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<T: PartialEq> PartialEq for Local<T>
impl<T: PartialEq> PartialEq for Local<T>
Source§impl<T: PartialOrd> PartialOrd for Local<T>
impl<T: PartialOrd> PartialOrd for Local<T>
Source§fn partial_cmp(&self, other: &Self) -> Option<Ordering>
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
§Panics
Panics in debug
mode if the value in either Local
is currently mutably borrowed or if
Local
has been moved to another thread.
Source§fn lt(&self, other: &Self) -> bool
fn lt(&self, other: &Self) -> bool
§Panics
Panics in debug
mode if the value in either Local
is currently mutably borrowed or if
Local
has been moved to another thread.
Source§fn le(&self, other: &Self) -> bool
fn le(&self, other: &Self) -> bool
§Panics
Panics in debug
mode if the value in either Local
is currently mutably borrowed or if
Local
has been moved to another thread.