From 6535da84176bb1a72871a89740b0def9221cc351 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 18 Jul 2012 15:03:46 -0700 Subject: [PATCH] Tighten pipe exports, and refactor traits. --- src/libcore/iter-trait/dlist.rs | 2 +- src/libcore/iter-trait/option.rs | 2 +- src/libcore/pipes.rs | 73 +++++++++++++++++++++----------- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/libcore/iter-trait/dlist.rs b/src/libcore/iter-trait/dlist.rs index 1cf7fb980cd2..a94ed6a54dc1 100644 --- a/src/libcore/iter-trait/dlist.rs +++ b/src/libcore/iter-trait/dlist.rs @@ -7,7 +7,7 @@ type IMPL_T = dlist::dlist; * e.g. breadth-first search with in-place enqueues), but removing the current * node is forbidden. */ -fn EACH(self: IMPL_T, f: fn(A) -> bool) { +pure fn EACH(self: IMPL_T, f: fn(A) -> bool) { import dlist::extensions; let mut link = self.peek_n(); diff --git a/src/libcore/iter-trait/option.rs b/src/libcore/iter-trait/option.rs index 530de27c614c..87763b273da6 100644 --- a/src/libcore/iter-trait/option.rs +++ b/src/libcore/iter-trait/option.rs @@ -1,6 +1,6 @@ type IMPL_T = option; -fn EACH(self: IMPL_T, f: fn(A) -> bool) { +pure fn EACH(self: IMPL_T, f: fn(A) -> bool) { alt self { none { } some(a) { f(a); } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 44e54fb0fd4b..2e463df9e900 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -5,17 +5,22 @@ import either::{either, left, right}; import option::unwrap; import arc::methods; -/* Use this after the snapshot +// Things used by code generated by the pipe compiler. +export entangle; + +// User-level things +export send_packet, recv_packet, send, recv, try_recv, peek; +export select, select2, selecti, select2i, selectable; +export spawn_service, spawn_service_recv; +export stream, port, chan, shared_chan, port_set, channel; + macro_rules! move { { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } } -*/ -fn macros() { - #macro[ - [#move(x), { unsafe { let y <- *ptr::addr_of(x); y } }] - ]; -} +// This is to help make sure we only move out of enums in safe +// places. Once there is unary move, it can be removed. +fn move(-x: T) -> T { x } enum state { empty, @@ -465,6 +470,19 @@ proto! streamp { } } +// It'd be nice to call this send, but it'd conflict with the built in +// send kind. +trait channel { + fn send(+x: T); +} + +trait recv { + fn recv() -> T; + fn try_recv() -> option; + // This should perhaps be a new trait + pure fn peek() -> bool; +} + type chan_ = { mut endp: option> }; enum chan { @@ -483,7 +501,7 @@ fn stream() -> (chan, port) { (chan_({ mut endp: some(c) }), port_({ mut endp: some(s) })) } -impl chan for chan { +impl chan of channel for chan { fn send(+x: T) { let mut endp = none; endp <-> self.endp; @@ -492,7 +510,7 @@ impl chan for chan { } } -impl port for port { +impl port of recv for port { fn recv() -> T { let mut endp = none; endp <-> self.endp; @@ -504,10 +522,10 @@ impl port for port { fn try_recv() -> option { let mut endp = none; endp <-> self.endp; - alt pipes::try_recv(unwrap(endp)) { + alt move(pipes::try_recv(unwrap(endp))) { some(streamp::data(x, endp)) { - self.endp = some(#move(endp)); - some(#move(x)) + self.endp = some(move!{endp}); + some(move!{x}) } none { none } } @@ -528,7 +546,7 @@ impl port for port { } // Treat a whole bunch of ports as one. -class port_set { +class port_set : recv { let mut ports: ~[pipes::port]; new() { self.ports = ~[]; } @@ -540,12 +558,12 @@ class port_set { fn try_recv() -> option { let mut result = none; while result == none && self.ports.len() > 0 { - let i = pipes::wait_many(self.ports.map(|p| p.header())); + let i = wait_many(self.ports.map(|p| p.header())); // dereferencing an unsafe pointer nonsense to appease the // borrowchecker. - alt unsafe {(*ptr::addr_of(self.ports[i])).try_recv()} { + alt move(unsafe {(*ptr::addr_of(self.ports[i])).try_recv()}) { some(m) { - result = some(#move(m)); + result = some(move!{m}); } none { // Remove this port. @@ -562,10 +580,19 @@ class port_set { fn recv() -> T { option::unwrap(self.try_recv()) } + + pure fn peek() -> bool { + // It'd be nice to use self.port.each, but that version isn't + // pure. + for vec::each(self.ports) |p| { + if p.peek() { ret true } + } + false + } } -impl of selectable for pipes::port { - pure fn header() -> *pipes::packet_header unchecked { +impl of selectable for port { + pure fn header() -> *packet_header unchecked { alt self.endp { some(endp) { endp.header() @@ -576,13 +603,9 @@ impl of selectable for pipes::port { } -type shared_chan = arc::exclusive>; +type shared_chan = arc::exclusive>; -trait send_on_shared_chan { - fn send(+x: T); -} - -impl chan of send_on_shared_chan for shared_chan { +impl chan of channel for shared_chan { fn send(+x: T) { let mut xx = some(x); do self.with |_c, chan| { @@ -593,6 +616,6 @@ impl chan of send_on_shared_chan for shared_chan { } } -fn shared_chan(+c: pipes::chan) -> shared_chan { +fn shared_chan(+c: chan) -> shared_chan { arc::exclusive(c) }