util: fix unsoundness when dropping ThreadModeMutex outside thread mode.
Fixes #283
This commit is contained in:
		| @@ -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(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user