@@ -36,12 +36,16 @@ mod counter;
36
36
pub fn unbounded_from < T > ( queue : Queue ) -> ( Sender < T > , Receiver < T > ) {
37
37
let ( s, r) = counter:: new ( queue) ;
38
38
let s = Sender {
39
- queue : s,
40
- _phantom : PhantomData ,
39
+ flavor : SenderFlavor :: Unbounded {
40
+ queue : s,
41
+ _phantom : PhantomData ,
42
+ }
41
43
} ;
42
44
let r = Receiver {
43
- queue : r,
44
- _phantom : PhantomData ,
45
+ flavor : ReceiverFlavor :: Unbounded {
46
+ queue : r,
47
+ _phantom : PhantomData ,
48
+ }
45
49
} ;
46
50
( s, r)
47
51
}
@@ -81,8 +85,7 @@ impl<T> Message<T> {
81
85
82
86
/// The sending side of a channel.
83
87
pub struct Sender < T > {
84
- queue : counter:: Sender < Queue > ,
85
- _phantom : PhantomData < T > ,
88
+ flavor : SenderFlavor < T > ,
86
89
}
87
90
88
91
unsafe impl < T : Send > Send for Sender < T > { }
@@ -92,45 +95,67 @@ impl<T> Sender<T> {
92
95
/// Sends a message over the given channel. This will perform an alloc of the message, which
93
96
/// will have an accompanied free on the recipient side.
94
97
pub fn send ( & self , msg : T ) -> Result < ( ) , SendError < T > > {
95
- let msg = Box :: new ( Message :: new ( msg) ) ;
96
- let msg = Box :: into_raw ( msg) ;
97
- unsafe {
98
- self . queue . send ( msg as * mut c_void ) ;
98
+ match & self . flavor {
99
+ SenderFlavor :: Unbounded { queue, .. } => {
100
+ let msg = Box :: new ( Message :: new ( msg) ) ;
101
+ let msg = Box :: into_raw ( msg) ;
102
+ unsafe {
103
+ queue. send ( msg as * mut c_void ) ;
104
+ }
105
+ }
99
106
}
100
107
Ok ( ( ) )
101
108
}
102
109
}
103
110
104
111
impl < T > Drop for Sender < T > {
105
112
fn drop ( & mut self ) {
106
- unsafe {
107
- self . queue . release ( |_| {
108
- crate :: printkln!( "Release" ) ;
109
- true
110
- } )
113
+ match & self . flavor {
114
+ SenderFlavor :: Unbounded { queue, .. } => {
115
+ unsafe {
116
+ queue. release ( |_| {
117
+ crate :: printkln!( "Release" ) ;
118
+ true
119
+ } )
120
+ }
121
+ }
111
122
}
112
123
}
113
124
}
114
125
115
126
impl < T > Clone for Sender < T > {
116
127
fn clone ( & self ) -> Self {
117
- Sender {
118
- queue : self . queue . acquire ( ) ,
119
- _phantom : PhantomData ,
120
- }
128
+ let flavor = match & self . flavor {
129
+ SenderFlavor :: Unbounded { queue, .. } => {
130
+ SenderFlavor :: Unbounded {
131
+ queue : queue. acquire ( ) ,
132
+ _phantom : PhantomData ,
133
+ }
134
+ }
135
+ } ;
136
+
137
+ Sender { flavor }
138
+ }
139
+ }
140
+
141
+ /// The "flavor" of a sender. This maps to the type of channel.
142
+ enum SenderFlavor < T > {
143
+ /// An unbounded queue. Messages are allocated with Box, and sent directly.
144
+ Unbounded {
145
+ queue : counter:: Sender < Queue > ,
146
+ _phantom : PhantomData < T > ,
121
147
}
122
148
}
123
149
124
150
impl < T : fmt:: Debug > fmt:: Debug for Sender < T > {
125
151
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
126
- write ! ( f, "Sender {:?}" , * self . queue )
152
+ write ! ( f, "Sender" )
127
153
}
128
154
}
129
155
130
156
/// The receiving side of a channel.
131
157
pub struct Receiver < T > {
132
- queue : counter:: Receiver < Queue > ,
133
- _phantom : PhantomData < T > ,
158
+ flavor : ReceiverFlavor < T > ,
134
159
}
135
160
136
161
unsafe impl < T : Send > Send for Receiver < T > { }
@@ -144,38 +169,61 @@ impl<T> Receiver<T> {
144
169
/// operation can proceed. If the channel is empty and becomes disconnected, this call will
145
170
/// wake up and return an error.
146
171
pub fn recv ( & self ) -> Result < T , RecvError > {
147
- let msg = unsafe {
148
- self . queue . recv ( )
149
- } ;
150
- let msg = msg as * mut Message < T > ;
151
- let msg = unsafe { Box :: from_raw ( msg) } ;
152
- Ok ( msg. data )
172
+ match & self . flavor {
173
+ ReceiverFlavor :: Unbounded { queue, .. } => {
174
+ let msg = unsafe {
175
+ queue. recv ( )
176
+ } ;
177
+ let msg = msg as * mut Message < T > ;
178
+ let msg = unsafe { Box :: from_raw ( msg) } ;
179
+ Ok ( msg. data )
180
+ }
181
+ }
153
182
}
154
183
}
155
184
156
185
impl < T > Drop for Receiver < T > {
157
186
fn drop ( & mut self ) {
158
- unsafe {
159
- self . queue . release ( |_| {
160
- crate :: printkln!( "Release" ) ;
161
- true
162
- } )
187
+ match & self . flavor {
188
+ ReceiverFlavor :: Unbounded { queue, .. } => {
189
+ unsafe {
190
+ queue. release ( |_| {
191
+ crate :: printkln!( "Release" ) ;
192
+ true
193
+ } )
194
+ }
195
+ }
163
196
}
164
197
}
165
198
}
166
199
167
200
impl < T > Clone for Receiver < T > {
168
201
fn clone ( & self ) -> Self {
169
- Receiver {
170
- queue : self . queue . acquire ( ) ,
171
- _phantom : PhantomData ,
172
- }
202
+ let flavor = match & self . flavor {
203
+ ReceiverFlavor :: Unbounded { queue, .. } => {
204
+ ReceiverFlavor :: Unbounded {
205
+ queue : queue. acquire ( ) ,
206
+ _phantom : PhantomData ,
207
+ }
208
+ }
209
+ } ;
210
+
211
+ Receiver { flavor }
173
212
}
174
213
}
175
214
176
215
impl < T > fmt:: Debug for Receiver < T > {
177
216
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
178
- write ! ( f, "Sender {:?}" , * self . queue)
217
+ write ! ( f, "Sender" )
218
+ }
219
+ }
220
+
221
+ /// The "flavor" of a receiver. This maps to the type of the channel.
222
+ enum ReceiverFlavor < T > {
223
+ /// An unbounded queue. Messages were allocated with Box, and will be freed upon receipt.
224
+ Unbounded {
225
+ queue : counter:: Receiver < Queue > ,
226
+ _phantom : PhantomData < T > ,
179
227
}
180
228
}
181
229
0 commit comments