File tree Expand file tree Collapse file tree 1 file changed +29
-2
lines changed Expand file tree Collapse file tree 1 file changed +29
-2
lines changed Original file line number Diff line number Diff line change @@ -161,10 +161,37 @@ pub enum Branch<L, R> {
161
161
Right ( R )
162
162
}
163
163
164
+ impl < E , P > Drop for Chan < E , P > {
165
+ fn drop ( & mut self ) {
166
+ panic ! ( "Session channel prematurely dropped" ) ;
167
+ }
168
+ }
169
+
164
170
impl < E > Chan < E , Eps > {
165
171
/// Close a channel. Should always be used at the end of your program.
166
- pub fn close ( self ) {
167
- // Consume `c`
172
+ pub fn close ( mut self ) {
173
+ // This method cleans up the channel without running the panicky destructor
174
+ // In essence, it calls the drop glue bypassing the `Drop::drop` method
175
+ use std:: mem;
176
+
177
+ // Create some dummy values to place the real things inside
178
+ // This is safe because nobody will read these
179
+ // mem::swap uses a similar technique (also paired with `forget()`)
180
+ let mut sender = unsafe { mem:: uninitialized ( ) } ;
181
+ let mut receiver = unsafe { mem:: uninitialized ( ) } ;
182
+
183
+ // Extract the internal sender/receiver so that we can drop them
184
+ // We cannot drop directly since moving out of a type
185
+ // that implements `Drop` is disallowed
186
+ mem:: swap ( & mut self . 0 , & mut sender) ;
187
+ mem:: swap ( & mut self . 1 , & mut receiver) ;
188
+
189
+ drop ( sender) ; drop ( receiver) ; // drop them
190
+
191
+ // Ensure Chan destructors don't run so that we don't panic
192
+ // This also ensures that the uninitialized values don't get
193
+ // read at any point
194
+ mem:: forget ( self ) ;
168
195
}
169
196
}
170
197
You can’t perform that action at this time.
0 commit comments