Refactor the bounded pingpong example to avoid needing to generate unsafe code.
Took some steps towards bounded codegen.
This commit is contained in:
parent
88877effa8
commit
c28af26258
4 changed files with 55 additions and 26 deletions
|
@ -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<T: send> = {
|
|||
mut payload: option<T>,
|
||||
};
|
||||
|
||||
trait has_buffer {
|
||||
fn set_buffer(b: *libc::c_void);
|
||||
}
|
||||
|
||||
impl methods<T: send> of has_buffer for packet<T> {
|
||||
fn set_buffer(b: *libc::c_void) {
|
||||
self.header.buffer = b;
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_packet<T: send>() -> packet<T> {
|
||||
{
|
||||
header: packet_header(),
|
||||
|
@ -182,6 +192,16 @@ fn packet<T: send>() -> *packet<T> {
|
|||
p
|
||||
}
|
||||
|
||||
fn entangle_buffer<T: send, Tstart: send>(
|
||||
-buffer: ~buffer<T>,
|
||||
init: fn(*libc::c_void, x: &T) -> *packet<Tstart>)
|
||||
-> (send_packet_buffered<Tstart, T>, recv_packet_buffered<Tstart, T>)
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -98,23 +98,23 @@ impl methods for state {
|
|||
}
|
||||
}
|
||||
|
||||
enum protocol {
|
||||
protocol_(@{
|
||||
name: ident,
|
||||
states: dvec<state>,
|
||||
}),
|
||||
}
|
||||
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<state>;
|
||||
|
||||
let mut bounded: option<bool>;
|
||||
|
||||
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<Tproto, Tstate, Tmessage> {
|
||||
|
|
|
@ -22,13 +22,11 @@ mod pingpong {
|
|||
pong: mk_packet::<pong>()
|
||||
}
|
||||
};
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue