about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-06 16:18:58 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-06 16:18:58 -0700
commit8567611adfa69c4488133e18d3ec4fc195afadd1 (patch)
tree80e325db23f407d643e2ada480de23b1fb8b4fc6 /src/libstd/rt
parentfb9b27910b41e714dfd6b3ccc48161260943c9cf (diff)
parentd89ff7eef969aee6b493bc846b64d68358fafbcd (diff)
downloadrust-8567611adfa69c4488133e18d3ec4fc195afadd1.tar.gz
rust-8567611adfa69c4488133e18d3ec4fc195afadd1.zip
Merge commit 'd89ff7eef969aee6b493bc846b64d68358fafbcd' into remove-str-trailing-nulls
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/local.rs81
-rw-r--r--src/libstd/rt/local_ptr.rs26
-rw-r--r--src/libstd/rt/logging.rs21
-rw-r--r--src/libstd/rt/mod.rs10
-rw-r--r--src/libstd/rt/sched.rs12
-rw-r--r--src/libstd/rt/task.rs17
6 files changed, 104 insertions, 63 deletions
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
index 7ab63233cff..131507196b1 100644
--- a/src/libstd/rt/local.rs
+++ b/src/libstd/rt/local.rs
@@ -126,6 +126,7 @@ impl Local for IoFactoryObject {
 
 #[cfg(test)]
 mod test {
+    use unstable::run_in_bare_thread;
     use rt::test::*;
     use super::*;
     use rt::task::Task;
@@ -133,56 +134,64 @@ mod test {
 
     #[test]
     fn thread_local_task_smoke_test() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-        let task: ~Task = Local::take();
-        cleanup_task(task);
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+            let task: ~Task = Local::take();
+            cleanup_task(task);
+        }
     }
 
     #[test]
     fn thread_local_task_two_instances() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-        let task: ~Task = Local::take();
-        cleanup_task(task);
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-        let task: ~Task = Local::take();
-        cleanup_task(task);
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+            let task: ~Task = Local::take();
+            cleanup_task(task);
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+            let task: ~Task = Local::take();
+            cleanup_task(task);
+        }
 
     }
 
     #[test]
     fn borrow_smoke_test() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-
-        unsafe {
-            let _task: *mut Task = Local::unsafe_borrow();
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+
+            unsafe {
+                let _task: *mut Task = Local::unsafe_borrow();
+            }
+            let task: ~Task = Local::take();
+            cleanup_task(task);
         }
-        let task: ~Task = Local::take();
-        cleanup_task(task);
     }
 
     #[test]
     fn borrow_with_return() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-
-        let res = do Local::borrow::<Task,bool> |_task| {
-            true
-        };
-        assert!(res)
-        let task: ~Task = Local::take();
-        cleanup_task(task);
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+
+            let res = do Local::borrow::<Task,bool> |_task| {
+                true
+            };
+            assert!(res)
+                let task: ~Task = Local::take();
+            cleanup_task(task);
+        }
     }
 
 }
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
index cd7c5daa444..652e39b05c7 100644
--- a/src/libstd/rt/local_ptr.rs
+++ b/src/libstd/rt/local_ptr.rs
@@ -52,7 +52,9 @@ pub unsafe fn put<T>(sched: ~T) {
 pub unsafe fn take<T>() -> ~T {
     let key = tls_key();
     let void_ptr: *mut c_void = tls::get(key);
-    rtassert!(void_ptr.is_not_null());
+    if void_ptr.is_null() {
+        rtabort!("thread-local pointer is null. bogus!");
+    }
     let ptr: ~T = cast::transmute(void_ptr);
     tls::set(key, ptr::mut_null());
     return ptr;
@@ -68,8 +70,8 @@ pub fn exists() -> bool {
     }
 }
 
-/// Borrow the thread-local scheduler from thread-local storage.
-/// While the scheduler is borrowed it is not available in TLS.
+/// Borrow the thread-local value from thread-local storage.
+/// While the value is borrowed it is not available in TLS.
 ///
 /// # Safety note
 ///
@@ -88,21 +90,23 @@ pub unsafe fn borrow<T>(f: &fn(&mut T)) {
     }
 }
 
-/// Borrow a mutable reference to the thread-local Scheduler
+/// Borrow a mutable reference to the thread-local value
 ///
 /// # Safety Note
 ///
-/// Because this leaves the Scheduler in thread-local storage it is possible
+/// Because this leaves the value in thread-local storage it is possible
 /// For the Scheduler pointer to be aliased
 pub unsafe fn unsafe_borrow<T>() -> *mut T {
     let key = tls_key();
-    let mut void_sched: *mut c_void = tls::get(key);
-    rtassert!(void_sched.is_not_null());
+    let mut void_ptr: *mut c_void = tls::get(key);
+    if void_ptr.is_null() {
+        rtabort!("thread-local pointer is null. bogus!");
+    }
     {
-        let sched: *mut *mut c_void = &mut void_sched;
-        let sched: *mut ~T = sched as *mut ~T;
-        let sched: *mut T = &mut **sched;
-        return sched;
+        let ptr: *mut *mut c_void = &mut void_ptr;
+        let ptr: *mut ~T = ptr as *mut ~T;
+        let ptr: *mut T = &mut **ptr;
+        return ptr;
     }
 }
 
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index 76619704bee..117795f6c90 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -10,6 +10,7 @@
 
 use either::*;
 use libc;
