diff --git a/src/librustuv/async.rs b/src/librustuv/async.rs index efc2d2c866d..5a0db8313fb 100644 --- a/src/librustuv/async.rs +++ b/src/librustuv/async.rs @@ -152,6 +152,7 @@ mod test_remote { let watcher = AsyncWatcher::new(local_loop(), cb as ~Callback); let thread = do Thread::start { + let mut watcher = watcher; watcher.fire(); }; diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index 09a13bdddaa..f68b1052492 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -395,13 +395,9 @@ fn local_loop() -> &'static mut Loop { unsafe { cast::transmute({ let mut sched = Local::borrow(None::); - let mut io = None; - sched.get().event_loop.io(|i| { - let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) = - cast::transmute(i); - io = Some(uvio); - }); - io.unwrap() + let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) = + cast::transmute(sched.get().event_loop.io().unwrap()); + uvio }.uv_loop()) } } diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs index a3931f213ec..c09383c2d8f 100644 --- a/src/librustuv/net.rs +++ b/src/librustuv/net.rs @@ -1073,6 +1073,8 @@ mod test { let tasksFriendHandle = sched2.make_handle(); let on_exit: proc(UnwindResult) = proc(exit_status) { + let mut handle1 = handle1; + let mut handle2 = handle2; handle1.send(Shutdown); handle2.send(Shutdown); assert!(exit_status.is_success()); @@ -1080,8 +1082,7 @@ mod test { unsafe fn local_io() -> &'static mut IoFactory { let mut sched = Local::borrow(None::); - let mut io = None; - sched.get().event_loop.io(|i| io = Some(i)); + let io = sched.get().event_loop.io(); cast::transmute(io.unwrap()) } @@ -1121,9 +1122,13 @@ mod test { // nothing }; + let main_task = main_task; + let sched1 = sched1; let thread1 = do Thread::start { sched1.bootstrap(main_task); }; + + let sched2 = sched2; let thread2 = do Thread::start { sched2.bootstrap(null_task); }; diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index db1c375b0c6..e0011398aa1 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -9,7 +9,6 @@ // except according to those terms. use std::c_str::CString; -use std::cast; use std::comm::SharedChan; use std::libc::c_int; use std::libc; @@ -162,11 +161,9 @@ impl EventLoop for UvEventLoop { ~AsyncWatcher::new(self.uvio.uv_loop(), f) as ~RemoteCallback } - fn io(&mut self) -> &'static mut IoFactory:'static { - unsafe { - let factory = &mut self.uvio as &mut IoFactory; - cast::transmute(factory) - } + fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> { + let factory = &mut self.uvio as &mut IoFactory; + Some(factory) } } diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index e49cf3e5303..280c79f1fd4 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -14,66 +14,6 @@ use prelude::*; use cast; use util::NonCopyable; - -/* -A dynamic, mutable location. - -Similar to a mutable option type, but friendlier. -*/ - -#[no_freeze] -#[deriving(Clone, DeepClone, Eq)] -#[allow(missing_doc)] -pub struct Cell { - priv value: Option -} - -impl Cell { - /// Creates a new full cell with the given value. - pub fn new(value: T) -> Cell { - Cell { value: Some(value) } - } - - /// Yields the value, failing if the cell is empty. - pub fn take(&self) -> T { - let this = unsafe { cast::transmute_mut(self) }; - if this.is_empty() { - fail!("attempt to take an empty cell"); - } - - this.value.take_unwrap() - } - - /// Yields the value if the cell is full, or `None` if it is empty. - pub fn take_opt(&self) -> Option { - let this = unsafe { cast::transmute_mut(self) }; - this.value.take() - } - - /// Returns true if the cell is empty and false if the cell is full. - pub fn is_empty(&self) -> bool { - self.value.is_none() - } -} - -#[test] -fn test_basic() { - let value_cell = Cell::new(~10); - assert!(!value_cell.is_empty()); - let value = value_cell.take(); - assert!(value == ~10); - assert!(value_cell.is_empty()); -} - -#[test] -#[should_fail] -fn test_take_empty() { - let value_cell: Cell<~int> = Cell::new(~0); - value_cell.take(); - value_cell.take(); -} - - /// A mutable memory location with dynamically checked borrow rules #[no_freeze] pub struct RefCell { diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 509ef2a8157..41337075aa9 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -31,7 +31,7 @@ use libc; use option::{Option, Some, None}; use result::{Ok, Err}; use io::buffered::LineBufferedWriter; -use rt::rtio::{IoFactory, RtioTTY, RtioFileStream, DontClose}; +use rt::rtio::{DontClose, IoFactory, LocalIo, RtioFileStream, RtioTTY}; use super::{Reader, Writer, io_error, IoError, OtherIoError, standard_error, EndOfFile}; diff --git a/src/libstd/rt/basic.rs b/src/libstd/rt/basic.rs index 87b776d3c1e..fa47ceb1c04 100644 --- a/src/libstd/rt/basic.rs +++ b/src/libstd/rt/basic.rs @@ -159,11 +159,9 @@ impl EventLoop for BasicLoop { ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback } - fn io(&mut self) -> &'static mut IoFactory:'static { - unsafe { - let factory: &mut IoFactory = self.io; - cast::transmute(factory) - } + fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> { + let factory: &mut IoFactory = self.io; + Some(factory) } } diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index c6942ab8388..05cc051a23e 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -39,7 +39,7 @@ pub trait EventLoop { fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback; /// The asynchronous I/O services. Not all event loops may provide one. - fn io(&mut self) -> &'static mut IoFactory:'static; + fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>; } pub trait RemoteCallback { @@ -78,19 +78,19 @@ pub enum CloseBehavior { CloseAsynchronously, } -pub struct LocalIo { - factory: &'static mut IoFactory:'static, +pub struct LocalIo<'a> { + priv factory: &'a mut IoFactory, } #[unsafe_destructor] -impl Drop for LocalIo { +impl<'a> Drop for LocalIo<'a> { fn drop(&mut self) { // XXX(pcwalton): Do nothing here for now, but eventually we may want // something. For now this serves to make `LocalIo` noncopyable. } } -impl LocalIo { +impl<'a> LocalIo<'a> { /// Returns the local I/O: either the local scheduler's I/O services or /// the native I/O services. pub fn borrow() -> LocalIo { @@ -102,8 +102,13 @@ impl LocalIo { let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow(); match sched { Some(sched) => { - return LocalIo { - factory: (*sched).event_loop.io(), + match (*sched).event_loop.io() { + Some(factory) => { + return LocalIo { + factory: factory, + } + } + None => {} } } None => {} @@ -120,7 +125,9 @@ impl LocalIo { /// Returns the underlying I/O factory as a trait reference. #[inline] - pub fn get(&mut self) -> &'static mut IoFactory { + pub fn get<'a>(&'a mut self) -> &'a mut IoFactory { + // XXX(pcwalton): I think this is actually sound? Could borrow check + // allow this safely? unsafe { cast::transmute_copy(&self.factory) } diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 6eacbd12a70..b148df24833 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -90,8 +90,9 @@ fn main() { for i in range(1u, num_tasks) { //error!("spawning %?", i); let (new_chan, num_port) = init(); + let num_chan_2 = num_chan.clone(); let new_future = do Future::spawn() { - thread_ring(i, msg_per_task, num_chan, num_port) + thread_ring(i, msg_per_task, num_chan_2, num_port) }; futures.push(new_future); num_chan = new_chan; diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index b713652e31d..ea241d267c7 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -86,8 +86,9 @@ fn main() { for i in range(1u, num_tasks) { //error!("spawning %?", i); let (new_chan, num_port) = init(); + let num_chan_2 = num_chan.clone(); let new_future = do Future::spawn { - thread_ring(i, msg_per_task, num_chan, num_port) + thread_ring(i, msg_per_task, num_chan_2, num_port) }; futures.push(new_future); num_chan = new_chan;