Skip to content

Commit c28af26

Browse files
committed
Refactor the bounded pingpong example to avoid needing to generate unsafe code.
Took some steps towards bounded codegen.
1 parent 88877ef commit c28af26

File tree

4 files changed

+55
-26
lines changed

4 files changed

+55
-26
lines changed

src/libcore/pipes.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import arc::methods;
88
// Things used by code generated by the pipe compiler.
99
export entangle, get_buffer, drop_buffer;
1010
export send_packet_buffered, recv_packet_buffered;
11-
export mk_packet;
11+
export mk_packet, entangle_buffer, has_buffer;
1212

1313
// export these so we can find them in the buffer_resource
1414
// destructor. This is probably another metadata bug.
@@ -151,6 +151,16 @@ type packet<T: send> = {
151151
mut payload: option<T>,
152152
};
153153

154+
trait has_buffer {
155+
fn set_buffer(b: *libc::c_void);
156+
}
157+
158+
impl methods<T: send> of has_buffer for packet<T> {
159+
fn set_buffer(b: *libc::c_void) {
160+
self.header.buffer = b;
161+
}
162+
}
163+
154164
fn mk_packet<T: send>() -> packet<T> {
155165
{
156166
header: packet_header(),
@@ -182,6 +192,16 @@ fn packet<T: send>() -> *packet<T> {
182192
p
183193
}
184194

195+
fn entangle_buffer<T: send, Tstart: send>(
196+
-buffer: ~buffer<T>,
197+
init: fn(*libc::c_void, x: &T) -> *packet<Tstart>)
198+
-> (send_packet_buffered<Tstart, T>, recv_packet_buffered<Tstart, T>)
199+
{
200+
let p = init(unsafe { reinterpret_cast(buffer) }, &buffer.data);
201+
unsafe { forget(buffer) }
202+
(send_packet_buffered(p), recv_packet_buffered(p))
203+
}
204+
185205
#[abi = "rust-intrinsic"]
186206
extern mod rusti {
187207
fn atomic_xchng(&dst: int, src: int) -> int;

src/libsyntax/ext/pipes/liveness.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ fn analyze(proto: protocol, _cx: ext_ctxt) {
8484
// involving these states: %s",
8585
// *proto.name,
8686
// states));
87+
88+
proto.bounded = some(false);
8789
}
8890
else {
8991
#debug("protocol %s is bounded. yay!", *proto.name);
92+
proto.bounded = some(true);
9093
}
9194
}

src/libsyntax/ext/pipes/proto.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,23 +98,23 @@ impl methods for state {
9898
}
9999
}
100100

101-
enum protocol {
102-
protocol_(@{
103-
name: ident,
104-
states: dvec<state>,
105-
}),
106-
}
101+
type protocol = @protocol_;
107102

108-
fn protocol(name: ident) -> protocol {
109-
protocol_(@{name: name, states: dvec()})
110-
}
103+
fn protocol(name: ident) -> protocol { @protocol_(name) }
111104

112-
impl methods for protocol {
113-
fn add_state(name: ident, dir: direction) -> state {
114-
self.add_state_poly(name, dir, ~[])
105+
class protocol_ {
106+
let name: ident;
107+
let states: dvec<state>;
108+
109+
let mut bounded: option<bool>;
110+
111+
new(name: ident) {
112+
self.name = name;
113+
self.states = dvec();
114+
self.bounded = none;
115115
}
116116

117-
/// Get or create a state.
117+
/// Get a state.
118118
fn get_state(name: ident) -> state {
119119
self.states.find(|i| i.name == name).get()
120120
}
@@ -125,6 +125,20 @@ impl methods for protocol {
125125
self.states.find(|i| i.name == name) != none
126126
}
127127

128+
fn filename() -> ~str {
129+
~"proto://" + *self.name
130+
}
131+
132+
fn num_states() -> uint { self.states.len() }
133+
134+
fn is_bounded() -> bool { self.bounded.get() }
135+
}
136+
137+
impl methods for protocol {
138+
fn add_state(name: ident, dir: direction) -> state {
139+
self.add_state_poly(name, dir, ~[])
140+
}
141+
128142
fn add_state_poly(name: ident, dir: direction,
129143
+ty_params: ~[ast::ty_param]) -> state {
130144
let messages = dvec();
@@ -141,12 +155,6 @@ impl methods for protocol {
141155
self.states.push(state);
142156
state
143157
}
144-
145-
fn filename() -> ~str {
146-
~"proto://" + *self.name
147-
}
148-
149-
fn num_states() -> uint { self.states.len() }
150158
}
151159

152160
trait visitor<Tproto, Tstate, Tmessage> {

src/test/run-pass/pipe-pingpong-bounded.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ mod pingpong {
2222
pong: mk_packet::<pong>()
2323
}
2424
};
25-
unsafe {
26-
buffer.data.ping.header.set_buffer(buffer);
27-
buffer.data.pong.header.set_buffer(buffer);
25+
do pipes::entangle_buffer(buffer) |buffer, data| {
26+
data.ping.set_buffer(buffer);
27+
data.pong.set_buffer(buffer);
28+
ptr::addr_of(data.ping)
2829
}
29-
let client = send_packet_buffered(ptr::addr_of(buffer.data.ping));
30-
let server = recv_packet_buffered(ptr::addr_of(buffer.data.ping));
31-
(client, server)
3230
}
3331
enum ping = server::pong;
3432
enum pong = client::ping;

0 commit comments

Comments
 (0)