util: fix unsoundness when dropping ThreadModeMutex outside thread mode.

Fixes #283
This commit is contained in:
Dario Nieuwenhuis 2021-08-05 22:20:16 +02:00
parent 8a65128cfe
commit aaa0d1419c

View File

@ -82,9 +82,7 @@ impl<T> ThreadModeMutex<T> {
inner: UnsafeCell::new(value), inner: UnsafeCell::new(value),
} }
} }
}
impl<T> ThreadModeMutex<T> {
/// Borrows the data /// Borrows the data
pub fn borrow(&self) -> &T { pub fn borrow(&self) -> &T {
assert!( assert!(
@ -107,6 +105,21 @@ impl<T> Mutex for ThreadModeMutex<T> {
} }
} }
impl<T> Drop for ThreadModeMutex<T> {
fn drop(&mut self) {
// Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so
// `drop` needs the same guarantees as `lock`. `ThreadModeMutex<T>` is Send even if
// T isn't, so without this check a user could create a ThreadModeMutex in thread mode,
// send it to interrupt context and drop it there, which would "send" a T even if T is not Send.
assert!(
in_thread_mode(),
"ThreadModeMutex can only be dropped from thread mode."
);
// Drop of the inner `T` happens after this.
}
}
pub fn in_thread_mode() -> bool { pub fn in_thread_mode() -> bool {
#[cfg(feature = "std")] #[cfg(feature = "std")]
return Some("main") == std::thread::current().name(); return Some("main") == std::thread::current().name();