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 { // 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> } struct SemInner { @@ -107,22 +105,20 @@ struct SemGuard<'a, Q> { impl Sem { fn new(count: int, q: Q) -> Sem { - 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|) { let _g = self.lock.lock(); - f(&mut *(self.inner as *mut SemInner)) + // 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) { @@ -163,16 +159,6 @@ impl Sem { } } -#[unsafe_destructor] -impl Drop for Sem { - fn drop(&mut self) { - let _waiters: Box> = unsafe { - mem::transmute(self.inner) - }; - self.inner = 0 as *(); - } -} - #[unsafe_destructor] impl<'a, Q: Send> Drop for SemGuard<'a, Q> { fn drop(&mut self) {