Skip to content

Commit 6abddca

Browse files
committed
Rewriting shared_arc to work around Issue #2444.
Sadly, this exposes another ICE when trying to use the new version with Graph500
1 parent dca11e1 commit 6abddca

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

src/libstd/arc.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,34 +76,42 @@ fn clone<T: const>(rc: &arc<T>) -> arc<T> {
7676

7777
// Convenience code for sharing arcs between tasks
7878

79-
enum proto<T: send const> {
80-
terminate,
81-
shared_get(comm::chan<arc::arc<T>>)
82-
}
79+
type get_chan<T: const send> = chan<chan<arc<T>>>;
80+
81+
// (terminate, get)
82+
type shared_arc<T: const send> = (shared_arc_res, get_chan<T>);
8383

84-
resource shared_arc_res<T: send const>(c: comm::chan<proto<T>>) {
85-
c.send(terminate);
84+
resource shared_arc_res(c: comm::chan<()>) {
85+
c.send(());
8686
}
8787

88-
fn shared_arc<T: send const>(-data: T) -> shared_arc_res<T> {
88+
fn shared_arc<T: send const>(-data: T) -> shared_arc<T> {
8989
let a = arc::arc(data);
90-
let c = task::spawn_listener::<proto<T>>() {|p, move a|
90+
let p = port();
91+
let c = chan(p);
92+
task::spawn() {|move a|
9193
let mut live = true;
94+
let terminate = port();
95+
let get = port();
96+
97+
c.send((chan(terminate), chan(get)));
98+
9299
while live {
93-
alt p.recv() {
94-
terminate { live = false; }
95-
shared_get(cc) {
96-
cc.send(arc::clone(&a));
100+
alt comm::select2(terminate, get) {
101+
either::left(()) { live = false; }
102+
either::right(cc) {
103+
comm::send(cc, arc::clone(&a));
97104
}
98105
}
99106
}
100107
};
101-
shared_arc_res(c)
108+
let (terminate, get) = p.recv();
109+
(shared_arc_res(terminate), get)
102110
}
103111

104-
fn get_arc<T: send const>(c: comm::chan<proto<T>>) -> arc::arc<T> {
112+
fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> {
105113
let p = port();
106-
c.send(shared_get(chan(p)));
114+
c.send(chan(p));
107115
p.recv()
108116
}
109117

@@ -136,4 +144,23 @@ mod tests {
136144

137145
log(info, arc_v);
138146
}
147+
148+
#[test]
149+
fn auto_share_arc() {
150+
let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
151+
let (res, arc_c) = shared_arc(v);
152+
153+
let p = port();
154+
let c = chan(p);
155+
156+
task::spawn() {||
157+
let arc_v = get_arc(arc_c);
158+
let v = *get(&arc_v);
159+
assert v[2] == 3;
160+
161+
c.send(());
162+
};
163+
164+
assert p.recv() == ();
165+
}
139166
}

0 commit comments

Comments
 (0)