]> git.lizzy.rs Git - rust.git/commitdiff
librustuv: RAII-ify `Local::borrow`, and remove some 12 Cells.
authorPatrick Walton <pcwalton@mimiga.net>
Wed, 4 Dec 2013 03:18:58 +0000 (19:18 -0800)
committerPatrick Walton <pcwalton@mimiga.net>
Tue, 10 Dec 2013 23:13:12 +0000 (15:13 -0800)
14 files changed:
src/librustuv/lib.rs
src/librustuv/macros.rs
src/librustuv/net.rs
src/librustuv/uvio.rs
src/libstd/at_vec.rs
src/libstd/rt/borrowck.rs
src/libstd/rt/comm.rs
src/libstd/rt/local.rs
src/libstd/rt/local_heap.rs
src/libstd/rt/local_ptr.rs
src/libstd/rt/sched.rs
src/libstd/rt/task.rs
src/libstd/rt/tube.rs
src/libstd/task/mod.rs

index ad1c53e97397fd1844bef5d96a399d1ae37ac411..09a13bdddaa841e70accea6e0199f369c9dd433e 100644 (file)
@@ -162,16 +162,20 @@ pub struct ForbidSwitch {
 
 impl ForbidSwitch {
     fn new(s: &'static str) -> ForbidSwitch {
+        let mut sched = Local::borrow(None::<Scheduler>);
         ForbidSwitch {
-            msg: s, sched: Local::borrow(|s: &mut Scheduler| s.sched_id())
+            msg: s,
+            sched: sched.get().sched_id(),
         }
     }
 }
 
 impl Drop for ForbidSwitch {
     fn drop(&mut self) {
-        assert!(self.sched == Local::borrow(|s: &mut Scheduler| s.sched_id()),
-                "didnt want a scheduler switch: {}", self.msg);
+        let mut sched = Local::borrow(None::<Scheduler>);
+        assert!(self.sched == sched.get().sched_id(),
+                "didnt want a scheduler switch: {}",
+                self.msg);
     }
 }
 
@@ -389,15 +393,16 @@ pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
 #[cfg(test)]
 fn local_loop() -> &'static mut Loop {
     unsafe {
-        cast::transmute(Local::borrow(|sched: &mut Scheduler| {
+        cast::transmute({
+            let mut sched = Local::borrow(None::<Scheduler>);
             let mut io = None;
-            sched.event_loop.io(|i| {
+            sched.get().event_loop.io(|i| {
                 let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) =
                     cast::transmute(i);
                 io = Some(uvio);
             });
             io.unwrap()
-        }).uv_loop())
+        }.uv_loop())
     }
 }
 
index eb679553e7642eead29e45ec84ff089bcbab83b7..a63dcc6de3105c97f7a196b7024cfc2d13735288 100644 (file)
@@ -29,7 +29,10 @@ macro_rules! uvdebug (
 
 // get a handle for the current scheduler
 macro_rules! get_handle_to_current_scheduler(
-    () => (Local::borrow(|sched: &mut Scheduler| sched.make_handle()))
+    () => ({
+        let mut sched = Local::borrow(None::<Scheduler>);
+        sched.get().make_handle()
+    })
 )
 
 pub fn dumb_println(args: &fmt::Arguments) {
index 1af0266f16a81bbb8b5205acf269e4c7e3d19153..1e9c40443458c3199eefb16c554bc298cc9a03d3 100644 (file)
@@ -1080,11 +1080,10 @@ fn test_simple_homed_udp_io_bind_then_move_task_then_home_and_close() {
             };
 
             unsafe fn local_io() -> &'static mut IoFactory {
-                Local::borrow(|sched: &mut Scheduler| {
-                    let mut io = None;
-                    sched.event_loop.io(|i| io = Some(i));
-                    cast::transmute(io.unwrap())
-                })
+                let mut sched = Local::borrow(None::<Scheduler>);
+                let mut io = None;
+                sched.get().event_loop.io(|i| io = Some(i));
+                cast::transmute(io.unwrap())
             }
 
             let test_function: proc() = proc() {
index 8d80f5ff61034db0f72955f0e0cac81d981d2ff0..c0d7a35cef8a882d9907b517464c7e4c798b2416 100644 (file)
@@ -45,9 +45,10 @@ fn go_to_IO_home(&mut self) -> uint {
 
         let _f = ForbidUnwind::new("going home");
 
-        let current_sched_id = Local::borrow(|sched: &mut Scheduler| {
-            sched.sched_id()
-        });
+        let current_sched_id = {
+            let mut sched = Local::borrow(None::<Scheduler>);
+            sched.get().sched_id()
+        };
 
         // Only need to invoke a context switch if we're not on the right
         // scheduler.
@@ -59,9 +60,10 @@ fn go_to_IO_home(&mut self) -> uint {
                 });
             })
         }
