@@ -139,6 +139,74 @@ pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
139
139
For reference, the examples used here are also available as an [ library on
140
140
GitHub] ( https://github.com/thestinger/rust-snappy ) .
141
141
142
+ # Destructors
143
+
144
+ Foreign libraries often hand off ownership of resources to the calling code,
145
+ which should be wrapped in a destructor to provide safety and guarantee their
146
+ release.
147
+
148
+ A type with the same functionality as owned boxes can be implemented by
149
+ wrapping ` malloc ` and ` free ` :
150
+
151
+ ~~~~
152
+ use core::libc::{c_void, size_t, malloc, free};
153
+
154
+ #[abi = "rust-intrinsic"]
155
+ extern "rust-intrinsic" mod rusti {
156
+ fn init<T>() -> T;
157
+ }
158
+
159
+ // a wrapper around the handle returned by the foreign code
160
+ pub struct Unique<T> {
161
+ priv ptr: *mut T
162
+ }
163
+
164
+ pub impl<'self, T: Owned> Unique<T> {
165
+ fn new(value: T) -> Unique<T> {
166
+ unsafe {
167
+ let ptr = malloc(core::sys::size_of::<T>() as size_t) as *mut T;
168
+ assert!(!ptr::is_null(ptr));
169
+ *ptr = value;
170
+ Unique{ptr: ptr}
171
+ }
172
+ }
173
+
174
+ // the 'self lifetime results in the same semantics as `&*x` with ~T
175
+ fn borrow(&self) -> &'self T {
176
+ unsafe { cast::transmute(self.ptr) }
177
+ }
178
+
179
+ // the 'self lifetime results in the same semantics as `&mut *x` with ~T
180
+ fn borrow_mut(&mut self) -> &'self mut T {
181
+ unsafe { cast::transmute(self.ptr) }
182
+ }
183
+ }
184
+
185
+ #[unsafe_destructor]
186
+ impl<T: Owned> Drop for Unique<T> {
187
+ fn finalize(&self) {
188
+ unsafe {
189
+ let mut x = rusti::init(); // dummy value to swap in
190
+ x <-> *self.ptr; // moving the object out is needed to call the destructor
191
+ free(self.ptr as *c_void)
192
+ }
193
+ }
194
+ }
195
+
196
+ // A comparison between the built-in ~ and this reimplementation
197
+ fn main() {
198
+ {
199
+ let mut x = ~5;
200
+ *x = 10;
201
+ } // `x` is freed here
202
+
203
+ {
204
+ let mut y = Unique::new(5);
205
+ *y.borrow_mut() = 10;
206
+ } // `y` is freed here
207
+ }
208
+ ~~~~
209
+
142
210
# Linking
143
211
144
212
In addition to the ` #[link_args] ` attribute for explicitly passing arguments to the linker, an
0 commit comments