Hello.
I'm developing a firmware for an embedded system with no std. The system can trigger interrupts and in the handler function I need to access some data from the main execution thread.
The reference to the data is set via statically allocated Option. It is guaranteed that when the Option has the reference, the reference is valid. The Option is guaranteed to be set to None before the reference becomes invalid.
However, I can't avoid errors by the borrow checker when the data is not statically allocated.
Is there any language feature that will guarantee resetting the Option before the reference becomes invalid, so that there are no errors by the borrow checker?
Othersise, is there any other way I can avoid the errors by the borrow checker?
Here is an example:
use std::cell::RefCell;
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
static GLOBAL_A: A = A::new();
fn some_thread() {
loop {
if let Some(str) = *GLOBAL_A.val.lock().unwrap().borrow() {
println!("THREAD: the string: {}", str);
} else {
println!("THREAD: no string.");
}
thread::sleep(Duration::from_millis(300));
}
}
struct A<'a> {
val: Mutex<RefCell<Option<&'a str>>>,
}
impl<'a> A<'a> {
const fn new() -> Self {
Self {
val: Mutex::new(RefCell::new(None)),
}
}
}
struct B<'a> {
aref: &'a A<'a>,
}
impl<'a> B<'a> {
fn new(aref: &'a A<'a>) -> Self {
Self { aref }
}
fn method(&self, s: &'a str, duration: Duration) {
println!("B: string set: {}", s);
*self.aref.val.lock().unwrap().borrow_mut() = Some(s);
thread::sleep(duration);
*self.aref.val.lock().unwrap().borrow_mut() = None;
println!("B: string reset.");
}
}
fn main() {
thread::spawn(some_thread);
let b = B::new(&GLOBAL_A);
b.method("hello", Duration::from_millis(500));
thread::sleep(Duration::from_millis(1000));
b.method("bye", Duration:`Preformatted text`:from_millis(1000));
thread::sleep(Duration::from_millis(1000));
let some_str = String::from("dynamic str");
// b.method(some_str.as_str(), Duration::from_millis(1000)); // some_str` does not live long enough
}
The output:
B: string set: hello
THREAD: the string: hello
THREAD: the string: hello
B: string reset.
THREAD: no string.
THREAD: no string.
THREAD: no string.
B: string set: bye
THREAD: the string: bye
THREAD: the string: bye
THREAD: the string: bye
THREAD: the string: bye
B: string reset.
At the end, when the data is locally allocated (from String
), the borrow checker does not allow me to pass the reference to the data in the method
function due to error[E0597]:
some_str does not live long enough
.
Is there any way I can make this code work without copying the data into statically allocated memory?
Thanks!