From 6abddca18b432d37945bd2fda24bbc77fba970aa Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 29 May 2012 13:13:31 -0700 Subject: [PATCH] Rewriting shared_arc to work around Issue #2444. Sadly, this exposes another ICE when trying to use the new version with Graph500 --- src/libstd/arc.rs | 59 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 067191a855b..2b76f7f3b03 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -76,34 +76,42 @@ fn clone(rc: &arc) -> arc { // Convenience code for sharing arcs between tasks -enum proto { - terminate, - shared_get(comm::chan>) +type get_chan = chan>>; + +// (terminate, get) +type shared_arc = (shared_arc_res, get_chan); + +resource shared_arc_res(c: comm::chan<()>) { + c.send(()); } -resource shared_arc_res(c: comm::chan>) { - c.send(terminate); -} - -fn shared_arc(-data: T) -> shared_arc_res { +fn shared_arc(-data: T) -> shared_arc { let a = arc::arc(data); - let c = task::spawn_listener::>() {|p, move a| + let p = port(); + let c = chan(p); + task::spawn() {|move a| let mut live = true; + let terminate = port(); + let get = port(); + + c.send((chan(terminate), chan(get))); + while live { - alt p.recv() { - terminate { live = false; } - shared_get(cc) { - cc.send(arc::clone(&a)); + alt comm::select2(terminate, get) { + either::left(()) { live = false; } + either::right(cc) { + comm::send(cc, arc::clone(&a)); } } } }; - shared_arc_res(c) + let (terminate, get) = p.recv(); + (shared_arc_res(terminate), get) } -fn get_arc(c: comm::chan>) -> arc::arc { +fn get_arc(c: get_chan) -> arc::arc { let p = port(); - c.send(shared_get(chan(p))); + c.send(chan(p)); p.recv() } @@ -136,4 +144,23 @@ mod tests { log(info, arc_v); } + + #[test] + fn auto_share_arc() { + let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let (res, arc_c) = shared_arc(v); + + let p = port(); + let c = chan(p); + + task::spawn() {|| + let arc_v = get_arc(arc_c); + let v = *get(&arc_v); + assert v[2] == 3; + + c.send(()); + }; + + assert p.recv() == (); + } }