Use region variance to remove a bunch of unsafety in sync/arc (#2282)
This commit is contained in:
parent
8d00603d78
commit
4cfb92f459
2 changed files with 15 additions and 54 deletions
|
@ -182,16 +182,9 @@ impl<T: send> &mutex_arc<T> {
|
||||||
do (&state.lock).lock_cond |cond| {
|
do (&state.lock).lock_cond |cond| {
|
||||||
check_poison(true, state.failed);
|
check_poison(true, state.failed);
|
||||||
let _z = poison_on_fail(&mut state.failed);
|
let _z = poison_on_fail(&mut state.failed);
|
||||||
/*
|
|
||||||
blk(&mut state.data,
|
blk(&mut state.data,
|
||||||
&condvar { is_mutex: true, failed: &mut state.failed,
|
&condvar { is_mutex: true, failed: &mut state.failed,
|
||||||
cond: cond })
|
cond: cond })
|
||||||
*/
|
|
||||||
// FIXME(#2282) region variance
|
|
||||||
let fref =
|
|
||||||
unsafe { unsafe::transmute_mut_region(&mut state.failed) };
|
|
||||||
let cvar = condvar { is_mutex: true, failed: fref, cond: cond };
|
|
||||||
blk(&mut state.data, unsafe { unsafe::transmute_region(&cvar) } )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,17 +295,9 @@ impl<T: const send> &rw_arc<T> {
|
||||||
do borrow_rwlock(state).write_cond |cond| {
|
do borrow_rwlock(state).write_cond |cond| {
|
||||||
check_poison(false, state.failed);
|
check_poison(false, state.failed);
|
||||||
let _z = poison_on_fail(&mut state.failed);
|
let _z = poison_on_fail(&mut state.failed);
|
||||||
/*
|
|
||||||
blk(&mut state.data,
|
blk(&mut state.data,
|
||||||
&condvar { is_mutex: false, failed: &mut state.failed,
|
&condvar { is_mutex: false, failed: &mut state.failed,
|
||||||
cond: cond })
|
cond: cond })
|
||||||
*/
|
|
||||||
// FIXME(#2282): Need region variance to use the commented-out
|
|
||||||
// code above instead of this casting mess
|
|
||||||
let fref =
|
|
||||||
unsafe { unsafe::transmute_mut_region(&mut state.failed) };
|
|
||||||
let cvar = condvar { is_mutex: false, failed: fref, cond: cond };
|
|
||||||
blk(&mut state.data, unsafe { unsafe::transmute_region(&cvar) } )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -353,11 +338,8 @@ impl<T: const send> &rw_arc<T> {
|
||||||
let state = unsafe { get_shared_mutable_state(&self.x) };
|
let state = unsafe { get_shared_mutable_state(&self.x) };
|
||||||
do borrow_rwlock(state).write_downgrade |write_mode| {
|
do borrow_rwlock(state).write_downgrade |write_mode| {
|
||||||
check_poison(false, state.failed);
|
check_poison(false, state.failed);
|
||||||
// FIXME(#2282) need region variance to avoid having to cast here
|
blk(rw_write_mode((&mut state.data, write_mode,
|
||||||
let (data,failed) =
|
poison_on_fail(&mut state.failed))))
|
||||||
unsafe { (unsafe::transmute_mut_region(&mut state.data),
|
|
||||||
unsafe::transmute_mut_region(&mut state.failed)) };
|
|
||||||
blk(rw_write_mode((data, write_mode, poison_on_fail(failed))))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,8 +383,8 @@ fn unwrap_rw_arc<T: const send>(+arc: rw_arc<T>) -> T {
|
||||||
// lock it. This wraps the unsafety, with the justification that the 'lock'
|
// lock it. This wraps the unsafety, with the justification that the 'lock'
|
||||||
// field is never overwritten; only 'failed' and 'data'.
|
// field is never overwritten; only 'failed' and 'data'.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn borrow_rwlock<T: const send>(state: &mut rw_arc_inner<T>) -> &rwlock {
|
fn borrow_rwlock<T: const send>(state: &r/mut rw_arc_inner<T>) -> &r/rwlock {
|
||||||
unsafe { unsafe::reinterpret_cast(&state.lock) }
|
unsafe { unsafe::transmute_immut(&mut state.lock) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME (#3154) ice with struct/&<T> prevents these from being structs.
|
// FIXME (#3154) ice with struct/&<T> prevents these from being structs.
|
||||||
|
@ -418,9 +400,7 @@ impl<T: const send> &rw_write_mode<T> {
|
||||||
fn write<U>(blk: fn(x: &mut T) -> U) -> U {
|
fn write<U>(blk: fn(x: &mut T) -> U) -> U {
|
||||||
match *self {
|
match *self {
|
||||||
rw_write_mode((data, ref token, _)) => {
|
rw_write_mode((data, ref token, _)) => {
|
||||||
// FIXME(#2282) cast to avoid region invariance
|
do token.write {
|
||||||
let mode = unsafe { unsafe::transmute_region(token) };
|
|
||||||
do mode.write {
|
|
||||||
blk(data)
|
blk(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,13 +410,10 @@ impl<T: const send> &rw_write_mode<T> {
|
||||||
fn write_cond<U>(blk: fn(x: &x/mut T, c: &c/condvar) -> U) -> U {
|
fn write_cond<U>(blk: fn(x: &x/mut T, c: &c/condvar) -> U) -> U {
|
||||||
match *self {
|
match *self {
|
||||||
rw_write_mode((data, ref token, ref poison)) => {
|
rw_write_mode((data, ref token, ref poison)) => {
|
||||||
// FIXME(#2282) cast to avoid region invariance
|
do token.write_cond |cond| {
|
||||||
let mode = unsafe { unsafe::transmute_region(token) };
|
|
||||||
do mode.write_cond |cond| {
|
|
||||||
let cvar = condvar {
|
let cvar = condvar {
|
||||||
is_mutex: false, failed: poison.failed,
|
is_mutex: false, failed: poison.failed,
|
||||||
cond: unsafe { unsafe::reinterpret_cast(cond) } };
|
cond: cond };
|
||||||
// FIXME(#2282) region variance would avoid having to cast
|
|
||||||
blk(data, &cvar)
|
blk(data, &cvar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,9 +426,7 @@ impl<T: const send> &rw_read_mode<T> {
|
||||||
fn read<U>(blk: fn(x: &T) -> U) -> U {
|
fn read<U>(blk: fn(x: &T) -> U) -> U {
|
||||||
match *self {
|
match *self {
|
||||||
rw_read_mode((data, ref token)) => {
|
rw_read_mode((data, ref token)) => {
|
||||||
// FIXME(#2282) cast to avoid region invariance
|
do token.read { blk(data) }
|
||||||
let mode = unsafe { unsafe::transmute_region(token) };
|
|
||||||
do mode.read { blk(data) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -593,9 +568,7 @@ mod tests {
|
||||||
let arc2 = ~arc.clone();
|
let arc2 = ~arc.clone();
|
||||||
do task::try {
|
do task::try {
|
||||||
do arc2.write_downgrade |write_mode| {
|
do arc2.write_downgrade |write_mode| {
|
||||||
// FIXME(#2282)
|
do (&write_mode).write |one| {
|
||||||
let mode = unsafe { unsafe::transmute_region(&write_mode) };
|
|
||||||
do mode.write |one| {
|
|
||||||
assert *one == 2;
|
assert *one == 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -637,9 +610,7 @@ mod tests {
|
||||||
do task::try {
|
do task::try {
|
||||||
do arc2.write_downgrade |write_mode| {
|
do arc2.write_downgrade |write_mode| {
|
||||||
let read_mode = arc2.downgrade(write_mode);
|
let read_mode = arc2.downgrade(write_mode);
|
||||||
// FIXME(#2282)
|
do (&read_mode).read |one| {
|
||||||
let mode = unsafe { unsafe::transmute_region(&read_mode) };
|
|
||||||
do mode.read |one| {
|
|
||||||
assert *one == 2;
|
assert *one == 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -728,9 +699,7 @@ mod tests {
|
||||||
|
|
||||||
// Downgrader (us)
|
// Downgrader (us)
|
||||||
do arc.write_downgrade |write_mode| {
|
do arc.write_downgrade |write_mode| {
|
||||||
// FIXME(#2282)
|
do (&write_mode).write_cond |state, cond| {
|
||||||
let mode = unsafe { unsafe::transmute_region(&write_mode) };
|
|
||||||
do mode.write_cond |state, cond| {
|
|
||||||
wc1.send(()); // send to another writer who will wake us up
|
wc1.send(()); // send to another writer who will wake us up
|
||||||
while *state == 0 {
|
while *state == 0 {
|
||||||
cond.wait();
|
cond.wait();
|
||||||
|
@ -745,9 +714,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let read_mode = arc.downgrade(write_mode);
|
let read_mode = arc.downgrade(write_mode);
|
||||||
// FIXME(#2282)
|
do (&read_mode).read |state| {
|
||||||
let mode = unsafe { unsafe::transmute_region(&read_mode) };
|
|
||||||
do mode.read |state| {
|
|
||||||
// complete handshake with other readers
|
// complete handshake with other readers
|
||||||
for vec::each(reader_convos) |x| {
|
for vec::each(reader_convos) |x| {
|
||||||
match x {
|
match x {
|
||||||
|
|
|
@ -998,16 +998,12 @@ mod tests {
|
||||||
write => x.write(blk),
|
write => x.write(blk),
|
||||||
downgrade =>
|
downgrade =>
|
||||||
do x.write_downgrade |mode| {
|
do x.write_downgrade |mode| {
|
||||||
// FIXME(#2282)
|
(&mode).write(blk);
|
||||||
let mode = unsafe { unsafe::transmute_region(&mode) };
|
|
||||||
mode.write(blk);
|
|
||||||
},
|
},
|
||||||
downgrade_read =>
|
downgrade_read =>
|
||||||
do x.write_downgrade |mode| {
|
do x.write_downgrade |mode| {
|
||||||
let mode = x.downgrade(mode);
|
let mode = x.downgrade(mode);
|
||||||
// FIXME(#2282)
|
(&mode).read(blk);
|
||||||
let mode = unsafe { unsafe::transmute_region(&mode) };
|
|
||||||
mode.read(blk);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1152,9 +1148,7 @@ mod tests {
|
||||||
fn lock_cond(x: &rwlock, downgrade: bool, blk: fn(c: &condvar)) {
|
fn lock_cond(x: &rwlock, downgrade: bool, blk: fn(c: &condvar)) {
|
||||||
if downgrade {
|
if downgrade {
|
||||||
do x.write_downgrade |mode| {
|
do x.write_downgrade |mode| {
|
||||||
// FIXME(#2282)
|
(&mode).write_cond(blk)
|
||||||
let mode = unsafe { unsafe::transmute_region(&mode) };
|
|
||||||
mode.write_cond(blk)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x.write_cond(blk)
|
x.write_cond(blk)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue