diff options
| author | Eric Holk <eric.holk@gmail.com> | 2012-05-29 13:13:31 -0700 |
|---|---|---|
| committer | Eric Holk <eric.holk@gmail.com> | 2012-05-30 12:03:51 -0700 |
| commit | 6abddca18b432d37945bd2fda24bbc77fba970aa (patch) | |
| tree | 4f1594fc99f30f49295027b73290eeccd5b7c961 /src/libstd | |
| parent | dca11e1f99bcb3b1e645625113d188c8b1b43f8d (diff) | |
| download | rust-6abddca18b432d37945bd2fda24bbc77fba970aa.tar.gz rust-6abddca18b432d37945bd2fda24bbc77fba970aa.zip | |
Rewriting shared_arc to work around Issue #2444.
Sadly, this exposes another ICE when trying to use the new version with Graph500
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/arc.rs | 57 |
1 files changed, 42 insertions, 15 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<T: const>(rc: &arc<T>) -> arc<T> { // Convenience code for sharing arcs between tasks -enum proto<T: send const> { - terminate, - shared_get(comm::chan<arc::arc<T>>) -} +type get_chan<T: const send> = chan<chan<arc<T>>>; + +// (terminate, get) +type shared_arc<T: const send> = (shared_arc_res, get_chan<T>); -resource shared_arc_res<T: send const>(c: comm::chan<proto<T>>) { - c.send(terminate); +resource shared_arc_res(c: comm::chan<()>) { + c.send(()); } -fn shared_arc<T: send const>(-data: T) -> shared_arc_res<T> { +fn shared_arc<T: send const>(-data: T) -> shared_arc<T> { let a = arc::arc(data); - let c = task::spawn_listener::<proto<T>>() {|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<T: send const>(c: comm::chan<proto<T>>) -> arc::arc<T> { +fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> { 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() == (); + } } |
