@@ -170,85 +170,6 @@ Foreign libraries often hand off ownership of resources to the calling code.
170
170
When this occurs, we must use Rust's destructors to provide safety and guarantee
171
171
the release of these resources (especially in the case of failure).
172
172
173
- As an example, we give a reimplementation of owned boxes by wrapping ` malloc `
174
- and ` free ` :
175
-
176
- ~~~~
177
- use std::cast;
178
- use std::libc::{c_void, size_t, malloc, free};
179
- use std::mem;
180
- use std::ptr;
181
-
182
- // Define a wrapper around the handle returned by the foreign code.
183
- // Unique<T> has the same semantics as ~T
184
- pub struct Unique<T> {
185
- // It contains a single raw, mutable pointer to the object in question.
186
- priv ptr: *mut T
187
- }
188
-
189
- // Implement methods for creating and using the values in the box.
190
- // NB: For simplicity and correctness, we require that T has kind Send
191
- // (owned boxes relax this restriction, and can contain managed (GC) boxes).
192
- // This is because, as implemented, the garbage collector would not know
193
- // about any shared boxes stored in the malloc'd region of memory.
194
- impl<T: Send> Unique<T> {
195
- pub fn new(value: T) -> Unique<T> {
196
- unsafe {
197
- let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
198
- assert!(!ptr.is_null());
199
- // `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
200
- // move_val_init moves a value into this memory without
201
- // attempting to drop the original value.
202
- mem::move_val_init(&mut *ptr, value);
203
- Unique{ptr: ptr}
204
- }
205
- }
206
-
207
- // the 'r lifetime results in the same semantics as `&*x` with ~T
208
- pub fn borrow<'r>(&'r self) -> &'r T {
209
- unsafe { cast::copy_lifetime(self, &*self.ptr) }
210
- }
211
-
212
- // the 'r lifetime results in the same semantics as `&mut *x` with ~T
213
- pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
214
- unsafe { cast::copy_mut_lifetime(self, &mut *self.ptr) }
215
- }
216
- }
217
-
218
- // The key ingredient for safety, we associate a destructor with
219
- // Unique<T>, making the struct manage the raw pointer: when the
220
- // struct goes out of scope, it will automatically free the raw pointer.
221
- // NB: This is an unsafe destructor, because rustc will not normally
222
- // allow destructors to be associated with parametrized types, due to
223
- // bad interaction with managed boxes. (With the Send restriction,
224
- // we don't have this problem.)
225
- #[unsafe_destructor]
226
- impl<T: Send> Drop for Unique<T> {
227
- fn drop(&mut self) {
228
- unsafe {
229
- let x = mem::uninit(); // dummy value to swap in
230
- // We need to move the object out of the box, so that
231
- // the destructor is called (at the end of this scope.)
232
- ptr::replace(self.ptr, x);
233
- free(self.ptr as *mut c_void)
234
- }
235
- }
236
- }
237
-
238
- // A comparison between the built-in ~ and this reimplementation
239
- fn main() {
240
- {
241
- let mut x = ~5;
242
- *x = 10;
243
- } // `x` is freed here
244
-
245
- {
246
- let mut y = Unique::new(5);
247
- *y.borrow_mut() = 10;
248
- } // `y` is freed here
249
- }
250
- ~~~~
251
-
252
173
# Callbacks from C code to Rust functions
253
174
254
175
Some external libraries require the usage of callbacks to report back their
0 commit comments