-        let current_sched_id = Local::borrow(|sched: &mut Scheduler| {
-            sched.sched_id()
-        });
+        let current_sched_id = {
+            let mut sched = Local::borrow(None::<Scheduler>);
+            sched.get().sched_id()
+        };
         assert!(current_sched_id == self.home().sched_id);
 
         self.home().sched_id
@@ -96,7 +98,8 @@ struct HomingMissile {
 
 impl HomingMissile {
     pub fn check(&self, msg: &'static str) {
-        let local_id = Local::borrow(|sched: &mut Scheduler| sched.sched_id());
+        let mut sched = Local::borrow(None::<Scheduler>);
+        let local_id = sched.get().sched_id();
         assert!(local_id == self.io_home, "{}", msg);
     }
 }
index 2b105a3fa7d2375bf593740beeedecd7f2ba0f6d..2b64c5c83fbda276edf76392023491f4292a5c02 100644 (file)
@@ -169,6 +169,7 @@ pub mod raw {
     use at_vec::capacity;
     use cast;
     use cast::{transmute, transmute_copy};
+    use option::None;
     use ptr;
     use mem;
     use uint;
@@ -259,9 +260,8 @@ fn local_realloc(ptr: *(), size: uint) -> *() {
             use rt::local::Local;
             use rt::task::Task;
 
-            Local::borrow(|task: &mut Task| {
-                task.heap.realloc(ptr as *mut Box<()>, size) as *()
-            })
+            let mut task = Local::borrow(None::<Task>);
+            task.get().heap.realloc(ptr as *mut Box<()>, size) as *()
         }
     }
 
index 30c2264bd869790afa919e109ce568d1cdf4c9e2..82f92bdb803e4c46271493ba687dacc8b933db85 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use cell::Cell;
 use c_str::{ToCStr, CString};
 use libc::{c_char, size_t};
 use option::{Option, None, Some};
@@ -35,7 +34,8 @@ pub struct BorrowRecord {
 }
 
 fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
-    Local::borrow(|task: &mut Task| task.borrow_list.take())
+    let mut task = Local::borrow(None::<Task>);
+    task.get().borrow_list.take()
 }
 
 fn swap_task_borrow_list(f: |~[BorrowRecord]| -> ~[BorrowRecord]) {
@@ -44,8 +44,9 @@ fn swap_task_borrow_list(f: |~[BorrowRecord]| -> ~[BorrowRecord]) {
         None => ~[]
     };
     let borrows = f(borrows);
-    let borrows = Cell::new(borrows);
-    Local::borrow(|task: &mut Task| task.borrow_list = Some(borrows.take()))
+
+    let mut task = Local::borrow(None::<Task>);
+    task.get().borrow_list = Some(borrows)
 }
 
 pub fn clear_task_borrow_list() {
index 1b5303e76c953e27edd480e2359b4f8841d46b37..d6024b7abea433dda041b11ed50186525fb6ccfe 100644 (file)
@@ -25,7 +25,7 @@
 use util;
 use util::Void;
 use comm::{GenericChan, GenericSmartChan, GenericPort, Peekable, SendDeferred};
-use cell::{Cell, RefCell};
+use cell::RefCell;
 use clone::Clone;
 use tuple::ImmutableTuple;
 
@@ -169,10 +169,8 @@ fn try_send_inner(mut self, val: T, do_resched: bool) -> bool {
                             Scheduler::run_task(woken_task);
                         });
                     } else {
-                        let recvr = Cell::new(recvr);
-                        Local::borrow(|sched: &mut Scheduler| {
-                            sched.enqueue_blocked_task(recvr.take());
-                        })
+                        let mut sched = Local::borrow(None::<Scheduler>);
+                        sched.get().enqueue_blocked_task(recvr);
                     }
                 }
             }
