diff --git a/src/libstd/cell.rs b/src/libcore/cell.rs similarity index 98% rename from src/libstd/cell.rs rename to src/libcore/cell.rs index c8121daddabd0..5887df6802f57 100644 --- a/src/libstd/cell.rs +++ b/src/libcore/cell.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::option; -use core::prelude::*; +use option; +use prelude::*; /// A dynamic, mutable location. /// diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 829651ae90925..ed18388f5783b 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -143,6 +143,7 @@ pub mod dlist; #[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"] pub mod dlist_iter; pub mod hashmap; +pub mod cell; /* Tasks and communication */ diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 94c0a567f4c09..15a6e700ffd84 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -86,6 +86,7 @@ bounded and unbounded protocols allows for less code duplication. use cmp::Eq; use cast::{forget, reinterpret_cast, transmute}; +use cell::Cell; use either::{Either, Left, Right}; use kinds::Owned; use libc; @@ -917,11 +918,9 @@ pub fn spawn_service( // This is some nasty gymnastics required to safely move the pipe // into a new task. - let server = ~mut Some(server); - do task::spawn || { - let mut server_ = None; - server_ <-> *server; - service(option::unwrap(server_)) + let server = Cell(server); + do task::spawn { + service(server.take()); } client @@ -941,11 +940,9 @@ pub fn spawn_service_recv( // This is some nasty gymnastics required to safely move the pipe // into a new task. - let server = ~mut Some(server); - do task::spawn || { - let mut server_ = None; - server_ <-> *server; - service(option::unwrap(server_)) + let server = Cell(server); + do task::spawn { + service(server.take()) } client diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 280eb14b172c4..d40f59fe673bf 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -107,10 +107,14 @@ fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool { * Shared state & exclusive ARC ****************************************************************************/ +struct UnwrapProtoInner { + contents: Option<(comm::ChanOne<()>, comm::PortOne)>, +} + // An unwrapper uses this protocol to communicate with the "other" task that // drops the last refcount on an arc. Unfortunately this can't be a proper // pipe protocol because the unwrapper has to access both stages at once. -type UnwrapProto = ~mut Option<(comm::ChanOne<()>, comm::PortOne)>; +type UnwrapProto = ~UnwrapProtoInner; struct ArcData { mut count: libc::intptr_t, @@ -139,9 +143,10 @@ struct ArcDestruct { // reference. In effect, being here means we're the only // *awake* task with the data. if data.unwrapper != 0 { - let p: UnwrapProto = + let mut p: UnwrapProto = cast::reinterpret_cast(&data.unwrapper); - let (message, response) = option::swap_unwrap(p); + let (message, response) = + option::swap_unwrap(&mut p.contents); // Send 'ready' and wait for a response. comm::send_one(message, ()); // Unkillable wait. Message guaranteed to come. @@ -196,7 +201,9 @@ pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) let ptr: ~ArcData = cast::reinterpret_cast(&rc.data); let (p1,c1) = comm::oneshot(); // () let (p2,c2) = comm::oneshot(); // bool - let server: UnwrapProto = ~mut Some((c1,p2)); + let mut server: UnwrapProto = ~UnwrapProtoInner { + contents: Some((c1,p2)) + }; let serverp: int = cast::transmute(server); // Try to put our server end in the unwrapper slot. if compare_and_swap(&mut ptr.unwrapper, 0, serverp) { @@ -409,8 +416,9 @@ pub fn unwrap_exclusive(arc: Exclusive) -> T { pub mod tests { use core::option::{None, Some}; - use option; + use cell::Cell; use comm; + use option; use private::{exclusive, unwrap_exclusive}; use result; use task; @@ -423,7 +431,7 @@ pub mod tests { let num_tasks = 10; let count = 10; - let total = exclusive(~mut 0); + let total = exclusive(~0); for uint::range(0, num_tasks) |_i| { let total = total.clone(); @@ -472,9 +480,9 @@ pub mod tests { #[test] pub fn exclusive_unwrap_contended() { let x = exclusive(~~"hello"); - let x2 = ~mut Some(x.clone()); - do task::spawn || { - let x2 = option::swap_unwrap(x2); + let x2 = Cell(x.clone()); + do task::spawn { + let x2 = option::swap_unwrap(x2.take()); do x2.with |_hello| { } task::yield(); } @@ -482,11 +490,10 @@ pub mod tests { // Now try the same thing, but with the child task blocking. let x = exclusive(~~"hello"); - let x2 = ~mut Some(x.clone()); + let x2 = Cell(x.clone()); let mut res = None; - do task::task().future_result(|+r| res = Some(r)).spawn - || { - let x2 = option::swap_unwrap(x2); + do task::task().future_result(|+r| res = Some(r)).spawn { + let x2 = x2.take(); assert unwrap_exclusive(x2) == ~~"hello"; } // Have to get rid of our reference before blocking. @@ -498,11 +505,10 @@ pub mod tests { #[test] #[should_fail] #[ignore(cfg(windows))] pub fn exclusive_unwrap_conflict() { let x = exclusive(~~"hello"); - let x2 = ~mut Some(x.clone()); + let x2 = Cell(x.clone()); let mut res = None; - do task::task().future_result(|+r| res = Some(r)).spawn - || { - let x2 = option::swap_unwrap(x2); + do task::task().future_result(|+r| res = Some(r)).spawn { + let x2 = x2.take(); assert unwrap_exclusive(x2) == ~~"hello"; } assert unwrap_exclusive(x) == ~~"hello"; diff --git a/src/libcore/private/weak_task.rs b/src/libcore/private/weak_task.rs index f3df8ce72f146..8445638850cd0 100644 --- a/src/libcore/private/weak_task.rs +++ b/src/libcore/private/weak_task.rs @@ -18,16 +18,17 @@ it is running, sending a notification to the task that the runtime is trying to shut down. */ +use cell::Cell; +use comm::{GenericSmartChan, stream}; +use comm::{Port, Chan, SharedChan, GenericChan, GenericPort}; +use hashmap::linear::LinearMap; +use ops::Drop; use option::{Some, None, swap_unwrap}; use private::at_exit::at_exit; -use private::global::global_data_clone_create; use private::finally::Finally; -use comm::{Port, Chan, SharedChan, GenericChan, - GenericPort, GenericSmartChan, stream}; -use task::{Task, task, spawn}; +use private::global::global_data_clone_create; use task::rt::{task_id, get_task_id}; -use hashmap::linear::LinearMap; -use ops::Drop; +use task::{Task, task, spawn}; type ShutdownMsg = (); @@ -37,14 +38,13 @@ pub unsafe fn weaken_task(f: &fn(Port)) { let service = global_data_clone_create(global_data_key, create_global_service); let (shutdown_port, shutdown_chan) = stream::(); - let shutdown_port = ~mut Some(shutdown_port); + let shutdown_port = Cell(shutdown_port); let task = get_task_id(); // Expect the weak task service to be alive assert service.try_send(RegisterWeakTask(task, shutdown_chan)); unsafe { rust_dec_kernel_live_count(); } do fn&() { - let shutdown_port = swap_unwrap(&mut *shutdown_port); - f(shutdown_port) + f(shutdown_port.take()) }.finally || { unsafe { rust_inc_kernel_live_count(); } // Service my have already exited @@ -67,16 +67,15 @@ fn create_global_service() -> ~WeakTaskService { debug!("creating global weak task service"); let (port, chan) = stream::(); - let port = ~mut Some(port); + let port = Cell(port); let chan = SharedChan(chan); let chan_clone = chan.clone(); do task().unlinked().spawn { debug!("running global weak task service"); - let port = swap_unwrap(&mut *port); - let port = ~mut Some(port); + let port = Cell(port.take()); do fn&() { - let port = swap_unwrap(&mut *port); + let port = port.take(); // The weak task service is itself a weak task debug!("weakening the weak service task"); unsafe { rust_dec_kernel_live_count(); } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 7f1687b08608a..4c3abb09756e9 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -602,7 +602,6 @@ fn test_repr() { exact_test(&(@10), "@10"); exact_test(&(@mut 10), "@10"); exact_test(&(~10), "~10"); - exact_test(&(~mut 10), "~mut 10"); exact_test(&(&10), "&10"); let mut x = 10; exact_test(&(&mut x), "&mut 10"); diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 336e686193b91..2a640e4bf8cf7 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -34,6 +34,7 @@ */ use cast; +use cell::Cell; use cmp; use cmp::Eq; use iter; @@ -397,9 +398,9 @@ impl TaskBuilder { } /// Runs a task, while transfering ownership of one argument to the child. fn spawn_with(arg: A, f: fn~(v: A)) { - let arg = ~mut Some(arg); - do self.spawn || { - f(option::swap_unwrap(arg)) + let arg = Cell(arg); + do self.spawn { + f(arg.take()); } } diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index e77af820079b6..5110f70ff11be 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -73,6 +73,7 @@ #[doc(hidden)]; // FIXME #3538 use cast; +use cell::Cell; use container::Map; use option; use comm::{Chan, GenericChan, GenericPort, Port, stream}; @@ -530,11 +531,11 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { gen_child_taskgroup(opts.linked, opts.supervised); unsafe { - let child_data = ~mut Some((child_tg, ancestors, f)); + let child_data = Cell((child_tg, ancestors, f)); // Being killed with the unsafe task/closure pointers would leak them. do unkillable { // Agh. Get move-mode items into the closure. FIXME (#2829) - let (child_tg, ancestors, f) = option::swap_unwrap(child_data); + let (child_tg, ancestors, f) = child_data.take(); // Create child task. let new_task = match opts.sched.mode { DefaultScheduler => rt::new_task(), @@ -571,10 +572,10 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) { ancestors: AncestorList, is_main: bool, notify_chan: Option>, f: fn~()) -> fn~() { - let child_data = ~mut Some((child_arc, ancestors)); + let child_data = Cell((child_arc, ancestors)); return fn~() { // Agh. Get move-mode items into the closure. FIXME (#2829) - let mut (child_arc, ancestors) = option::swap_unwrap(child_data); + let mut (child_arc, ancestors) = child_data.take(); // Child task runs this code. // Even if the below code fails to kick the child off, we must diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index cc5e860715d6d..ee59868665252 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -549,6 +549,7 @@ use syntax::codemap; use util::common::indenter; use util::ppaux::note_and_explain_region; +use core::cell::{Cell, empty_cell}; use core::cmp; use core::dvec::DVec; use core::to_bytes; @@ -557,7 +558,6 @@ use core::vec; use result::Result; use result::{Ok, Err}; use std::oldmap::HashMap; -use std::cell::{Cell, empty_cell}; use std::list::{List, Nil, Cons}; use syntax::codemap::span; use syntax::codemap; diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 01758a1845d7c..251e21578a523 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -314,8 +314,8 @@ fails without recording a fatal error then we've encountered a compiler bug and need to present an error. */ pub fn monitor(+f: fn~(diagnostic::Emitter)) { + use core::cell::Cell; use core::comm::*; - use std::cell::Cell; let (p, ch) = stream(); let ch = SharedChan(ch); let ch_capture = ch.clone(); diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index fff2e189eb85c..1c45fdafa189c 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -21,8 +21,8 @@ use core::prelude::*; use parse; use util; -use std::cell::Cell; +use core::cell::Cell; use core::comm::{stream, Chan, SharedChan, Port}; use core::vec; use core::ops::Drop; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e904015e419f6..11a1b9f357657 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -10,6 +10,7 @@ use core::prelude::*; +use core::cell::Cell; use core::cmp; use core::os; use core::result; @@ -18,7 +19,6 @@ use core::run::ProgramOutput; use core::vec; use core::result::Result; use std::getopts; -use std::cell::Cell; /// The type of document to output pub enum OutputFormat { diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index ff9faabaec24b..f64f365496d83 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -34,11 +34,11 @@ use sort_pass; use trim_pass; use unindent_pass; +use core::cell::Cell; use core::iter; use core::str; use core::vec; use std::par; -use std::cell::Cell; use syntax; pub fn mk_pass(writer_factory: WriterFactory) -> Pass { diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index b9dbe523fdd33..83f35418b0b1f 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -20,8 +20,8 @@ use fold; use pass::Pass; use util::NominalOp; +use core::cell::Cell; use std::par; -use std::cell::Cell; pub fn mk_pass(name: ~str, op: @fn(&str) -> ~str) -> Pass { let op = Cell(op); diff --git a/src/libstd/std.rc b/src/libstd/std.rc index b985e579244dd..bdb455cc6549c 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -54,7 +54,6 @@ pub mod uv_global_loop; pub mod c_vec; pub mod timer; -pub mod cell; pub mod io_util; // Concurrency