18
18
use std:: kinds:: marker;
19
19
use std:: mem;
20
20
use std:: sync:: atomics;
21
+ use std:: ty:: Unsafe ;
21
22
use std:: finally:: Finally ;
22
23
23
24
use mutex;
@@ -85,11 +86,8 @@ struct Sem<Q> {
85
86
// n.b, we need Sem to be `Share`, but the WaitQueue type is not send/share
86
87
// (for good reason). We have an internal invariant on this semaphore,
87
88
// 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 > >
93
91
}
94
92
95
93
struct SemInner < Q > {
@@ -107,22 +105,20 @@ struct SemGuard<'a, Q> {
107
105
108
106
impl < Q : Send > Sem < Q > {
109
107
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 {
112
111
waiters : WaitQueue :: new ( ) ,
113
112
count : count,
114
113
blocked : q,
115
114
} )
116
- } ;
117
- Sem {
118
- lock : mutex:: Mutex :: new ( ) ,
119
- inner : inner,
120
115
}
121
116
}
122
117
123
118
unsafe fn with ( & self , f: |& mut SemInner < Q > |) {
124
119
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 ( ) )
126
122
}
127
123
128
124
pub fn acquire ( & self ) {
@@ -163,16 +159,6 @@ impl<Q: Send> Sem<Q> {
163
159
}
164
160
}
165
161
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
-
176
162
#[ unsafe_destructor]
177
163
impl < ' a , Q : Send > Drop for SemGuard < ' a , Q > {
178
164
fn drop ( & mut self ) {
0 commit comments