diff options
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/arc.rs | 6 | ||||
| -rw-r--r-- | src/liballoc/boxed.rs | 22 | ||||
| -rw-r--r-- | src/liballoc/heap.rs | 16 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 12 | ||||
| -rw-r--r-- | src/liballoc/libc_heap.rs | 6 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 296 |
6 files changed, 180 insertions, 178 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 1d6714430a8..0d9e4f0a1c2 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -77,7 +77,7 @@ struct ArcInner<T> { } impl<T: Sync + Send> Arc<T> { - /// Create an atomically reference counted wrapper. + /// Creates an atomically reference counted wrapper. #[inline] #[stable] pub fn new(data: T) -> Arc<T> { @@ -101,7 +101,7 @@ impl<T: Sync + Send> Arc<T> { unsafe { &*self._ptr } } - /// Downgrades a strong pointer to a weak pointer + /// Downgrades a strong pointer to a weak pointer. /// /// Weak pointers will not keep the data alive. Once all strong references /// to the underlying data have been dropped, the data itself will be @@ -224,7 +224,7 @@ impl<T: Sync + Send> Weak<T> { /// /// This method will fail to upgrade this reference if the strong reference /// count has already reached 0, but if there are still other active strong - /// references this function will return a new strong reference to the data + /// references this function will return a new strong reference to the data. pub fn upgrade(&self) -> Option<Arc<T>> { // We use a CAS loop to increment the strong count instead of a // fetch_add because once the count hits 0 is must never be above 0. diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 58278d5664e..6a3e1fa2862 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A unique pointer type +//! A unique pointer type. use core::any::{Any, AnyRefExt}; use core::clone::Clone; @@ -26,12 +26,14 @@ use core::result::{Ok, Err, Result}; /// /// The following two examples are equivalent: /// -/// use std::boxed::HEAP; +/// ```rust +/// use std::boxed::HEAP; /// -/// # struct Bar; -/// # impl Bar { fn new(_a: int) { } } -/// let foo = box(HEAP) Bar::new(2); -/// let foo = box Bar::new(2); +/// # struct Bar; +/// # impl Bar { fn new(_a: int) { } } +/// let foo = box(HEAP) Bar::new(2); +/// let foo = box Bar::new(2); +/// ``` #[lang = "exchange_heap"] #[experimental = "may be renamed; uncertain about custom allocator design"] pub static HEAP: () = (); @@ -47,11 +49,11 @@ impl<T: Default> Default for Box<T> { #[unstable] impl<T: Clone> Clone for Box<T> { - /// Return a copy of the owned box. + /// Returns a copy of the owned box. #[inline] fn clone(&self) -> Box<T> { box {(**self).clone()} } - /// Perform copy-assignment from `source` by reusing the existing allocation. + /// Performs copy-assignment from `source` by reusing the existing allocation. #[inline] fn clone_from(&mut self, source: &Box<T>) { (**self).clone_from(&(**source)); @@ -86,7 +88,7 @@ impl<T: Ord> Ord for Box<T> { } impl<T: Eq> Eq for Box<T> {} -/// Extension methods for an owning `Any` trait object +/// Extension methods for an owning `Any` trait object. #[unstable = "post-DST and coherence changes, this will not be a trait but \ rather a direct `impl` on `Box<Any>`"] pub trait BoxAny { diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 3175c516d8e..e2faa3240ed 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -15,7 +15,7 @@ #[cfg(not(test))] use core::raw; #[cfg(not(test))] use util; -/// Return a pointer to `size` bytes of memory. +/// Returns a pointer to `size` bytes of memory. /// /// Behavior is undefined if the requested size is 0 or the alignment is not a /// power of 2. The alignment must be no larger than the largest supported page @@ -25,7 +25,7 @@ pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 { imp::allocate(size, align) } -/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of +/// Extends or shrinks the allocation referenced by `ptr` to `size` bytes of /// memory. /// /// Behavior is undefined if the requested size is 0 or the alignment is not a @@ -41,10 +41,10 @@ pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint, imp::reallocate(ptr, size, align, old_size) } -/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of +/// Extends or shrinks the allocation referenced by `ptr` to `size` bytes of /// memory in-place. /// -/// Return true if successful, otherwise false if the allocation was not +/// Returns true if successful, otherwise false if the allocation was not /// altered. /// /// Behavior is undefined if the requested size is 0 or the alignment is not a @@ -60,7 +60,7 @@ pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint, imp::reallocate_inplace(ptr, size, align, old_size) } -/// Deallocate the memory referenced by `ptr`. +/// Deallocates the memory referenced by `ptr`. /// /// The `ptr` parameter must not be null. /// @@ -72,14 +72,14 @@ pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) { imp::deallocate(ptr, size, align) } -/// Return the usable size of an allocation created with the specified the +/// Returns the usable size of an allocation created with the specified the /// `size` and `align`. #[inline] pub fn usable_size(size: uint, align: uint) -> uint { imp::usable_size(size, align) } -/// Print implementation-defined allocator statistics. +/// Prints implementation-defined allocator statistics. /// /// These statistics may be inconsistent if other threads use the allocator /// during the call. @@ -88,7 +88,7 @@ pub fn stats_print() { imp::stats_print(); } -// The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size +// The compiler never calls `exchange_free` on Box<ZeroSizeType>, so zero-size // allocations can point to this `static`. It would be incorrect to use a null // pointer, due to enums assuming types like unique pointers are never null. pub static mut EMPTY: uint = 12345; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 7809c17d938..cacb9e28989 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Rust's core allocation library +//! # The Rust core allocation library //! //! This is the lowest level library through which allocation in Rust can be //! performed where the allocation is assumed to succeed. This library will @@ -23,13 +23,13 @@ //! //! ## Boxed values //! -//! The [`Box`](boxed/index.html) type is the core owned pointer type in rust. +//! The [`Box`](boxed/index.html) type is the core owned pointer type in Rust. //! There can only be one owner of a `Box`, and the owner can decide to mutate //! the contents, which live on the heap. //! //! This type can be sent among tasks efficiently as the size of a `Box` value -//! is just a pointer. Tree-like data structures are often built on owned -//! pointers because each node often has only one owner, the parent. +//! is the same as that of a pointer. Tree-like data structures are often built +//! with boxes because each node often has only one owner, the parent. //! //! ## Reference counted pointers //! @@ -37,8 +37,8 @@ //! type intended for sharing memory within a task. An `Rc` pointer wraps a //! type, `T`, and only allows access to `&T`, a shared reference. //! -//! This type is useful when inherited mutability is too constraining for an -//! application (such as using `Box`), and is often paired with the `Cell` or +//! This type is useful when inherited mutability (such as using `Box`) is too +//! constraining for an application, and is often paired with the `Cell` or //! `RefCell` types in order to allow mutation. //! //! ## Atomically reference counted pointers diff --git a/src/liballoc/libc_heap.rs b/src/liballoc/libc_heap.rs index 25938ba0d54..e3fa639929f 100644 --- a/src/liballoc/libc_heap.rs +++ b/src/liballoc/libc_heap.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -14,7 +14,7 @@ use libc::{c_void, size_t, free, malloc, realloc}; use core::ptr::{RawPtr, mut_null}; -/// A wrapper around libc::malloc, aborting on out-of-memory +/// A wrapper around libc::malloc, aborting on out-of-memory. #[inline] pub unsafe fn malloc_raw(size: uint) -> *mut u8 { // `malloc(0)` may allocate, but it may also return a null pointer @@ -30,7 +30,7 @@ pub unsafe fn malloc_raw(size: uint) -> *mut u8 { } } -/// A wrapper around libc::realloc, aborting on out-of-memory +/// A wrapper around libc::realloc, aborting on out-of-memory. #[inline] pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 { // `realloc(ptr, 0)` may allocate, but it may also return a null pointer diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 060f9875bfc..ec19844a24a 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -8,145 +8,142 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! Task-local reference-counted boxes (`Rc` type) - -The `Rc` type provides shared ownership of an immutable value. Destruction is -deterministic, and will occur as soon as the last owner is gone. It is marked -as non-sendable because it avoids the overhead of atomic reference counting. - -The `downgrade` method can be used to create a non-owning `Weak` pointer to the -box. A `Weak` pointer can be upgraded to an `Rc` pointer, but will return -`None` if the value has already been freed. - -For example, a tree with parent pointers can be represented by putting the -nodes behind strong `Rc` pointers, and then storing the parent pointers as -`Weak` pointers. - - -## Examples - -Consider a scenario where a set of Gadgets are owned by a given Owner. We want -to have our Gadgets point to their Owner. We can't do this with unique -ownership, because more than one gadget may belong to the same Owner. Rc -allows us to share an Owner between multiple Gadgets, and have the Owner kept -alive as long as any Gadget points at it. - -```rust -use std::rc::Rc; - -struct Owner { - name: String - // ...other fields -} - -struct Gadget { - id: int, - owner: Rc<Owner> - // ...other fields -} - -fn main() { - // Create a reference counted Owner. - let gadget_owner : Rc<Owner> = Rc::new( - Owner { name: String::from_str("Gadget Man") } - ); - - // Create Gadgets belonging to gadget_owner. To increment the reference - // count we clone the Rc object. - let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() }; - let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() }; - - drop(gadget_owner); - - // Despite dropping gadget_owner, we're still able to print out the name of - // the Owner of the Gadgets. This is because we've only dropped the - // reference count object, not the Owner it wraps. As long as there are - // other Rc objects pointing at the same Owner, it will stay alive. Notice - // that the Rc wrapper around Gadget.owner gets automatically dereferenced - // for us. - println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name); - println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name); - - // At the end of the method, gadget1 and gadget2 get destroyed, and with - // them the last counted references to our Owner. Gadget Man now gets - // destroyed as well. -} -``` - -If our requirements change, and we also need to be able to traverse from -Owner->Gadget, we will run into problems: an Rc pointer from Owner->Gadget -introduces a cycle between the objects. This means that their reference counts -can never reach 0, and the objects will stay alive: a memory leak. In order to -get around this, we can use `Weak` pointers. These are reference counted -pointers that don't keep an object alive if there are no normal `Rc` (or -*strong*) pointers left. - -Rust actually makes it somewhat difficult to produce this loop in the first -place: in order to end up with two objects that point at each other, one of -them needs to be mutable. This is problematic because Rc enforces memory -safety by only giving out shared references to the object it wraps, and these -don't allow direct mutation. We need to wrap the part of the object we wish to -mutate in a `RefCell`, which provides *interior mutability*: a method to -achieve mutability through a shared reference. `RefCell` enforces Rust's -borrowing rules at runtime. Read the `Cell` documentation for more details on -interior mutability. - -```rust -use std::rc::Rc; -use std::rc::Weak; -use std::cell::RefCell; - -struct Owner { - name: String, - gadgets: RefCell<Vec<Weak<Gadget>>> - // ...other fields -} - -struct Gadget { - id: int, - owner: Rc<Owner> - // ...other fields -} - -fn main() { - // Create a reference counted Owner. Note the fact that we've put the - // Owner's vector of Gadgets inside a RefCell so that we can mutate it - // through a shared reference. - let gadget_owner : Rc<Owner> = Rc::new( - Owner { - name: "Gadget Man".to_string(), - gadgets: RefCell::new(Vec::new()) - } - ); - - // Create Gadgets belonging to gadget_owner as before. - let gadget1 = Rc::new(Gadget{id: 1, owner: gadget_owner.clone()}); - let gadget2 = Rc::new(Gadget{id: 2, owner: gadget_owner.clone()}); - - // Add the Gadgets to their Owner. To do this we mutably borrow from - // the RefCell holding the Owner's Gadgets. - gadget_owner.gadgets.borrow_mut().push(gadget1.clone().downgrade()); - gadget_owner.gadgets.borrow_mut().push(gadget2.clone().downgrade()); - - // Iterate over our Gadgets, printing their details out - for gadget_opt in gadget_owner.gadgets.borrow().iter() { - - // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee - // that their object is still alive, we need to call upgrade() on them - // to turn them into a strong reference. This returns an Option, which - // contains a reference to our object if it still exists. - let gadget = gadget_opt.upgrade().unwrap(); - println!("Gadget {} owned by {}", gadget.id, gadget.owner.name); - } - - // At the end of the method, gadget_owner, gadget1 and gadget2 get - // destroyed. There are now no strong (Rc) references to the gadgets. - // Once they get destroyed, the Gadgets get destroyed. This zeroes the - // reference count on Gadget Man, so he gets destroyed as well. -} -``` - -*/ +//! Task-local reference-counted boxes (the `Rc` type). +//! +//! The `Rc` type provides shared ownership of an immutable value. Destruction is +//! deterministic, and will occur as soon as the last owner is gone. It is marked +//! as non-sendable because it avoids the overhead of atomic reference counting. +//! +//! The `downgrade` method can be used to create a non-owning `Weak` pointer to the +//! box. A `Weak` pointer can be upgraded to an `Rc` pointer, but will return +//! `None` if the value has already been freed. +//! +//! For example, a tree with parent pointers can be represented by putting the +//! nodes behind strong `Rc` pointers, and then storing the parent pointers as +//! `Weak` pointers. +//! +//! # Examples +//! +//! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. +//! We want to have our `Gadget`s point to their `Owner`. We can't do this with +//! unique ownership, because more than one gadget may belong to the same +//! `Owner`. `Rc` allows us to share an `Owner` between multiple `Gadget`s, and +//! have the `Owner` kept alive as long as any `Gadget` points at it. +//! +//! ```rust +//! use std::rc::Rc; +//! +//! struct Owner { +//! name: String +//! // ...other fields +//! } +//! +//! struct Gadget { +//! id: int, +//! owner: Rc<Owner> +//! // ...other fields +//! } +//! +//! fn main() { +//! // Create a reference counted Owner. +//! let gadget_owner : Rc<Owner> = Rc::new( +//! Owner { name: String::from_str("Gadget Man") } +//! ); +//! +//! // Create Gadgets belonging to gadget_owner. To increment the reference +//! // count we clone the Rc object. +//! let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() }; +//! let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() }; +//! +//! drop(gadget_owner); +//! +//! // Despite dropping gadget_owner, we're still able to print out the name of +//! // the Owner of the Gadgets. This is because we've only dropped the +//! // reference count object, not the Owner it wraps. As long as there are +//! // other Rc objects pointing at the same Owner, it will stay alive. Notice +//! // that the Rc wrapper around Gadget.owner gets automatically dereferenced +//! // for us. +//! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name); +//! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name); +//! +//! // At the end of the method, gadget1 and gadget2 get destroyed, and with +//! // them the last counted references to our Owner. Gadget Man now gets +//! // destroyed as well. +//! } +//! ``` +//! +//! If our requirements change, and we also need to be able to traverse from +//! Owner → Gadget, we will run into problems: an `Rc` pointer from Owner → Gadget +//! introduces a cycle between the objects. This means that their reference counts +//! can never reach 0, and the objects will stay alive: a memory leak. In order to +//! get around this, we can use `Weak` pointers. These are reference counted +//! pointers that don't keep an object alive if there are no normal `Rc` (or +//! *strong*) pointers left. +//! +//! Rust actually makes it somewhat difficult to produce this loop in the first +//! place: in order to end up with two objects that point at each other, one of +//! them needs to be mutable. This is problematic because `Rc` enforces memory +//! safety by only giving out shared references to the object it wraps, and these +//! don't allow direct mutation. We need to wrap the part of the object we wish to +//! mutate in a `RefCell`, which provides *interior mutability*: a method to +//! achieve mutability through a shared reference. `RefCell` enforces Rust's +//! borrowing rules at runtime. Read the `Cell` documentation for more details on +//! interior mutability. +//! +//! ```rust +//! use std::rc::Rc; +//! use std::rc::Weak; +//! use std::cell::RefCell; +//! +//! struct Owner { +//! name: String, +//! gadgets: RefCell<Vec<Weak<Gadget>>> +//! // ...other fields +//! } +//! +//! struct Gadget { +//! id: int, +//! owner: Rc<Owner> +//! // ...other fields +//! } +//! +//! fn main() { +//! // Create a reference counted Owner. Note the fact that we've put the +//! // Owner's vector of Gadgets inside a RefCell so that we can mutate it +//! // through a shared reference. +//! let gadget_owner : Rc<Owner> = Rc::new( +//! Owner { +//! name: "Gadget Man".to_string(), +//! gadgets: RefCell::new(Vec::new()) +//! } +//! ); +//! +//! // Create Gadgets belonging to gadget_owner as before. +//! let gadget1 = Rc::new(Gadget{id: 1, owner: gadget_owner.clone()}); +//! let gadget2 = Rc::new(Gadget{id: 2, owner: gadget_owner.clone()}); +//! +//! // Add the Gadgets to their Owner. To do this we mutably borrow from +//! // the RefCell holding the Owner's Gadgets. +//! gadget_owner.gadgets.borrow_mut().push(gadget1.clone().downgrade()); +//! gadget_owner.gadgets.borrow_mut().push(gadget2.clone().downgrade()); +//! +//! // Iterate over our Gadgets, printing their details out +//! for gadget_opt in gadget_owner.gadgets.borrow().iter() { +//! +//! // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee +//! // that their object is still alive, we need to call upgrade() on them +//! // to turn them into a strong reference. This returns an Option, which +//! // contains a reference to our object if it still exists. +//! let gadget = gadget_opt.upgrade().unwrap(); +//! println!("Gadget {} owned by {}", gadget.id, gadget.owner.name); +//! } +//! +//! // At the end of the method, gadget_owner, gadget1 and gadget2 get +//! // destroyed. There are now no strong (Rc) references to the gadgets. +//! // Once they get destroyed, the Gadgets get destroyed. This zeroes the +//! // reference count on Gadget Man, so he gets destroyed as well. +//! } +//! ``` #![stable] @@ -171,7 +168,7 @@ struct RcBox<T> { weak: Cell<uint> } -/// Immutable reference counted pointer type +/// An immutable reference-counted pointer type. #[unsafe_no_drop_flag] #[stable] pub struct Rc<T> { @@ -184,7 +181,7 @@ pub struct Rc<T> { #[stable] impl<T> Rc<T> { - /// Construct a new reference-counted box + /// Constructs a new reference-counted pointer. pub fn new(value: T) -> Rc<T> { unsafe { Rc { @@ -206,8 +203,8 @@ impl<T> Rc<T> { } impl<T> Rc<T> { - /// Downgrade the reference-counted pointer to a weak reference - #[experimental = "Weak pointers may not belong in this module."] + /// Downgrades the reference-counted pointer to a weak reference. + #[experimental = "Weak pointers may not belong in this module"] pub fn downgrade(&self) -> Weak<T> { self.inc_weak(); Weak { @@ -234,7 +231,7 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool { /// If the `Rc` does not have unique ownership, `Err` is returned with the /// same `Rc`. /// -/// # Example: +/// # Example /// /// ``` /// use std::rc::{mod, Rc}; @@ -267,7 +264,7 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { /// /// Returns `None` if the `Rc` does not have unique ownership. /// -/// # Example: +/// # Example /// /// ``` /// use std::rc::{mod, Rc}; @@ -312,7 +309,7 @@ impl<T: Clone> Rc<T> { #[experimental = "Deref is experimental."] impl<T> Deref<T> for Rc<T> { - /// Borrow the value contained in the reference-counted box + /// Borrows the value contained in the reference-counted pointer. #[inline(always)] fn deref(&self) -> &T { &self.inner().value @@ -404,7 +401,7 @@ impl<T: fmt::Show> fmt::Show for Rc<T> { } } -/// Weak reference to a reference-counted box +/// A weak reference to a reference-counted pointer. #[unsafe_no_drop_flag] #[experimental = "Weak pointers may not belong in this module."] pub struct Weak<T> { @@ -417,7 +414,10 @@ pub struct Weak<T> { #[experimental = "Weak pointers may not belong in this module."] impl<T> Weak<T> { - /// Upgrade a weak reference to a strong reference + /// Upgrades a weak reference to a strong reference. + /// + /// Returns `None` if there were no strong references and the data was + /// destroyed. pub fn upgrade(&self) -> Option<Rc<T>> { if self.strong() == 0 { None |
