about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexis Bourget <alexis.bourget@gmail.com>2020-07-11 00:15:24 +0200
committerAlexis Bourget <alexis.bourget@gmail.com>2020-09-21 22:37:30 +0200
commita83b79ec31df3a467753c3e5b41cf457af544c7b (patch)
tree829f38112852740dbb8cbe81597b2b18ff63e40f
parent8c9cb06c2ec287e4b9d2bce79390b444752c3686 (diff)
downloadrust-a83b79ec31df3a467753c3e5b41cf457af544c7b.tar.gz
rust-a83b79ec31df3a467753c3e5b41cf457af544c7b.zip
Finished documenting all unsafe op inside unsafe fn
-rw-r--r--library/std/src/thread/local.rs22
1 files changed, 17 insertions, 5 deletions
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 991631d91f0..281e1ef6741 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -539,20 +539,28 @@ pub mod os {
         }
 
         pub unsafe fn get(&'static self, init: fn() -> T) -> Option<&'static T> {
-            let ptr = self.os.get() as *mut Value<T>;
+            // SAFETY: No mutable references are ever handed out meaning getting
+            // the value is ok.
+            let ptr = unsafe { self.os.get() as *mut Value<T> };
             if ptr as usize > 1 {
-                if let Some(ref value) = (*ptr).inner.get() {
+                // SAFETY: the check ensured the pointer is safe (its destructor
+                // is not running) + it is coming from a trusted source (self).
+                if let Some(ref value) = unsafe { (*ptr).inner.get() } {
                     return Some(value);
                 }
             }
-            self.try_initialize(init)
+            // SAFETY: At this point we are sure we have no value and so
+            // initializing (or trying to) is safe.
+            unsafe { self.try_initialize(init) }
         }
 
         // `try_initialize` is only called once per os thread local variable,
         // except in corner cases where thread_local dtors reference other
         // thread_local's, or it is being recursively initialized.
         unsafe fn try_initialize(&'static self, init: fn() -> T) -> Option<&'static T> {
-            let ptr = self.os.get() as *mut Value<T>;
+            // SAFETY: No mutable references are ever handed out meaning getting
+            // the value is ok.
+            let ptr = unsafe { self.os.get() as *mut Value<T> };
             if ptr as usize == 1 {
                 // destructor is running
                 return None;
@@ -563,7 +571,11 @@ pub mod os {
                 // local copy, so do that now.
                 let ptr: Box<Value<T>> = box Value { inner: LazyKeyInner::new(), key: self };
                 let ptr = Box::into_raw(ptr);
-                self.os.set(ptr as *mut u8);
+                // SAFETY: At this point we are sure there is no value inside
+                // ptr so setting it will not affect anyone else.
+                unsafe {
+                    self.os.set(ptr as *mut u8);
+                }
                 ptr
             } else {
                 // recursive initialization