diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 3bb2467f3df4..82b2d31a0be6 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -8,7 +8,7 @@ import arc::methods; // Things used by code generated by the pipe compiler. export entangle, get_buffer, drop_buffer; export send_packet_buffered, recv_packet_buffered; -export mk_packet; +export mk_packet, entangle_buffer, has_buffer; // export these so we can find them in the buffer_resource // destructor. This is probably another metadata bug. @@ -151,6 +151,16 @@ type packet = { mut payload: option, }; +trait has_buffer { + fn set_buffer(b: *libc::c_void); +} + +impl methods of has_buffer for packet { + fn set_buffer(b: *libc::c_void) { + self.header.buffer = b; + } +} + fn mk_packet() -> packet { { header: packet_header(), @@ -182,6 +192,16 @@ fn packet() -> *packet { p } +fn entangle_buffer( + -buffer: ~buffer, + init: fn(*libc::c_void, x: &T) -> *packet) + -> (send_packet_buffered, recv_packet_buffered) +{ + let p = init(unsafe { reinterpret_cast(buffer) }, &buffer.data); + unsafe { forget(buffer) } + (send_packet_buffered(p), recv_packet_buffered(p)) +} + #[abi = "rust-intrinsic"] extern mod rusti { fn atomic_xchng(&dst: int, src: int) -> int; diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index 4f8039925202..d8467e36c84e 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -84,8 +84,11 @@ fn analyze(proto: protocol, _cx: ext_ctxt) { // involving these states: %s", // *proto.name, // states)); + + proto.bounded = some(false); } else { #debug("protocol %s is bounded. yay!", *proto.name); + proto.bounded = some(true); } } \ No newline at end of file diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index e9070c79b558..8a535e851888 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -98,23 +98,23 @@ impl methods for state { } } -enum protocol { - protocol_(@{ - name: ident, - states: dvec, - }), -} +type protocol = @protocol_; -fn protocol(name: ident) -> protocol { - protocol_(@{name: name, states: dvec()}) -} +fn protocol(name: ident) -> protocol { @protocol_(name) } -impl methods for protocol { - fn add_state(name: ident, dir: direction) -> state { - self.add_state_poly(name, dir, ~[]) +class protocol_ { + let name: ident; + let states: dvec; + + let mut bounded: option; + + new(name: ident) { + self.name = name; + self.states = dvec(); + self.bounded = none; } - /// Get or create a state. + /// Get a state. fn get_state(name: ident) -> state { self.states.find(|i| i.name == name).get() } @@ -125,6 +125,20 @@ impl methods for protocol { self.states.find(|i| i.name == name) != none } + fn filename() -> ~str { + ~"proto://" + *self.name + } + + fn num_states() -> uint { self.states.len() } + + fn is_bounded() -> bool { self.bounded.get() } +} + +impl methods for protocol { + fn add_state(name: ident, dir: direction) -> state { + self.add_state_poly(name, dir, ~[]) + } + fn add_state_poly(name: ident, dir: direction, +ty_params: ~[ast::ty_param]) -> state { let messages = dvec(); @@ -141,12 +155,6 @@ impl methods for protocol { self.states.push(state); state } - - fn filename() -> ~str { - ~"proto://" + *self.name - } - - fn num_states() -> uint { self.states.len() } } trait visitor { diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs index bad605b8929e..c8b0dc3006a7 100644 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ b/src/test/run-pass/pipe-pingpong-bounded.rs @@ -22,13 +22,11 @@ mod pingpong { pong: mk_packet::() } }; - unsafe { - buffer.data.ping.header.set_buffer(buffer); - buffer.data.pong.header.set_buffer(buffer); + do pipes::entangle_buffer(buffer) |buffer, data| { + data.ping.set_buffer(buffer); + data.pong.set_buffer(buffer); + ptr::addr_of(data.ping) } - let client = send_packet_buffered(ptr::addr_of(buffer.data.ping)); - let server = recv_packet_buffered(ptr::addr_of(buffer.data.ping)); - (client, server) } enum ping = server::pong; enum pong = client::ping;