+use str::StrSlice;
 
 pub trait Logger {
     fn log(&mut self, msg: Either<~str, &'static str>);
@@ -35,10 +36,22 @@ impl Logger for StdErrLogger {
                 s
             }
         };
-        let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
-        dbg.write_str(s);
-        dbg.write_str("\n");
-        dbg.flush();
+
+        // Truncate the string
+        let buf_bytes = 256;
+        if s.len() > buf_bytes {
+            let s = s.slice(0, buf_bytes) + "[...]";
+            print(s);
+        } else {
+            print(s)
+        };
+
+        fn print(s: &str) {
+            let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
+            dbg.write_str(s);
+            dbg.write_str("\n");
+            dbg.flush();
+        }
     }
 }
 
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 4cfe0efacfe..33e83fd9040 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -432,13 +432,3 @@ pub fn context() -> RuntimeContext {
         pub fn rust_try_get_task() -> *rust_task;
     }
 }
-
-#[test]
-fn test_context() {
-    use unstable::run_in_bare_thread;
-
-    assert_eq!(context(), OldTaskContext);
-    do run_in_bare_thread {
-        assert_eq!(context(), GlobalContext);
-    }
-}
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 18cfeade157..1a75f2569b5 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -172,6 +172,10 @@ impl Scheduler {
 
         rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id());
 
+        // Should not have any messages
+        let message = stask.sched.get_mut_ref().message_queue.pop();
+        assert!(message.is_none());
+
         stask.destroyed = true;
     }
 
@@ -335,19 +339,24 @@ impl Scheduler {
         let mut this = self;
         match this.message_queue.pop() {
             Some(PinnedTask(task)) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
                 let mut task = task;
                 task.give_home(Sched(this.make_handle()));
                 this.resume_task_immediately(task);
                 return None;
             }
             Some(TaskFromFriend(task)) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
+                rtdebug!("got a task from a friend. lovely!");
                 return this.sched_schedule_task(task);
             }
             Some(Wake) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
                 this.sleepy = false;
                 return Some(this);
             }
             Some(Shutdown) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
                 if this.sleepy {
                     // There may be an outstanding handle on the
                     // sleeper list.  Pop them all to make sure that's
@@ -395,6 +404,7 @@ impl Scheduler {
     /// Take a non-homed task we aren't allowed to run here and send
     /// it to the designated friend scheduler to execute.
     fn send_to_friend(&mut self, task: ~Task) {
+        rtdebug!("sending a task to friend");
         match self.friend_handle {
             Some(ref mut handle) => {
                 handle.send(TaskFromFriend(task));
@@ -426,12 +436,14 @@ impl Scheduler {
                             Scheduler::send_task_home(task);
                             return Some(this);
                         } else {
+                            this.event_loop.callback(Scheduler::run_sched_once);
                             task.give_home(Sched(home_handle));
                             this.resume_task_immediately(task);
                             return None;
                         }
                     }
                     AnySched if this.run_anything => {
+                        this.event_loop.callback(Scheduler::run_sched_once);
                         task.give_home(AnySched);
                         this.resume_task_immediately(task);
                         return None;
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index abafe1cf209..cb949edd7bb 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -228,6 +228,19 @@ impl Task {
                     _ => ()
                 }
 
+                // FIXME #8302: Dear diary. I'm so tired and confused.
+                // There's some interaction in rustc between the box
+                // annihilator and the TLS dtor by which TLS is
+                // accessed from annihilated box dtors *after* TLS is
+                // destroyed. Somehow setting TLS back to null, as the
+                // old runtime did, makes this work, but I don't currently
+                // understand how. I would expect that, if the annihilator
+                // reinvokes TLS while TLS is uninitialized, that
+                // TLS would be reinitialized but never destroyed,
+                // but somehow this works. I have no idea what's going
+                // on but this seems to make things magically work. FML.
+                self.storage = LocalStorage(ptr::null(), None);
+
                 // Destroy remaining boxes. Also may run user dtors.
                 unsafe { cleanup::annihilate(); }
             }
@@ -303,7 +316,7 @@ impl Task {
 impl Drop for Task {
     fn drop(&self) {
         rtdebug!("called drop for a task: %u", borrow::to_uint(self));
-        assert!(self.destroyed)
+        rtassert!(self.destroyed)
     }
 }
 
@@ -313,7 +326,7 @@ impl Drop for Task {
 impl Coroutine {
 
     pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
-        static MIN_STACK_SIZE: uint = 2000000; // XXX: Too much stack
+        static MIN_STACK_SIZE: uint = 3000000; // XXX: Too much stack
 
         let start = Coroutine::build_start_wrapper(start);
         let mut stack = stack_pool.take_segment(MIN_STACK_SIZE);