58
58
59
59
use core:: prelude:: * ;
60
60
61
- use core:: cell:: Cell ;
61
+ use core:: cell:: { Cell , UnsafeCell } ;
62
62
use core:: marker;
63
63
use core:: mem;
64
64
use core:: ptr;
@@ -70,9 +70,13 @@ use sync::mpsc::blocking::{self, SignalToken};
70
70
/// The "receiver set" of the select interface. This structure is used to manage
71
71
/// a set of receivers which are being selected over.
72
72
pub struct Select {
73
+ inner : UnsafeCell < SelectInner > ,
74
+ next_id : Cell < usize > ,
75
+ }
76
+
77
+ struct SelectInner {
73
78
head : * mut Handle < ' static , ( ) > ,
74
79
tail : * mut Handle < ' static , ( ) > ,
75
- next_id : Cell < usize > ,
76
80
}
77
81
78
82
impl !marker:: Send for Select { }
@@ -84,7 +88,7 @@ pub struct Handle<'rx, T:Send+'rx> {
84
88
/// The ID of this handle, used to compare against the return value of
85
89
/// `Select::wait()`
86
90
id : usize ,
87
- selector : & ' rx Select ,
91
+ selector : * mut SelectInner ,
88
92
next : * mut Handle < ' static , ( ) > ,
89
93
prev : * mut Handle < ' static , ( ) > ,
90
94
added : bool ,
@@ -127,8 +131,10 @@ impl Select {
127
131
/// ```
128
132
pub fn new ( ) -> Select {
129
133
Select {
130
- head : ptr:: null_mut ( ) ,
131
- tail : ptr:: null_mut ( ) ,
134
+ inner : UnsafeCell :: new ( SelectInner {
135
+ head : ptr:: null_mut ( ) ,
136
+ tail : ptr:: null_mut ( ) ,
137
+ } ) ,
132
138
next_id : Cell :: new ( 1 ) ,
133
139
}
134
140
}
@@ -141,7 +147,7 @@ impl Select {
141
147
self . next_id . set ( id + 1 ) ;
142
148
Handle {
143
149
id : id,
144
- selector : self ,
150
+ selector : self . inner . get ( ) ,
145
151
next : ptr:: null_mut ( ) ,
146
152
prev : ptr:: null_mut ( ) ,
147
153
added : false ,
@@ -250,7 +256,7 @@ impl Select {
250
256
}
251
257
}
252
258
253
- fn iter ( & self ) -> Packets { Packets { cur : self . head } }
259
+ fn iter ( & self ) -> Packets { Packets { cur : unsafe { & * self . inner . get ( ) } . head } }
254
260
}
255
261
256
262
impl < ' rx , T : Send > Handle < ' rx , T > {
@@ -271,7 +277,7 @@ impl<'rx, T: Send> Handle<'rx, T> {
271
277
/// while it is added to the `Select` set.
272
278
pub unsafe fn add ( & mut self ) {
273
279
if self . added { return }
274
- let selector: & mut Select = mem :: transmute ( & * self . selector ) ;
280
+ let selector = & mut * self . selector ;
275
281
let me: * mut Handle < ' static , ( ) > = mem:: transmute ( & * self ) ;
276
282
277
283
if selector. head . is_null ( ) {
@@ -292,7 +298,7 @@ impl<'rx, T: Send> Handle<'rx, T> {
292
298
pub unsafe fn remove ( & mut self ) {
293
299
if !self . added { return }
294
300
295
- let selector: & mut Select = mem :: transmute ( & * self . selector ) ;
301
+ let selector = & mut * self . selector ;
296
302
let me: * mut Handle < ' static , ( ) > = mem:: transmute ( & * self ) ;
297
303
298
304
if self . prev . is_null ( ) {
@@ -317,8 +323,10 @@ impl<'rx, T: Send> Handle<'rx, T> {
317
323
318
324
impl Drop for Select {
319
325
fn drop ( & mut self ) {
320
- assert ! ( self . head. is_null( ) ) ;
321
- assert ! ( self . tail. is_null( ) ) ;
326
+ unsafe {
327
+ assert ! ( ( & * self . inner. get( ) ) . head. is_null( ) ) ;
328
+ assert ! ( ( & * self . inner. get( ) ) . tail. is_null( ) ) ;
329
+ }
322
330
}
323
331
}
324
332
0 commit comments