1818use std:: kinds:: marker;
1919use std:: mem;
2020use std:: sync:: atomics;
21+ use std:: ty:: Unsafe ;
2122use std:: finally:: Finally ;
2223
2324use mutex;
@@ -85,11 +86,8 @@ struct Sem<Q> {
8586 // n.b, we need Sem to be `Share`, but the WaitQueue type is not send/share
8687 // (for good reason). We have an internal invariant on this semaphore,
8788 // however, that the queue is never accessed outside of a locked
88- // context. For this reason, we shove these behind a pointer which will
89- // be inferred to be `Share`.
90- //
91- // FIXME: this requires an extra allocation, which is bad.
92- inner : * ( )
89+ // context.
90+ inner : Unsafe < SemInner < Q > >
9391}
9492
9593struct SemInner < Q > {
@@ -107,22 +105,20 @@ struct SemGuard<'a, Q> {
107105
108106impl < Q : Send > Sem < Q > {
109107 fn new ( count : int , q : Q ) -> Sem < Q > {
110- let inner = unsafe {
111- mem:: transmute ( box SemInner {
108+ Sem {
109+ lock : mutex:: Mutex :: new ( ) ,
110+ inner : Unsafe :: new ( SemInner {
112111 waiters : WaitQueue :: new ( ) ,
113112 count : count,
114113 blocked : q,
115114 } )
116- } ;
117- Sem {
118- lock : mutex:: Mutex :: new ( ) ,
119- inner : inner,
120115 }
121116 }
122117
123118 unsafe fn with ( & self , f: |& mut SemInner < Q > |) {
124119 let _g = self . lock . lock ( ) ;
125- f ( & mut * ( self . inner as * mut SemInner < Q > ) )
120+ // This &mut is safe because, due to the lock, we are the only one who can touch the data
121+ f ( & mut * self . inner . get ( ) )
126122 }
127123
128124 pub fn acquire ( & self ) {
@@ -163,16 +159,6 @@ impl<Q: Send> Sem<Q> {
163159 }
164160}
165161
166- #[ unsafe_destructor]
167- impl < Q : Send > Drop for Sem < Q > {
168- fn drop ( & mut self ) {
169- let _waiters: Box < SemInner < Q > > = unsafe {
170- mem:: transmute ( self . inner )
171- } ;
172- self . inner = 0 as * ( ) ;
173- }
174- }
175-
176162#[ unsafe_destructor]
177163impl < ' a , Q : Send > Drop for SemGuard < ' a , Q > {
178164 fn drop ( & mut self ) {
0 commit comments