about summary refs log tree commit diff
path: root/src/libsync
diff options
context:
space:
mode:
authorJonathan S <gereeter@gmail.com>2014-06-06 15:24:14 -0500
committerJonathan S <gereeter@gmail.com>2014-06-06 15:24:14 -0500
commitf2f1991c81825b542f77b4e4f2ac65d24a063a9c (patch)
tree71c3fe1cdf55293ee29d6840ab786fcb9d564c5d /src/libsync
parent566b7b93c6ca2c034f110fa670040de1a09195e4 (diff)
downloadrust-f2f1991c81825b542f77b4e4f2ac65d24a063a9c.tar.gz
rust-f2f1991c81825b542f77b4e4f2ac65d24a063a9c.zip
Make sync::raw::Sem use Unsafe to manage mutability instead of transmuting an unsafe pointer
Diffstat (limited to 'src/libsync')
-rw-r--r--src/libsync/raw.rs30
1 files changed, 8 insertions, 22 deletions
diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs
index aae790f887a..8fd10cdfa8b 100644
--- a/src/libsync/raw.rs
+++ b/src/libsync/raw.rs
@@ -18,6 +18,7 @@
 use std::kinds::marker;
 use std::mem;
 use std::sync::atomics;
+use std::ty::Unsafe;
 use std::finally::Finally;
 
 use mutex;
@@ -85,11 +86,8 @@ struct Sem<Q> {
     // n.b, we need Sem to be `Share`, but the WaitQueue type is not send/share
     //      (for good reason). We have an internal invariant on this semaphore,
     //      however, that the queue is never accessed outside of a locked
-    //      context. For this reason, we shove these behind a pointer which will
-    //      be inferred to be `Share`.
-    //
-    // FIXME: this requires an extra allocation, which is bad.
-    inner: *()
+    //      context.
+    inner: Unsafe<SemInner<Q>>
 }
 
 struct SemInner<Q> {
@@ -107,22 +105,20 @@ struct SemGuard<'a, Q> {
 
 impl<Q: Send> Sem<Q> {
     fn new(count: int, q: Q) -> Sem<Q> {
-        let inner = unsafe {
-            mem::transmute(box SemInner {
+        Sem {
+            lock: mutex::Mutex::new(),
+            inner: Unsafe::new(SemInner {
                 waiters: WaitQueue::new(),
                 count: count,
                 blocked: q,
             })
-        };
-        Sem {
-            lock: mutex::Mutex::new(),
-            inner: inner,
         }
     }
 
     unsafe fn with(&self, f: |&mut SemInner<Q>|) {
         let _g = self.lock.lock();
-        f(&mut *(self.inner as *mut SemInner<Q>))
+        // This &mut is safe because, due to the lock, we are the only one who can touch the data
+        f(&mut *self.inner.get())
     }
 
     pub fn acquire(&self) {
@@ -164,16 +160,6 @@ impl<Q: Send> Sem<Q> {
 }
 
 #[unsafe_destructor]
-impl<Q: Send> Drop for Sem<Q> {
-    fn drop(&mut self) {
-        let _waiters: Box<SemInner<Q>> = unsafe {
-            mem::transmute(self.inner)
-        };
-        self.inner = 0 as *();
-    }
-}
-
-#[unsafe_destructor]
 impl<'a, Q: Send> Drop for SemGuard<'a, Q> {
     fn drop(&mut self) {
         self.sem.release();