libstd: Remove Cell from the library.

This commit is contained in:
Patrick Walton
2013-12-05 17:37:02 -08:00
parent 6113508055
commit fd7a513bef
10 changed files with 37 additions and 91 deletions

View File

@@ -152,6 +152,7 @@ mod test_remote {
let watcher = AsyncWatcher::new(local_loop(), cb as ~Callback); let watcher = AsyncWatcher::new(local_loop(), cb as ~Callback);
let thread = do Thread::start { let thread = do Thread::start {
let mut watcher = watcher;
watcher.fire(); watcher.fire();
}; };

View File

@@ -395,13 +395,9 @@ fn local_loop() -> &'static mut Loop {
unsafe { unsafe {
cast::transmute({ cast::transmute({
let mut sched = Local::borrow(None::<Scheduler>); let mut sched = Local::borrow(None::<Scheduler>);
let mut io = None; let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) =
sched.get().event_loop.io(|i| { cast::transmute(sched.get().event_loop.io().unwrap());
let (_vtable, uvio): (uint, &'static mut uvio::UvIoFactory) = uvio
cast::transmute(i);
io = Some(uvio);
});
io.unwrap()
}.uv_loop()) }.uv_loop())
} }
} }

View File

@@ -1073,6 +1073,8 @@ mod test {
let tasksFriendHandle = sched2.make_handle(); let tasksFriendHandle = sched2.make_handle();
let on_exit: proc(UnwindResult) = proc(exit_status) { let on_exit: proc(UnwindResult) = proc(exit_status) {
let mut handle1 = handle1;
let mut handle2 = handle2;
handle1.send(Shutdown); handle1.send(Shutdown);
handle2.send(Shutdown); handle2.send(Shutdown);
assert!(exit_status.is_success()); assert!(exit_status.is_success());
@@ -1080,8 +1082,7 @@ mod test {
unsafe fn local_io() -> &'static mut IoFactory { unsafe fn local_io() -> &'static mut IoFactory {
let mut sched = Local::borrow(None::<Scheduler>); let mut sched = Local::borrow(None::<Scheduler>);
let mut io = None; let io = sched.get().event_loop.io();
sched.get().event_loop.io(|i| io = Some(i));
cast::transmute(io.unwrap()) cast::transmute(io.unwrap())
} }
@@ -1121,9 +1122,13 @@ mod test {
// nothing // nothing
}; };
let main_task = main_task;
let sched1 = sched1;
let thread1 = do Thread::start { let thread1 = do Thread::start {
sched1.bootstrap(main_task); sched1.bootstrap(main_task);
}; };
let sched2 = sched2;
let thread2 = do Thread::start { let thread2 = do Thread::start {
sched2.bootstrap(null_task); sched2.bootstrap(null_task);
}; };

View File

@@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use std::c_str::CString; use std::c_str::CString;
use std::cast;
use std::comm::SharedChan; use std::comm::SharedChan;
use std::libc::c_int; use std::libc::c_int;
use std::libc; use std::libc;
@@ -162,11 +161,9 @@ impl EventLoop for UvEventLoop {
~AsyncWatcher::new(self.uvio.uv_loop(), f) as ~RemoteCallback ~AsyncWatcher::new(self.uvio.uv_loop(), f) as ~RemoteCallback
} }
fn io(&mut self) -> &'static mut IoFactory:'static { fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> {
unsafe { let factory = &mut self.uvio as &mut IoFactory;
let factory = &mut self.uvio as &mut IoFactory; Some(factory)
cast::transmute(factory)
}
} }
} }

View File

@@ -14,66 +14,6 @@ use prelude::*;
use cast; use cast;
use util::NonCopyable; 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<T> {
priv value: Option<T>
}
impl<T> Cell<T> {
/// Creates a new full cell with the given value.
pub fn new(value: T) -> Cell<T> {
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<T> {
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 /// A mutable memory location with dynamically checked borrow rules
#[no_freeze] #[no_freeze]
pub struct RefCell<T> { pub struct RefCell<T> {

View File

@@ -31,7 +31,7 @@ use libc;
use option::{Option, Some, None}; use option::{Option, Some, None};
use result::{Ok, Err}; use result::{Ok, Err};
use io::buffered::LineBufferedWriter; 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, use super::{Reader, Writer, io_error, IoError, OtherIoError,
standard_error, EndOfFile}; standard_error, EndOfFile};

View File

@@ -159,11 +159,9 @@ impl EventLoop for BasicLoop {
~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
} }
fn io(&mut self) -> &'static mut IoFactory:'static { fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> {
unsafe { let factory: &mut IoFactory = self.io;
let factory: &mut IoFactory = self.io; Some(factory)
cast::transmute(factory)
}
} }
} }

View File

@@ -39,7 +39,7 @@ pub trait EventLoop {
fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback; fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
/// The asynchronous I/O services. Not all event loops may provide one. /// 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 { pub trait RemoteCallback {
@@ -78,19 +78,19 @@ pub enum CloseBehavior {
CloseAsynchronously, CloseAsynchronously,
} }
pub struct LocalIo { pub struct LocalIo<'a> {
factory: &'static mut IoFactory:'static, priv factory: &'a mut IoFactory,
} }
#[unsafe_destructor] #[unsafe_destructor]
impl Drop for LocalIo { impl<'a> Drop for LocalIo<'a> {
fn drop(&mut self) { fn drop(&mut self) {
// XXX(pcwalton): Do nothing here for now, but eventually we may want // XXX(pcwalton): Do nothing here for now, but eventually we may want
// something. For now this serves to make `LocalIo` noncopyable. // 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 /// Returns the local I/O: either the local scheduler's I/O services or
/// the native I/O services. /// the native I/O services.
pub fn borrow() -> LocalIo { pub fn borrow() -> LocalIo {
@@ -102,8 +102,13 @@ impl LocalIo {
let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow(); let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow();
match sched { match sched {
Some(sched) => { Some(sched) => {
return LocalIo { match (*sched).event_loop.io() {
factory: (*sched).event_loop.io(), Some(factory) => {
return LocalIo {
factory: factory,
}
}
None => {}
} }
} }
None => {} None => {}
@@ -120,7 +125,9 @@ impl LocalIo {
/// Returns the underlying I/O factory as a trait reference. /// Returns the underlying I/O factory as a trait reference.
#[inline] #[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 { unsafe {
cast::transmute_copy(&self.factory) cast::transmute_copy(&self.factory)
} }

View File

@@ -90,8 +90,9 @@ fn main() {
for i in range(1u, num_tasks) { for i in range(1u, num_tasks) {
//error!("spawning %?", i); //error!("spawning %?", i);
let (new_chan, num_port) = init(); let (new_chan, num_port) = init();
let num_chan_2 = num_chan.clone();
let new_future = do Future::spawn() { 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); futures.push(new_future);
num_chan = new_chan; num_chan = new_chan;

View File

@@ -86,8 +86,9 @@ fn main() {
for i in range(1u, num_tasks) { for i in range(1u, num_tasks) {
//error!("spawning %?", i); //error!("spawning %?", i);
let (new_chan, num_port) = init(); let (new_chan, num_port) = init();
let num_chan_2 = num_chan.clone();
let new_future = do Future::spawn { 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); futures.push(new_future);
num_chan = new_chan; num_chan = new_chan;