提交 7c9daa8f 编写于 作者: S Steven Fackler

Remove RcMut

Rc<Mut<T>> should be used instead
上级 0fade3a7
......@@ -14,10 +14,6 @@
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 `RcMut` type provides shared ownership of a mutable value. Since multiple owners prevent
inherited mutability, a dynamic freezing check is used to maintain the invariant that an `&mut`
reference is a unique handle and the type is marked as non-`Freeze`.
*/
use ptr::RawPtr;
......@@ -151,236 +147,3 @@ fn test_destructor() {
assert_eq!(**x.borrow(), 5);
}
}
#[deriving(Eq)]
enum Borrow {
Mutable,
Immutable,
Nothing
}
struct RcMutBox<T> {
value: T,
count: uint,
borrow: Borrow
}
/// Mutable reference counted pointer type
#[no_send]
#[no_freeze]
#[unsafe_no_drop_flag]
pub struct RcMut<T> {
priv ptr: *mut RcMutBox<T>,
}
impl<T: Freeze> RcMut<T> {
/// Construct a new mutable reference-counted box from a `Freeze` value
#[inline]
pub fn new(value: T) -> RcMut<T> {
unsafe { RcMut::new_unchecked(value) }
}
}
impl<T: Send> RcMut<T> {
/// Construct a new mutable reference-counted box from a `Send` value
#[inline]
pub fn from_send(value: T) -> RcMut<T> {
unsafe { RcMut::new_unchecked(value) }
}
}
impl<T> RcMut<T> {
/// Unsafety construct a new mutable reference-counted box from any value.
///
/// It is possible to create cycles, which will leak, and may interact
/// poorly with managed pointers.
#[inline]
pub unsafe fn new_unchecked(value: T) -> RcMut<T> {
RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})}
}
}
impl<T> RcMut<T> {
/// Fails if there is already a mutable borrow of the box
#[inline]
pub fn with_borrow<U>(&self, f: |&T| -> U) -> U {
unsafe {
assert!((*self.ptr).borrow != Mutable);
let previous = (*self.ptr).borrow;
(*self.ptr).borrow = Immutable;
let res = f(&(*self.ptr).value);
(*self.ptr).borrow = previous;
res
}
}
/// Fails if there is already a mutable or immutable borrow of the box
#[inline]
pub fn with_mut_borrow<U>(&self, f: |&mut T| -> U) -> U {
unsafe {
assert_eq!((*self.ptr).borrow, Nothing);
(*self.ptr).borrow = Mutable;
let res = f(&mut (*self.ptr).value);
(*self.ptr).borrow = Nothing;
res
}
}
}
#[unsafe_destructor]
impl<T> Drop for RcMut<T> {
fn drop(&mut self) {
unsafe {
if self.ptr.is_not_null() {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
let _: ~RcMutBox<T> = transmute(self.ptr);
}
}
}
}
}
impl<T> Clone for RcMut<T> {
/// Return a shallow copy of the reference counted pointer.
#[inline]
fn clone(&self) -> RcMut<T> {
unsafe {
(*self.ptr).count += 1;
RcMut{ptr: self.ptr}
}
}
}
impl<T: DeepClone> DeepClone for RcMut<T> {
/// Return a deep copy of the reference counted pointer.
#[inline]
fn deep_clone(&self) -> RcMut<T> {
do self.with_borrow |x| {
// FIXME: #6497: should avoid freeze (slow)
unsafe { RcMut::new_unchecked(x.deep_clone()) }
}
}
}
#[cfg(test)]
mod test_rc_mut {
use super::*;
#[test]
fn test_clone() {
let x = RcMut::from_send(5);
let y = x.clone();
do x.with_mut_borrow |value| {
*value = 20;
}
do y.with_borrow |value| {
assert_eq!(*value, 20);
}
}
#[test]
fn test_deep_clone() {
let x = RcMut::new(5);
let y = x.deep_clone();
do x.with_mut_borrow |value| {
*value = 20;
}
do y.with_borrow |value| {
assert_eq!(*value, 5);
}
}
#[test]
fn borrow_many() {
let x = RcMut::from_send(5);
let y = x.clone();
do x.with_borrow |a| {
assert_eq!(*a, 5);
do y.with_borrow |b| {
assert_eq!(*b, 5);
do x.with_borrow |c| {
assert_eq!(*c, 5);
}
}
}
}
#[test]
fn modify() {
let x = RcMut::new(5);
let y = x.clone();
do y.with_mut_borrow |a| {
assert_eq!(*a, 5);
*a = 6;
}
do x.with_borrow |a| {
assert_eq!(*a, 6);
}
}
#[test]
fn release_immutable() {
let x = RcMut::from_send(5);
do x.with_borrow |_| {}
do x.with_mut_borrow |_| {}
}
#[test]
fn release_mutable() {
let x = RcMut::new(5);
do x.with_mut_borrow |_| {}
do x.with_borrow |_| {}
}
#[test]
#[should_fail]
fn frozen() {
let x = RcMut::from_send(5);
let y = x.clone();
do x.with_borrow |_| {
do y.with_mut_borrow |_| {
}
}
}
#[test]
#[should_fail]
fn mutable_dupe() {
let x = RcMut::new(5);
let y = x.clone();
do x.with_mut_borrow |_| {
do y.with_mut_borrow |_| {
}
}
}
#[test]
#[should_fail]
fn mutable_freeze() {
let x = RcMut::from_send(5);
let y = x.clone();
do x.with_mut_borrow |_| {
do y.with_borrow |_| {
}
}
}
#[test]
#[should_fail]
fn restore_freeze() {
let x = RcMut::new(5);
let y = x.clone();
do x.with_borrow |_| {
do x.with_borrow |_| {}
do y.with_mut_borrow |_| {}
}
}
}
......@@ -8,21 +8,22 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::rc::RcMut;
use std::rc::Rc;
use std::mutable::Mut;
trait Foo
{
fn set(&mut self, v: RcMut<A>);
fn set(&mut self, v: Rc<Mut<A>>);
}
struct B
{
v: Option<RcMut<A>>
v: Option<Rc<Mut<A>>>
}
impl Foo for B
{
fn set(&mut self, v: RcMut<A>)
fn set(&mut self, v: Rc<Mut<A>>)
{
self.v = Some(v);
}
......@@ -36,7 +37,9 @@ struct A
fn main()
{
let a = A {v: ~B{v: None} as ~Foo}; //~ ERROR cannot pack type `~B`, which does not fulfill `Send`
let v = RcMut::new(a); //~ ERROR instantiating a type parameter with an incompatible type
let v = Rc::from_send(Mut::new(a));
let w = v.clone();
v.with_mut_borrow(|p| {p.v.set(w.clone());})
let b = v.borrow();
let mut b = b.borrow_mut();
b.get().v.set(w.clone());
}
......@@ -8,13 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::rc::RcMut;
use std::mutable::Mut;
use std::rc::Rc;
fn o<T: Send>(_: &T) {}
fn c<T: Freeze>(_: &T) {}
fn main() {
let x = RcMut::from_send(0);
o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut<int>`, which does not fulfill `Send`
c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut<int>`, which does not fulfill `Freeze`
let x = Rc::from_send(Mut::new(0));
o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::mutable::Mut<int>>`, which does not fulfill `Send`
c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::mutable::Mut<int>>`, which does not fulfill `Freeze`
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册