@@ -230,9 +228,8 @@ fn optimistic_check(&mut self) -> bool {
         // The optimistic check is never necessary for correctness. For testing
         // purposes, making it randomly return false simulates a racing sender.
         use rand::{Rand};
-        let actually_check = Local::borrow(|sched: &mut Scheduler| {
-            Rand::rand(&mut sched.rng)
-        });
+        let mut sched = Local::borrow(None::<Scheduler>);
+        let actually_check = Rand::rand(&mut sched.get().rng);
         if actually_check {
             unsafe { (*self.packet()).state.load(Acquire) == STATE_ONE }
         } else {
index 2375ce55766806969d633145e7449406a4505f80..d73ad98a25b37ead1637d8d0b9b8343abb51672c 100644 (file)
 use rt::sched::Scheduler;
 use rt::task::Task;
 use rt::local_ptr;
-use cell::Cell;
 
-pub trait Local {
+/// Encapsulates some task-local data.
+pub trait Local<Borrowed> {
     fn put(value: ~Self);
     fn take() -> ~Self;
     fn exists(unused_value: Option<Self>) -> bool;
-    fn borrow<T>(f: |&mut Self| -> T) -> T;
+    fn borrow(unused_value: Option<Self>) -> Borrowed;
     unsafe fn unsafe_take() -> ~Self;
     unsafe fn unsafe_borrow() -> *mut Self;
     unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
 }
 
-impl Local for Task {
+impl Local<local_ptr::Borrowed<Task>> for Task {
     #[inline]
     fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
     #[inline]
     fn take() -> ~Task { unsafe { local_ptr::take() } }
     fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
-    fn borrow<T>(f: |&mut Task| -> T) -> T {
-        let mut res: Option<T> = None;
-        let res_ptr: *mut Option<T> = &mut res;
+    #[inline]
+    fn borrow(_: Option<Task>) -> local_ptr::Borrowed<Task> {
         unsafe {
-            local_ptr::borrow(|task| {
-                let result = f(task);
-                *res_ptr = Some(result);
-            })
-        }
-        match res {
-            Some(r) => { r }
-            None => { rtabort!("function failed in local_borrow") }
+            local_ptr::borrow::<Task>()
         }
     }
     #[inline]
@@ -54,13 +46,35 @@ unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
     }
 }
 
-impl Local for Scheduler {
+/// Encapsulates a temporarily-borrowed scheduler.
+pub struct BorrowedScheduler {
+    priv task: local_ptr::Borrowed<Task>,
+}
+
+impl BorrowedScheduler {
+    fn new(mut task: local_ptr::Borrowed<Task>) -> BorrowedScheduler {
+        if task.get().sched.is_none() {
+            rtabort!("no scheduler")
+        } else {
+            BorrowedScheduler {
+                task: task,
+            }
+        }
+    }
+
+    #[inline]
+    pub fn get<'a>(&'a mut self) -> &'a mut ~Scheduler {
+        match self.task.get().sched {
+            None => rtabort!("no scheduler"),
+            Some(ref mut sched) => sched,
+        }
+    }
+}
+
+impl Local<BorrowedScheduler> for Scheduler {
     fn put(value: ~Scheduler) {
-        let value = Cell::new(value);
-        Local::borrow(|task: &mut Task| {
-            let task = task;
-            task.sched = Some(value.take());
-        });
+        let mut task = Local::borrow(None::<Task>);
+        task.get().sched = Some(value);
     }
     #[inline]
     fn take() -> ~Scheduler {
@@ -71,24 +85,12 @@ fn take() -> ~Scheduler {
         }
     }
     fn exists(_: Option<Scheduler>) -> bool {
-        Local::borrow(|task: &mut Task| {
-            match task.sched {
-                Some(ref _task) => true,
-                None => false
-            }
-        })
+        let mut task = Local::borrow(None::<Task>);
+        task.get().sched.is_some()
     }
-    fn borrow<T>(f: |&mut Scheduler| -> T) -> T {
-        Local::borrow(|task: &mut Task| {
-            match task.sched {
-                Some(~ref mut task) => {
-                    f(task)
-                }
-                None => {
-                    rtabort!("no scheduler")
-                }
-            }
-        })
+    #[inline]
+    fn borrow(_: Option<Scheduler>) -> BorrowedScheduler {
+        BorrowedScheduler::new(Local::borrow(None::<Task>))
     }
     unsafe fn unsafe_take() -> ~Scheduler { rtabort!("unimpl") }
     unsafe fn unsafe_borrow() -> *mut Scheduler {
@@ -182,11 +184,11 @@ fn borrow_with_return() {
             let task = ~Task::new_root(&mut sched.stack_pool, None, proc(){});
             Local::put(task);
 
-            let res = Local::borrow(|_task: &mut Task| {
-                true
-            });
-            assert!(res)
-                let task: ~Task = Local::take();
+            {
+                let _ = Local::borrow(None::<Task>);
+            }
+
+            let task: ~Task = Local::take();
             cleanup_task(task);
         }
     }
index 2386a261bdf82132ece92997189facee4ec10d2e..e364137de4572ad5dda80efb3fe4cd7036319a41 100644 (file)
@@ -304,7 +304,8 @@ pub unsafe fn local_free(ptr: *libc::c_char) {
 }
 
 pub fn live_allocs() -> *mut Box {
-    Local::borrow(|task: &mut Task| task.heap.live_allocs)
+    let mut task = Local::borrow(None::<Task>);
+    task.get().heap.live_allocs
 }
 
 #[cfg(test)]
index be3b5f951ebc454a7dfa13bcccde4946febf5ccd..66fe9742121ff49d2feee0a55aa4d930858cc7dc 100644 (file)
@@ -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
 #[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
index af8de06adb7850a5f6ab90cd7d6129ce87f98be9..f4410f7ee27ca8b6798870cf7c0cc57b5ac81aa3 100644 (file)
@@ -24,7 +24,6 @@
 use rt::local::Local;
 use rt::rtio::{RemoteCallback, PausibleIdleCallback, Callback};
 use borrow::{to_uint};
-use cell::Cell;
 use rand::{XorShiftRng, Rng, Rand};
 use iter::range;
 use unstable::mutex::Mutex;
@@ -235,12 +234,12 @@ pub fn run(mut ~self) {
         unsafe {
             let event_loop: *mut ~EventLoop = &mut self.event_loop;
 
-            // Our scheduler must be in the task before the event loop
-            // is started.
-            let self_sched = Cell::new(self);
-            Local::borrow(|stask: &mut Task| {
-                stask.sched = Some(self_sched.take());
-            });
+            {
+                // Our scheduler must be in the task before the event loop
+                // is started.
+                let mut stask = Local::borrow(None::<Task>);
+                stask.get().sched = Some(self);
+            }
 
             (*event_loop).run();
         }
@@ -751,10 +750,8 @@ pub fn run_task(task: ~Task) {
     }
 
     pub fn run_task_later(next_task: ~Task) {
-        let next_task = Cell::new(next_task);
-        Local::borrow(|sched: &mut Scheduler| {
-            sched.enqueue_task(next_task.take());
-        });
+        let mut sched = Local::borrow(None::<Scheduler>);
+        sched.get().enqueue_task(next_task);
     }
 
     /// Yield control to the scheduler, executing another task. This is guaranteed
index 63cc397e8d795df248ee86ee2a920dab38eea228..0cb60c58a6d3353b7cc8c35c3f677fc0a39aab35 100644 (file)
@@ -144,17 +144,15 @@ pub fn build_homed_child(stack_size: Option<uint>,
                              f: proc(),
                              home: SchedHome)
                              -> ~Task {
-        let f = Cell::new(f);
-        let home = Cell::new(home);
-        Local::borrow(|running_task: &mut Task| {
-            let mut sched = running_task.sched.take_unwrap();
-            let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
-                                                         stack_size,
-                                                         home.take(),
-                                                         f.take());
-            running_task.sched = Some(sched);
-            new_task
-        })
+        let mut running_task = Local::borrow(None::<Task>);
+        let mut sched = running_task.get().sched.take_unwrap();
+        let new_task = ~running_task.get()
+                                    .new_child_homed(&mut sched.stack_pool,
+                                                     stack_size,
+                                                     home,
+                                                     f);
+        running_task.get().sched = Some(sched);
+        new_task
     }
 
     pub fn build_child(stack_size: Option<uint>, f: proc()) -> ~Task {
@@ -165,17 +163,14 @@ pub fn build_homed_root(stack_size: Option<uint>,
                             f: proc(),
                             home: SchedHome)
                             -> ~Task {
-        let f = Cell::new(f);
-        let home = Cell::new(home);
-        Local::borrow(|running_task: &mut Task| {
-            let mut sched = running_task.sched.take_unwrap();
-            let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
-                                                 stack_size,
-                                                 home.take(),
-                                                 f.take());
-            running_task.sched = Some(sched);
-            new_task
-        })
+        let mut running_task = Local::borrow(None::<Task>);
+        let mut sched = running_task.get().sched.take_unwrap();
+        let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
+                                             stack_size,
+                                             home,
+                                             f);
+        running_task.get().sched = Some(sched);
+        new_task
     }
 
     pub fn build_root(stack_size: Option<uint>, f: proc()) -> ~Task {
@@ -371,26 +366,25 @@ pub fn homed(&self) -> bool {
     // Grab both the scheduler and the task from TLS and check if the
     // task is executing on an appropriate scheduler.
     pub fn on_appropriate_sched() -> bool {
-        Local::borrow(|task: &mut Task| {
-            let sched_id = task.sched.get_ref().sched_id();
-            let sched_run_anything = task.sched.get_ref().run_anything;
-            match task.task_type {
-                GreenTask(Some(AnySched)) => {
-                    rtdebug!("anysched task in sched check ****");
-                    sched_run_anything
-                }
-                GreenTask(Some(Sched(SchedHandle { sched_id: ref id, ..}))) => {
-                    rtdebug!("homed task in sched check ****");
-                    *id == sched_id
-                }
-                GreenTask(None) => {
-                    rtabort!("task without home");
-                }
-                SchedTask => {
-                    rtabort!("type error: expected: GreenTask, found: SchedTask");
-                }
+        let mut task = Local::borrow(None::<Task>);
+        let sched_id = task.get().sched.get_ref().sched_id();
+        let sched_run_anything = task.get().sched.get_ref().run_anything;
+        match task.get().task_type {
+            GreenTask(Some(AnySched)) => {
+                rtdebug!("anysched task in sched check ****");
+                sched_run_anything
+            }
+            GreenTask(Some(Sched(SchedHandle { sched_id: ref id, ..}))) => {
+                rtdebug!("homed task in sched check ****");
+                *id == sched_id
+            }
+            GreenTask(None) => {
+                rtabort!("task without home");
             }
-        })
+            SchedTask => {
+                rtabort!("type error: expected: GreenTask, found: SchedTask");
+            }
+        }
     }
 }
 
@@ -440,9 +434,10 @@ fn build_start_wrapper(start: proc()) -> proc() {
             unsafe {
 
                 // Again - might work while safe, or it might not.
-                Local::borrow(|sched: &mut Scheduler| {
-                    sched.run_cleanup_job();
-                });
+                {
+                    let mut sched = Local::borrow(None::<Scheduler>);
+                    sched.get().run_cleanup_job();
+                }
 
                 // To call the run method on a task we need a direct
                 // reference to it. The task is in TLS, so we can
@@ -594,16 +589,19 @@ pub extern "C" fn rust_stack_exhausted() {
         //  #2361 - possible implementation of not using landing pads
 
         if in_green_task_context() {
-            Local::borrow(|task: &mut Task| {
-                let n = task.name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
-
-                // See the message below for why this is not emitted to the
-                // task's logger. This has the additional conundrum of the
-                // logger may not be initialized just yet, meaning that an FFI
-                // call would happen to initialized it (calling out to libuv),
-                // and the FFI call needs 2MB of stack when we just ran out.
-                rterrln!("task '{}' has overflowed its stack", n);
-            })
+            let mut task = Local::borrow(None::<Task>);
+            let n = task.get()
+                        .name
+                        .as_ref()
+                        .map(|n| n.as_slice())
+                        .unwrap_or("<unnamed>");
+
+            // See the message below for why this is not emitted to the
+            // task's logger. This has the additional conundrum of the
+            // logger may not be initialized just yet, meaning that an FFI
+            // call would happen to initialized it (calling out to libuv),
+            // and the FFI call needs 2MB of stack when we just ran out.
+            rterrln!("task '{}' has overflowed its stack", n);
         } else {
             rterrln!("stack overflow in non-task context");
         }
index 0d4171d5a643ca1c70a44b25cfe68631ee201e8b..15d8c7f9aac65a6968f6c24f703dc77b51cbff2e 100644 (file)
@@ -121,9 +121,9 @@ fn blocking_test() {
             let tube_clone = Cell::new(tube_clone);
             let sched: ~Scheduler = Local::take();
             sched.deschedule_running_task_and_then(|sched, task| {
-                let tube_clone = Cell::new(tube_clone.take());
+                let tube_clone = tube_clone.take();
                 do sched.event_loop.callback {
-                    let mut tube_clone = tube_clone.take();
+                    let mut tube_clone = tube_clone;
                     // The task should be blocked on this now and
                     // sending will wake it up.
                     tube_clone.send(1);
@@ -148,19 +148,18 @@ fn many_blocking_test() {
                 callback_send(tube_clone.take(), 0);
 
                 fn callback_send(tube: Tube<int>, i: int) {
-                    if i == 100 { return; }
-
-                    let tube = Cell::new(Cell::new(tube));
-                    Local::borrow(|sched: &mut Scheduler| {
-                        let tube = tube.take();
-                        do sched.event_loop.callback {
-                            let mut tube = tube.take();
-                            // The task should be blocked on this now and
-                            // sending will wake it up.
-                            tube.send(i);
-                            callback_send(tube, i + 1);
-                        }
-                    })
+                    if i == 100 {
+                        return
+                    }
+
+                    let mut sched = Local::borrow(None::<Scheduler>);
+                    do sched.get().event_loop.callback {
+                        let mut tube = tube;
+                        // The task should be blocked on this now and
+                        // sending will wake it up.
+                        tube.send(i);
+                        callback_send(tube, i + 1);
+                    }
                 }
 
                 sched.enqueue_blocked_task(task);
index 1777a5230734681a4a27ccafef0227acaeb4d0a6..24a24f2481887f600067e4af6cd947744a617538 100644 (file)
@@ -429,12 +429,11 @@ pub fn with_task_name<U>(blk: |Option<&str>| -> U) -> U {
     use rt::task::Task;
 
     if in_green_task_context() {
-        Local::borrow(|task: &mut Task| {
-            match task.name {
-                Some(ref name) => blk(Some(name.as_slice())),
-                None => blk(None)
-            }
-        })
+        let mut task = Local::borrow(None::<Task>);
+        match task.get().name {
+            Some(ref name) => blk(Some(name.as_slice())),
+            None => blk(None)
+        }
     } else {
         fail!("no task name exists in non-green task context")
     }
@@ -456,7 +455,8 @@ pub fn failing() -> bool {
 
     use rt::task::Task;
 
-    Local::borrow(|local: &mut Task| local.unwinder.unwinding)
+    let mut local = Local::borrow(None::<Task>);
+    local.get().unwinder.unwinding
 }
 
 // The following 8 tests test the following 2^3 combinations:
@@ -601,9 +601,9 @@ fn test_try_fail() {
 
 #[cfg(test)]
 fn get_sched_id() -> int {
-    Local::borrow(|sched: &mut ::rt::sched::Scheduler| {
-        sched.sched_id() as int
-    })
+    use rt::sched::Scheduler;
+    let mut sched = Local::borrow(None::<Scheduler>);
+    sched.get().sched_id() as int
 }
 
 #[test]