Updating tests to use pipes.
This commit is contained in:
@@ -138,6 +138,15 @@ fn with<A,B>(future: future<A>, blk: fn(A) -> B) -> B {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The pipe protocol, generated by pipec
|
// The pipe protocol, generated by pipec
|
||||||
|
/*
|
||||||
|
proto! future_pipe {
|
||||||
|
waiting:recv<T:send> {
|
||||||
|
completed(T) -> terminated
|
||||||
|
}
|
||||||
|
|
||||||
|
terminated { }
|
||||||
|
}
|
||||||
|
*/
|
||||||
mod future_pipe {
|
mod future_pipe {
|
||||||
fn init<T: send>() -> (client::waiting<T>, server::waiting<T>) {
|
fn init<T: send>() -> (client::waiting<T>, server::waiting<T>) {
|
||||||
{ let (s, c) = pipes::entangle(); (c, s) }
|
{ let (s, c) = pipes::entangle(); (c, s) }
|
||||||
|
|||||||
@@ -10,11 +10,10 @@ impl proto_parser for parser {
|
|||||||
fn parse_proto(id: ident) -> protocol {
|
fn parse_proto(id: ident) -> protocol {
|
||||||
let proto = protocol(id);
|
let proto = protocol(id);
|
||||||
|
|
||||||
self.expect(token::LBRACE);
|
self.parse_unspanned_seq(token::LBRACE,
|
||||||
|
token::RBRACE,
|
||||||
while self.token != token::RBRACE {
|
{sep: none, trailing_sep_allowed: false},
|
||||||
self.parse_state(proto);
|
|self| self.parse_state(proto));
|
||||||
}
|
|
||||||
|
|
||||||
ret proto;
|
ret proto;
|
||||||
}
|
}
|
||||||
@@ -35,29 +34,44 @@ impl proto_parser for parser {
|
|||||||
_ { fail }
|
_ { fail }
|
||||||
};
|
};
|
||||||
|
|
||||||
let state = proto.add_state(id, dir);
|
let typarms = if self.token == token::LT {
|
||||||
// TODO: add typarams too.
|
self.parse_ty_params()
|
||||||
|
}
|
||||||
|
else { ~[] };
|
||||||
|
|
||||||
self.expect(token::LBRACE);
|
let state = proto.add_state_poly(id, dir, typarms);
|
||||||
|
|
||||||
while self.token != token::RBRACE {
|
// parse the messages
|
||||||
|
self.parse_unspanned_seq(
|
||||||
|
token::LBRACE, token::RBRACE,
|
||||||
|
{sep: some(token::COMMA), trailing_sep_allowed: true},
|
||||||
|
|self| {
|
||||||
let mname = self.parse_ident();
|
let mname = self.parse_ident();
|
||||||
|
|
||||||
// TODO: parse data
|
let args = if self.token == token::LPAREN {
|
||||||
|
self.parse_unspanned_seq(token::LPAREN,
|
||||||
|
token::RPAREN,
|
||||||
|
{sep: some(token::COMMA),
|
||||||
|
trailing_sep_allowed: true},
|
||||||
|
|p| p.parse_ty(false))
|
||||||
|
}
|
||||||
|
else { ~[] };
|
||||||
|
|
||||||
self.expect(token::RARROW);
|
self.expect(token::RARROW);
|
||||||
|
|
||||||
let next = self.parse_ident();
|
let next = self.parse_ident();
|
||||||
// TODO: parse next types
|
|
||||||
|
|
||||||
state.add_message(mname, ~[], next, ~[]);
|
let ntys = if self.token == token::LT {
|
||||||
|
self.parse_unspanned_seq(token::LT,
|
||||||
|
token::GT,
|
||||||
|
{sep: some(token::COMMA),
|
||||||
|
trailing_sep_allowed: true},
|
||||||
|
|p| p.parse_ty(false))
|
||||||
|
}
|
||||||
|
else { ~[] };
|
||||||
|
|
||||||
alt copy self.token {
|
state.add_message(mname, args, next, ntys);
|
||||||
token::COMMA { self.bump() }
|
|
||||||
token::RBRACE { }
|
});
|
||||||
_ { fail }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.bump();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// that things will look really good once we get that lock out of the
|
// that things will look really good once we get that lock out of the
|
||||||
// message path.
|
// message path.
|
||||||
|
|
||||||
// This version uses semi-automatically compiled channel contracts.
|
// This version uses automatically compiled channel contracts.
|
||||||
|
|
||||||
// xfail-pretty
|
// xfail-pretty
|
||||||
|
|
||||||
@@ -13,40 +13,15 @@ import future::future;
|
|||||||
use std;
|
use std;
|
||||||
import std::time;
|
import std::time;
|
||||||
|
|
||||||
import ring::server::recv;
|
import pipes::recv;
|
||||||
|
|
||||||
// This module was generated by the pipe compiler.
|
proto! ring {
|
||||||
mod ring {
|
num:send {
|
||||||
fn init() -> (client::num, server::num) { pipes::entangle() }
|
num(uint) -> num
|
||||||
enum num { num(uint, server::num), }
|
|
||||||
mod client {
|
|
||||||
fn num(-pipe: num, x_0: uint) -> num {
|
|
||||||
let (c, s) = pipes::entangle();
|
|
||||||
let message = ring::num(x_0, s);
|
|
||||||
pipes::send(pipe, message);
|
|
||||||
c
|
|
||||||
}
|
|
||||||
type num = pipes::send_packet<ring::num>;
|
|
||||||
}
|
|
||||||
mod server {
|
|
||||||
impl recv for num {
|
|
||||||
fn recv() -> extern fn(-num) -> ring::num {
|
|
||||||
fn recv(-pipe: num) -> ring::num {
|
|
||||||
option::unwrap(pipes::recv(pipe))
|
|
||||||
}
|
|
||||||
recv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type num = pipes::recv_packet<ring::num>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn macros() {
|
fn macros() {
|
||||||
#macro[
|
|
||||||
[#recv[chan],
|
|
||||||
chan.recv()(chan)]
|
|
||||||
];
|
|
||||||
|
|
||||||
#macro[
|
#macro[
|
||||||
[#move[x],
|
[#move[x],
|
||||||
unsafe { let y <- *ptr::addr_of(x); y }]
|
unsafe { let y <- *ptr::addr_of(x); y }]
|
||||||
@@ -68,7 +43,7 @@ fn thread_ring(i: uint,
|
|||||||
num_port2 <-> num_port;
|
num_port2 <-> num_port;
|
||||||
num_chan = some(ring::client::num(option::unwrap(num_chan2), i * j));
|
num_chan = some(ring::client::num(option::unwrap(num_chan2), i * j));
|
||||||
let port = option::unwrap(num_port2);
|
let port = option::unwrap(num_port2);
|
||||||
alt (#recv(port)) {
|
alt (option::unwrap(recv(port))) {
|
||||||
ring::num(_n, p) {
|
ring::num(_n, p) {
|
||||||
//log(error, _n);
|
//log(error, _n);
|
||||||
num_port = some(#move(p));
|
num_port = some(#move(p));
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
The first test case using pipes. The idea is to break this into
|
|
||||||
several stages for prototyping. Here's the plan:
|
|
||||||
|
|
||||||
1. Write an already-compiled protocol using existing ports and chans.
|
|
||||||
|
|
||||||
2. Take the already-compiled version and add the low-level
|
|
||||||
synchronization code instead.
|
|
||||||
|
|
||||||
3. Write a syntax extension to compile the protocols.
|
|
||||||
|
|
||||||
At some point, we'll need to add support for select.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod pingpong {
|
|
||||||
import newcomm::*;
|
|
||||||
|
|
||||||
type pingpong = ~mut option<(chan<()>, port<()>)>;
|
|
||||||
|
|
||||||
fn init() -> (client::ping, server::ping) {
|
|
||||||
let cp = port();
|
|
||||||
let sp = port();
|
|
||||||
let cc = chan(sp);
|
|
||||||
let sc = chan(cp);
|
|
||||||
|
|
||||||
let client = client::ping(~mut some((cc, cp)));
|
|
||||||
let server = server::ping(~mut some((sc, sp)));
|
|
||||||
|
|
||||||
(client, server)
|
|
||||||
}
|
|
||||||
|
|
||||||
mod client {
|
|
||||||
enum ping = pingpong;
|
|
||||||
enum pong = pingpong;
|
|
||||||
|
|
||||||
fn do_ping(-c: ping) -> pong {
|
|
||||||
let mut op = none;
|
|
||||||
op <-> **c;
|
|
||||||
let (c, s) <- option::unwrap(op);
|
|
||||||
c.send(());
|
|
||||||
let p <- (c, s);
|
|
||||||
pong(~mut some(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_pong(-c: pong) -> (ping, ()) {
|
|
||||||
let mut op = none;
|
|
||||||
op <-> **c;
|
|
||||||
let (c, s) <- option::unwrap(op);
|
|
||||||
let d = s.recv();
|
|
||||||
let p <- (c, s);
|
|
||||||
(ping(~mut some(p)), d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod server {
|
|
||||||
enum ping = pingpong;
|
|
||||||
enum pong = pingpong;
|
|
||||||
|
|
||||||
fn do_ping(-c: ping) -> (pong, ()) {
|
|
||||||
let mut op = none;
|
|
||||||
op <-> **c;
|
|
||||||
let (c, s) <- option::unwrap(op);
|
|
||||||
let d = s.recv();
|
|
||||||
let p <- (c, s);
|
|
||||||
(pong(~mut some(p)), d)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_pong(-c: pong) -> ping {
|
|
||||||
let mut op = none;
|
|
||||||
op <-> **c;
|
|
||||||
let (c, s) <- option::unwrap(op);
|
|
||||||
c.send(());
|
|
||||||
let p <- (c, s);
|
|
||||||
ping(~mut some(p))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn client(-chan: pingpong::client::ping) {
|
|
||||||
let chan = pingpong::client::do_ping(chan);
|
|
||||||
log(error, "Sent ping");
|
|
||||||
let (_chan, _data) = pingpong::client::do_pong(chan);
|
|
||||||
log(error, "Received pong");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn server(-chan: pingpong::server::ping) {
|
|
||||||
let (chan, _data) = pingpong::server::do_ping(chan);
|
|
||||||
log(error, "Received ping");
|
|
||||||
let _chan = pingpong::server::do_pong(chan);
|
|
||||||
log(error, "Sent pong");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let (client_, server_) = pingpong::init();
|
|
||||||
let client_ = ~mut some(client_);
|
|
||||||
let server_ = ~mut some(server_);
|
|
||||||
|
|
||||||
do task::spawn |move client_| {
|
|
||||||
let mut client__ = none;
|
|
||||||
*client_ <-> client__;
|
|
||||||
client(option::unwrap(client__));
|
|
||||||
};
|
|
||||||
do task::spawn |move server_| {
|
|
||||||
let mut server_ˊ = none;
|
|
||||||
*server_ <-> server_ˊ;
|
|
||||||
server(option::unwrap(server_ˊ));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
The first test case using pipes. The idea is to break this into
|
|
||||||
several stages for prototyping. Here's the plan:
|
|
||||||
|
|
||||||
1. Write an already-compiled protocol using existing ports and chans.
|
|
||||||
|
|
||||||
2. Take the already-compiled version and add the low-level
|
|
||||||
synchronization code instead. (That's what this file attempts to do)
|
|
||||||
|
|
||||||
3. Write a syntax extension to compile the protocols.
|
|
||||||
|
|
||||||
At some point, we'll need to add support for select.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod pingpong {
|
|
||||||
enum ping = *pipes::packet<pong>;
|
|
||||||
enum pong = *pipes::packet<ping>;
|
|
||||||
|
|
||||||
fn init() -> (client::ping, server::ping) {
|
|
||||||
pipes::entangle()
|
|
||||||
}
|
|
||||||
|
|
||||||
mod client {
|
|
||||||
type ping = pipes::send_packet<pingpong::ping>;
|
|
||||||
type pong = pipes::recv_packet<pingpong::pong>;
|
|
||||||
|
|
||||||
fn do_ping(-c: ping) -> pong {
|
|
||||||
let p = pipes::packet();
|
|
||||||
|
|
||||||
pipes::send(c, pingpong::ping(p));
|
|
||||||
pipes::recv_packet(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_pong(-c: pong) -> (ping, ()) {
|
|
||||||
let packet = pipes::recv(c);
|
|
||||||
if packet == none {
|
|
||||||
fail "sender closed the connection"
|
|
||||||
}
|
|
||||||
(pipes::send_packet(*option::unwrap(packet)), ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod server {
|
|
||||||
type ping = pipes::recv_packet<pingpong::ping>;
|
|
||||||
type pong = pipes::send_packet<pingpong::pong>;
|
|
||||||
|
|
||||||
fn do_ping(-c: ping) -> (pong, ()) {
|
|
||||||
let packet = pipes::recv(c);
|
|
||||||
if packet == none {
|
|
||||||
fail "sender closed the connection"
|
|
||||||
}
|
|
||||||
(pipes::send_packet(*option::unwrap(packet)), ())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_pong(-c: pong) -> ping {
|
|
||||||
let p = pipes::packet();
|
|
||||||
pipes::send(c, pingpong::pong(p));
|
|
||||||
pipes::recv_packet(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn client(-chan: pingpong::client::ping) {
|
|
||||||
let chan = pingpong::client::do_ping(chan);
|
|
||||||
log(error, "Sent ping");
|
|
||||||
let (chan, _data) = pingpong::client::do_pong(chan);
|
|
||||||
log(error, "Received pong");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn server(-chan: pingpong::server::ping) {
|
|
||||||
let (chan, _data) = pingpong::server::do_ping(chan);
|
|
||||||
log(error, "Received ping");
|
|
||||||
let chan = pingpong::server::do_pong(chan);
|
|
||||||
log(error, "Sent pong");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let (client_, server_) = pingpong::init();
|
|
||||||
let client_ = ~mut some(client_);
|
|
||||||
let server_ = ~mut some(server_);
|
|
||||||
|
|
||||||
do task::spawn |move client_| {
|
|
||||||
let mut client__ = none;
|
|
||||||
*client_ <-> client__;
|
|
||||||
client(option::unwrap(client__));
|
|
||||||
};
|
|
||||||
do task::spawn |move server_| {
|
|
||||||
let mut server_ˊ = none;
|
|
||||||
*server_ <-> server_ˊ;
|
|
||||||
server(option::unwrap(server_ˊ));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
The first test case using pipes. The idea is to break this into
|
|
||||||
several stages for prototyping. Here's the plan:
|
|
||||||
|
|
||||||
1. Write an already-compiled protocol using existing ports and chans.
|
|
||||||
|
|
||||||
2. Take the already-compiled version and add the low-level
|
|
||||||
synchronization code instead.
|
|
||||||
|
|
||||||
3. Write a syntax extension to compile the protocols.
|
|
||||||
|
|
||||||
At some point, we'll need to add support for select.
|
|
||||||
|
|
||||||
This file does horrible things to pretend we have self-move.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod pingpong {
|
|
||||||
enum ping { ping, }
|
|
||||||
enum ping_message = *pipes::packet<pong_message>;
|
|
||||||
enum pong { pong, }
|
|
||||||
enum pong_message = *pipes::packet<ping_message>;
|
|
||||||
|
|
||||||
fn init() -> (client::ping, server::ping) {
|
|
||||||
pipes::entangle()
|
|
||||||
}
|
|
||||||
|
|
||||||
mod client {
|
|
||||||
type ping = pipes::send_packet<pingpong::ping_message>;
|
|
||||||
type pong = pipes::recv_packet<pingpong::pong_message>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl abominable for client::ping {
|
|
||||||
fn send() -> fn@(-client::ping, ping) -> client::pong {
|
|
||||||
|pipe, data| {
|
|
||||||
let p = pipes::packet();
|
|
||||||
pipes::send(pipe, pingpong::ping_message(p));
|
|
||||||
pipes::recv_packet(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl abominable for client::pong {
|
|
||||||
fn recv() -> fn@(-client::pong) -> (client::ping, pong) {
|
|
||||||
|pipe| {
|
|
||||||
let packet = pipes::recv(pipe);
|
|
||||||
if packet == none {
|
|
||||||
fail "sender closed the connection"
|
|
||||||
}
|
|
||||||
let p : pong_message = option::unwrap(packet);
|
|
||||||
(pipes::send_packet(*p), pong)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod server {
|
|
||||||
type ping = pipes::recv_packet<pingpong::ping_message>;
|
|
||||||
type pong = pipes::send_packet<pingpong::pong_message>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl abominable for server::ping {
|
|
||||||
fn recv() -> fn@(-server::ping) -> (server::pong, ping) {
|
|
||||||
|pipe| {
|
|
||||||
let packet = pipes::recv(pipe);
|
|
||||||
if packet == none {
|
|
||||||
fail "sender closed the connection"
|
|
||||||
}
|
|
||||||
let p : ping_message = option::unwrap(packet);
|
|
||||||
(pipes::send_packet(*p), ping)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl abominable for server::pong {
|
|
||||||
fn send() -> fn@(-server::pong, pong) -> server::ping {
|
|
||||||
|pipe, data| {
|
|
||||||
let p = pipes::packet();
|
|
||||||
pipes::send(pipe, pingpong::pong_message(p));
|
|
||||||
pipes::recv_packet(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod test {
|
|
||||||
import pingpong::{ping, pong, abominable};
|
|
||||||
|
|
||||||
fn macros() {
|
|
||||||
#macro[
|
|
||||||
[#send[chan, data],
|
|
||||||
chan.send()(chan, data)]
|
|
||||||
];
|
|
||||||
#macro[
|
|
||||||
[#recv[chan],
|
|
||||||
chan.recv()(chan)]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn client(-chan: pingpong::client::ping) {
|
|
||||||
let chan = #send(chan, ping);
|
|
||||||
log(error, "Sent ping");
|
|
||||||
let (chan, _data) = #recv(chan);
|
|
||||||
log(error, "Received pong");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn server(-chan: pingpong::server::ping) {
|
|
||||||
let (chan, _data) = #recv(chan);
|
|
||||||
log(error, "Received ping");
|
|
||||||
let chan = #send(chan, pong);
|
|
||||||
log(error, "Sent pong");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let (client_, server_) = pingpong::init();
|
|
||||||
let client_ = ~mut some(client_);
|
|
||||||
let server_ = ~mut some(server_);
|
|
||||||
|
|
||||||
do task::spawn |move client_| {
|
|
||||||
let mut client__ = none;
|
|
||||||
*client_ <-> client__;
|
|
||||||
test::client(option::unwrap(client__));
|
|
||||||
};
|
|
||||||
do task::spawn |move server_| {
|
|
||||||
let mut server_ˊ = none;
|
|
||||||
*server_ <-> server_ˊ;
|
|
||||||
test::server(option::unwrap(server_ˊ));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,72 +1,22 @@
|
|||||||
|
// xfail-pretty
|
||||||
|
|
||||||
use std;
|
use std;
|
||||||
import std::timer::sleep;
|
import std::timer::sleep;
|
||||||
import std::uv;
|
import std::uv;
|
||||||
|
|
||||||
import pipes::{recv, select};
|
import pipes::{recv, select};
|
||||||
|
|
||||||
// Compiled by pipec
|
proto! oneshot {
|
||||||
mod oneshot {
|
waiting:send {
|
||||||
fn init() -> (client::waiting, server::waiting) { pipes::entangle() }
|
signal -> signaled
|
||||||
enum waiting { signal(server::signaled), }
|
|
||||||
enum signaled { }
|
|
||||||
mod client {
|
|
||||||
fn signal(-pipe: waiting) -> signaled {
|
|
||||||
let (c, s) = pipes::entangle();
|
|
||||||
let message = oneshot::signal(s);
|
|
||||||
pipes::send(pipe, message);
|
|
||||||
c
|
|
||||||
}
|
|
||||||
type waiting = pipes::send_packet<oneshot::waiting>;
|
|
||||||
type signaled = pipes::send_packet<oneshot::signaled>;
|
|
||||||
}
|
|
||||||
mod server {
|
|
||||||
impl recv for waiting {
|
|
||||||
fn recv() -> extern fn(-waiting) -> oneshot::waiting {
|
|
||||||
fn recv(-pipe: waiting) -> oneshot::waiting {
|
|
||||||
option::unwrap(pipes::recv(pipe))
|
|
||||||
}
|
|
||||||
recv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type waiting = pipes::recv_packet<oneshot::waiting>;
|
|
||||||
impl recv for signaled {
|
|
||||||
fn recv() -> extern fn(-signaled) -> oneshot::signaled {
|
|
||||||
fn recv(-pipe: signaled) -> oneshot::signaled {
|
|
||||||
option::unwrap(pipes::recv(pipe))
|
|
||||||
}
|
|
||||||
recv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type signaled = pipes::recv_packet<oneshot::signaled>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod stream {
|
signaled:send { }
|
||||||
fn init<T: send>() -> (client::stream<T>, server::stream<T>) {
|
|
||||||
pipes::entangle()
|
|
||||||
}
|
}
|
||||||
enum stream<T: send> { send(T, server::stream<T>), }
|
|
||||||
mod client {
|
proto! stream {
|
||||||
fn send<T: send>(+pipe: stream<T>, +x_0: T) -> stream<T> {
|
stream:send<T:send> {
|
||||||
{
|
send(T) -> stream<T>
|
||||||
let (c, s) = pipes::entangle();
|
|
||||||
let message = stream::send(x_0, s);
|
|
||||||
pipes::send(pipe, message);
|
|
||||||
c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type stream<T: send> = pipes::send_packet<stream::stream<T>>;
|
|
||||||
}
|
|
||||||
mod server {
|
|
||||||
impl recv<T: send> for stream<T> {
|
|
||||||
fn recv() -> extern fn(+stream<T>) -> stream::stream<T> {
|
|
||||||
fn recv<T: send>(+pipe: stream<T>) -> stream::stream<T> {
|
|
||||||
option::unwrap(pipes::recv(pipe))
|
|
||||||
}
|
|
||||||
recv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type stream<T: send> = pipes::recv_packet<stream::stream<T>>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,54 +1,22 @@
|
|||||||
|
// xfail-pretty
|
||||||
|
|
||||||
use std;
|
use std;
|
||||||
import std::timer::sleep;
|
import std::timer::sleep;
|
||||||
import std::uv;
|
import std::uv;
|
||||||
|
import pipes::recv;
|
||||||
|
|
||||||
// Compiled by pipec
|
proto! oneshot {
|
||||||
mod oneshot {
|
waiting:send {
|
||||||
fn init() -> (client::waiting, server::waiting) { pipes::entangle() }
|
signal -> signaled
|
||||||
enum waiting { signal(server::signaled), }
|
|
||||||
enum signaled { }
|
|
||||||
mod client {
|
|
||||||
fn signal(-pipe: waiting) -> signaled {
|
|
||||||
let (c, s) = pipes::entangle();
|
|
||||||
let message = oneshot::signal(s);
|
|
||||||
pipes::send(pipe, message);
|
|
||||||
c
|
|
||||||
}
|
|
||||||
type waiting = pipes::send_packet<oneshot::waiting>;
|
|
||||||
type signaled = pipes::send_packet<oneshot::signaled>;
|
|
||||||
}
|
|
||||||
mod server {
|
|
||||||
impl recv for waiting {
|
|
||||||
fn recv() -> extern fn(-waiting) -> oneshot::waiting {
|
|
||||||
fn recv(-pipe: waiting) -> oneshot::waiting {
|
|
||||||
option::unwrap(pipes::recv(pipe))
|
|
||||||
}
|
|
||||||
recv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type waiting = pipes::recv_packet<oneshot::waiting>;
|
|
||||||
impl recv for signaled {
|
|
||||||
fn recv() -> extern fn(-signaled) -> oneshot::signaled {
|
|
||||||
fn recv(-pipe: signaled) -> oneshot::signaled {
|
|
||||||
option::unwrap(pipes::recv(pipe))
|
|
||||||
}
|
|
||||||
recv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type signaled = pipes::recv_packet<oneshot::signaled>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signaled:send { }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
import oneshot::client::*;
|
import oneshot::client::*;
|
||||||
import oneshot::server::recv;
|
|
||||||
|
|
||||||
#macro[
|
let c = pipes::spawn_service(oneshot::init, |p| { recv(p); });
|
||||||
[#recv[chan],
|
|
||||||
chan.recv()(chan)]
|
|
||||||
];
|
|
||||||
|
|
||||||
let c = pipes::spawn_service(oneshot::init, |p| { #recv(p); });
|
|
||||||
|
|
||||||
let iotask = uv::global_loop::get();
|
let iotask = uv::global_loop::get();
|
||||||
sleep(iotask, 5000);
|
sleep(iotask, 5000);
|
||||||
|
|||||||
Reference in New Issue
Block a user