aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-08-05 22:20:16 +0200
committerDario Nieuwenhuis <[email protected]>2021-08-05 22:20:45 +0200
commitaaa0d1419cca754add76950ac9bae8a3dd526964 (patch)
treebf10936b0b92eacb7a125db3f5b739f1d47c0d91
parent8a65128cfed335e637ee80c91b1efc7b3c58ba10 (diff)
util: fix unsoundness when dropping ThreadModeMutex outside thread mode.
Fixes #283
-rw-r--r--embassy/src/util/mutex.rs17
1 files changed, 15 insertions, 2 deletions
diff --git a/embassy/src/util/mutex.rs b/embassy/src/util/mutex.rs
index 0506ffe6f..9a00a409e 100644
--- a/embassy/src/util/mutex.rs
+++ b/embassy/src/util/mutex.rs
@@ -82,9 +82,7 @@ impl<T> ThreadModeMutex<T> {
82 inner: UnsafeCell::new(value), 82 inner: UnsafeCell::new(value),
83 } 83 }
84 } 84 }
85}
86 85
87impl<T> ThreadModeMutex<T> {
88 /// Borrows the data 86 /// Borrows the data
89 pub fn borrow(&self) -> &T { 87 pub fn borrow(&self) -> &T {
90 assert!( 88 assert!(
@@ -107,6 +105,21 @@ impl<T> Mutex for ThreadModeMutex<T> {
107 } 105 }
108} 106}
109 107
108impl<T> Drop for ThreadModeMutex<T> {
109 fn drop(&mut self) {
110 // Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so
111 // `drop` needs the same guarantees as `lock`. `ThreadModeMutex<T>` is Send even if
112 // T isn't, so without this check a user could create a ThreadModeMutex in thread mode,
113 // send it to interrupt context and drop it there, which would "send" a T even if T is not Send.
114 assert!(
115 in_thread_mode(),
116 "ThreadModeMutex can only be dropped from thread mode."
117 );
118
119 // Drop of the inner `T` happens after this.
120 }
121}
122
110pub fn in_thread_mode() -> bool { 123pub fn in_thread_mode() -> bool {
111 #[cfg(feature = "std")] 124 #[cfg(feature = "std")]
112 return Some("main") == std::thread::current().name(); 125 return Some("main") == std::thread::current().name();