about summary refs log tree commit diff
path: root/src/libstd/rt/local_ptr.rs
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-12-03 19:18:58 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-12-10 15:13:12 -0800
commit7cac9fe76349120ea2373f3ce47a561271b5e8b6 (patch)
tree495b1694a3fa4b84ede3f962b24e703363d64d80 /src/libstd/rt/local_ptr.rs
parent786dea207d5b891d37e596e96dd2f84c4cb59f49 (diff)
downloadrust-7cac9fe76349120ea2373f3ce47a561271b5e8b6.tar.gz
rust-7cac9fe76349120ea2373f3ce47a561271b5e8b6.zip
librustuv: RAII-ify `Local::borrow`, and remove some 12 Cells.
Diffstat (limited to 'src/libstd/rt/local_ptr.rs')
-rw-r--r--src/libstd/rt/local_ptr.rs47
1 files changed, 37 insertions, 10 deletions
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
index be3b5f951eb..66fe9742121 100644
--- a/src/libstd/rt/local_ptr.rs
+++ b/src/libstd/rt/local_ptr.rs
@@ -18,8 +18,7 @@
 #[allow(dead_code)];
 
 use cast;
-use cell::Cell;
-use unstable::finally::Finally;
+use ops::Drop;
 
 #[cfg(windows)]               // mingw-w32 doesn't like thread_local things
 #[cfg(target_os = "android")] // see #10686
@@ -28,20 +27,48 @@ pub use self::native::*;
 #[cfg(not(windows), not(target_os = "android"))]
 pub use self::compiled::*;
 
+/// Encapsulates a borrowed value. When this value goes out of scope, the
+/// pointer is returned.
+pub struct Borrowed<T> {
+    priv val: *(),
+}
+
+#[unsafe_destructor]
+impl<T> Drop for Borrowed<T> {
+    fn drop(&mut self) {
+        unsafe {
+            if self.val.is_null() {
+                rtabort!("Aiee, returning null borrowed object!");
+            }
+            let val: ~T = cast::transmute(self.val);
+            put::<T>(val);
+            assert!(exists());
+        }
+    }
+}
+
+impl<T> Borrowed<T> {
+    pub fn get<'a>(&'a mut self) -> &'a mut T {
+        unsafe {
+            let val_ptr: &mut ~T = cast::transmute(&mut self.val);
+            let val_ptr: &'a mut T = *val_ptr;
+            val_ptr
+        }
+    }
+}
+
 /// Borrow the thread-local value from thread-local storage.
 /// While the value is borrowed it is not available in TLS.
 ///
 /// # Safety note
 ///
 /// Does not validate the pointer type.
-pub unsafe fn borrow<T>(f: |&mut T|) {
-    let mut value = take();
-
-    // XXX: Need a different abstraction from 'finally' here to avoid unsafety
-    let unsafe_ptr = cast::transmute_mut_region(&mut *value);
-    let value_cell = Cell::new(value);
-
-    (|| f(unsafe_ptr)).finally(|| put(value_cell.take()));
+#[inline]
+pub unsafe fn borrow<T>() -> Borrowed<T> {
+    let val: *() = cast::transmute(take::<T>());
+    Borrowed {
+        val: val,
+    }
 }
 
 /// Compiled implementation of accessing the runtime local pointer. This is