diff options
| author | Alexis Bourget <alexis.bourget@gmail.com> | 2020-07-11 00:15:24 +0200 |
|---|---|---|
| committer | Alexis Bourget <alexis.bourget@gmail.com> | 2020-09-21 22:37:30 +0200 |
| commit | a83b79ec31df3a467753c3e5b41cf457af544c7b (patch) | |
| tree | 829f38112852740dbb8cbe81597b2b18ff63e40f | |
| parent | 8c9cb06c2ec287e4b9d2bce79390b444752c3686 (diff) | |
| download | rust-a83b79ec31df3a467753c3e5b41cf457af544c7b.tar.gz rust-a83b79ec31df3a467753c3e5b41cf457af544c7b.zip | |
Finished documenting all unsafe op inside unsafe fn
| -rw-r--r-- | library/std/src/thread/local.rs | 22 |
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 |
