about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2015-02-10 10:04:39 +0100
committerFelix S. Klock II <pnkfelix@pnkfx.org>2015-03-26 14:08:54 +0100
commit3902190ac4d64962b2c1ac9a6ae88777b7112f82 (patch)
tree61759f62fbca6a1e9c25e3e95dd1d957340510df /src/liballoc
parent1501f33e76f6f9621aa08fb0cbbc5f85a5ac7f0f (diff)
downloadrust-3902190ac4d64962b2c1ac9a6ae88777b7112f82.tar.gz
rust-3902190ac4d64962b2c1ac9a6ae88777b7112f82.zip
Switch drop-flag to `u8` to allow special tags to instrument state.
Refactored code so that the drop-flag values for initialized
(`DTOR_NEEDED`) versus dropped (`DTOR_DONE`) are given explicit names.

Add `mem::dropped()` (which with `DTOR_DONE == 0` is semantically the
same as `mem::zeroed`, but the point is that it abstracts away from
the particular choice of value for `DTOR_DONE`).

Filling-drop needs to use something other than `ptr::read_and_zero`,
so I added such a function: `ptr::read_and_drop`.  But, libraries
should not use it if they can otherwise avoid it.

Fixes to tests to accommodate filling-drop.
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/arc.rs5
-rw-r--r--src/liballoc/rc.rs6
2 files changed, 6 insertions, 5 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index b5d16d29272..e107d19a87c 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -354,7 +354,8 @@ impl<T> Drop for Arc<T> {
         // more than once (but it is guaranteed to be zeroed after the first if
         // it's run more than once)
         let ptr = *self._ptr;
-        if ptr.is_null() { return }
+        // if ptr.is_null() { return }
+        if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return }
 
         // Because `fetch_sub` is already atomic, we do not need to synchronize
         // with other threads unless we are going to delete the object. This
@@ -485,7 +486,7 @@ impl<T> Drop for Weak<T> {
         let ptr = *self._ptr;
 
         // see comments above for why this check is here
-        if ptr.is_null() { return }
+        if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return }
 
         // If we find out that we were the last weak pointer, then its time to
         // deallocate the data entirely. See the discussion in Arc::drop() about
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index eb3c5c16726..e0d7e32ecf5 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -160,7 +160,7 @@ use core::default::Default;
 use core::fmt;
 use core::hash::{Hasher, Hash};
 use core::marker;
-use core::mem::{min_align_of, size_of, forget};
+use core::mem::{self, min_align_of, size_of, forget};
 use core::nonzero::NonZero;
 use core::ops::{Deref, Drop};
 use core::option::Option;
@@ -407,7 +407,7 @@ impl<T> Drop for Rc<T> {
     fn drop(&mut self) {
         unsafe {
             let ptr = *self._ptr;
-            if !ptr.is_null() {
+            if !ptr.is_null() && ptr as usize != mem::POST_DROP_USIZE {
                 self.dec_strong();
                 if self.strong() == 0 {
                     ptr::read(&**self); // destroy the contained object
@@ -718,7 +718,7 @@ impl<T> Drop for Weak<T> {
     fn drop(&mut self) {
         unsafe {
             let ptr = *self._ptr;
-            if !ptr.is_null() {
+            if !ptr.is_null() && ptr as usize != mem::POST_DROP_USIZE {
                 self.dec_weak();
                 // the weak count starts at 1, and will only go to zero if all
                 // the strong pointers have disappeared.