diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index ee454312e04..502efcf9dc6 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -42,6 +42,7 @@ use result;
 use task::rt::{task_id, sched_id, rust_task};
 use util;
 use util::replace;
+use unstable::finally::Finally;
 
 #[cfg(test)] use comm::SharedChan;
 
@@ -565,51 +566,27 @@ pub fn get_scheduler() -> Scheduler {
  * ~~~
  */
 pub unsafe fn unkillable<U>(f: &fn() -> U) -> U {
-    struct AllowFailure {
-        t: *rust_task,
-        drop {
-            unsafe {
-                rt::rust_task_allow_kill(self.t);
-            }
-        }
-    }
-
-    fn AllowFailure(t: *rust_task) -> AllowFailure{
-        AllowFailure {
-            t: t
-        }
-    }
-
     unsafe {
         let t = rt::rust_get_task();
-        let _allow_failure = AllowFailure(t);
         rt::rust_task_inhibit_kill(t);
-        f()
+        do (|| {
+            f()
+        }).finally {
+            rt::rust_task_allow_kill(t);
+        }
     }
 }
 
 /// The inverse of unkillable. Only ever to be used nested in unkillable().
 pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
-    struct DisallowFailure {
-        t: *rust_task,
-        drop {
-            unsafe {
-                rt::rust_task_inhibit_kill(self.t);
-            }
-        }
-    }
-
-    fn DisallowFailure(t: *rust_task) -> DisallowFailure {
-        DisallowFailure {
-            t: t
-        }
-    }
-
     unsafe {
         let t = rt::rust_get_task();
-        let _allow_failure = DisallowFailure(t);
         rt::rust_task_allow_kill(t);
-        f()
+        do (|| {
+            f()
+        }).finally {
+            rt::rust_task_inhibit_kill(t);
+        }
     }
 }
 
@@ -618,28 +595,16 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
  * For use with exclusive ARCs, which use pthread mutexes directly.
  */
 pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
-    struct DeferInterrupts {
-        t: *rust_task,
-        drop {
-            unsafe {
-                rt::rust_task_allow_yield(self.t);
-                rt::rust_task_allow_kill(self.t);
-            }
-        }
-    }
-
-    fn DeferInterrupts(t: *rust_task) -> DeferInterrupts {
-        DeferInterrupts {
-            t: t
-        }
-    }
-
     unsafe {
         let t = rt::rust_get_task();
-        let _interrupts = DeferInterrupts(t);
         rt::rust_task_inhibit_kill(t);
         rt::rust_task_inhibit_yield(t);
-        f()
+        do (|| {
+            f()
+        }).finally {
+            rt::rust_task_allow_yield(t);
+            rt::rust_task_allow_kill(t);
+        }
     }
 }
 
diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs
index c717c1692a8..9ccce0cfe76 100644
--- a/src/libcore/unstable.rs
+++ b/src/libcore/unstable.rs
@@ -16,6 +16,7 @@ use comm::{GenericChan, GenericPort};
 use prelude::*;
 use task;
 use task::atomically;
+use self::finally::Finally;
 
 #[path = "unstable/at_exit.rs"]
 pub mod at_exit;
@@ -229,25 +230,13 @@ fn LittleLock() -> LittleLock {
 pub impl LittleLock {
     #[inline(always)]
     unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
-        struct Unlock {
-            l: rust_little_lock,
-            drop {
-                unsafe {
-                    rustrt::rust_unlock_little_lock(self.l);
-                }
-            }
-        }
-
-        fn Unlock(l: rust_little_lock) -> Unlock {
-            Unlock {
-                l: l
-            }
-        }
-
         do atomically {
             rustrt::rust_lock_little_lock(self.l);
-            let _r = Unlock(self.l);
-            f()
+            do (|| {
+                f()
+            }).finally {
+                rustrt::rust_unlock_little_lock(self.l);
+            }
         }
     }
 }