-
Notifications
You must be signed in to change notification settings - Fork 182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Example usage of heapless::spsc
triggers UB?
#314
Comments
Indeed, this is probably UB. |
I also think it's UB, since this wouldn't be allowed even in a single thread if you paste it in the playground example let mut q = Queue(0);
let producer = q.split().0;
let consumer = q.split().1;
producer.enqueue();
consumer.dequeue();
I'm not saying it should look like this, this is the best I could come up with so far using an intermediary static PRODUCER: Mutex<RefCell<Option<Producer<'static, (), 4>>>> =
Mutex::new(RefCell::new(None));
fn main() {
let mut consumer = {
let (p, c) = {
static mut Q: Queue<(), 4> = Queue::new();
// SAFETY: Mutable access to `Q` is allowed exclusively in this scope
// and `main` is only called once.
unsafe { Q.split() }
};
critical_section::with(move |cs| {
let mut producer = PRODUCER.borrow_ref_mut(cs);
*producer = Some(p);
});
c
};
}
fn interrupt() {
let mut producer = {
static mut P: Option<Producer<'static, (), 4>> = None;
// SAFETY: Mutable access to `P` is allowed exclusively in this scope
// and `interrupt` cannot be called directly or preempt itself.
unsafe { &mut P }
}.get_or_insert_with(|| {
critical_section::with(|cs| {
PRODUCER.borrow_ref_mut(cs).take().unwrap()
})
});
} |
The
split
example ofheapless::spsc
attempts to avoid the need for using aMutex<RefCell<Queue>>
_as well as avoidingstatic
scope forProducer
andConsumer
by usingunsafe
code:I'm not 100% sure, but I believe this usage is in and of itself UB; the lifetime of
consumer
andproducer
is tied toQ
, and the mutable borrow ofQ
lasts as long asconsumer
orproducer
lives. If an interrupt happens whileconsumer
exists,Q
is mutably borrowed twice whenproducer
is created.I would appreciate clarification, as I'm not 100% sure if this is UB (and if it is, what an alternate
unsafe
solution should look like). Here is a playground snippet of me attempting to minimize thespsc
code to show UB in Miri: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=597cb05f9f1003515b01e82f79abb9c1The text was updated successfully, but these errors were encountered: