1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
extern crate atomic_refcell;
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
struct Foo {
u: u32,
}
struct Bar {
f: Foo,
}
impl Default for Bar {
fn default() -> Self {
Bar { f: Foo { u: 42 } }
}
}
// FIXME(bholley): Add tests to exercise this in concurrent scenarios.
#[test]
fn immutable() {
let a = AtomicRefCell::new(Bar::default());
let _first = a.borrow();
let _second = a.borrow();
}
#[test]
fn mutable() {
let a = AtomicRefCell::new(Bar::default());
let _ = a.borrow_mut();
}
#[test]
fn interleaved() {
let a = AtomicRefCell::new(Bar::default());
{
let _ = a.borrow_mut();
}
{
let _first = a.borrow();
let _second = a.borrow();
}
{
let _ = a.borrow_mut();
}
}
#[test]
#[should_panic(expected = "already immutably borrowed")]
fn immutable_then_mutable() {
let a = AtomicRefCell::new(Bar::default());
let _first = a.borrow();
let _second = a.borrow_mut();
}
#[test]
#[should_panic(expected = "already mutably borrowed")]
fn mutable_then_immutable() {
let a = AtomicRefCell::new(Bar::default());
let _first = a.borrow_mut();
let _second = a.borrow();
}
#[test]
#[should_panic(expected = "already mutably borrowed")]
fn double_mutable() {
let a = AtomicRefCell::new(Bar::default());
let _first = a.borrow_mut();
let _second = a.borrow_mut();
}
#[test]
fn map() {
let a = AtomicRefCell::new(Bar::default());
let b = a.borrow();
assert_eq!(b.f.u, 42);
let c = AtomicRef::map(b, |x| &x.f);
assert_eq!(c.u, 42);
let d = AtomicRef::map(c, |x| &x.u);
assert_eq!(*d, 42);
}
#[test]
fn map_mut() {
let a = AtomicRefCell::new(Bar::default());
let mut b = a.borrow_mut();
assert_eq!(b.f.u, 42);
b.f.u = 43;
let mut c = AtomicRefMut::map(b, |x| &mut x.f);
assert_eq!(c.u, 43);
c.u = 44;
let mut d = AtomicRefMut::map(c, |x| &mut x.u);
assert_eq!(*d, 44);
*d = 45;
assert_eq!(*d, 45);
}
|