Test case for previous commit

(basically a stripped-down version of comm, and a "driver" that
constructs a new port)
This commit is contained in:
Tim Chevalier 2012-06-12 16:41:11 -07:00
parent aa9d2d88d3
commit eadd74b5b6
2 changed files with 126 additions and 0 deletions

View File

@ -0,0 +1,108 @@
/*
Minimized version of core::comm (with still-local modifications
to turn a resource into a class) for testing.
Could probably be more minimal.
*/
import libc::size_t;
export port::{};
export port;
export recv;
#[doc = "
A communication endpoint that can receive messages
Each port has a unique per-task identity and may not be replicated or
transmitted. If a port value is copied, both copies refer to the same
port. Ports may be associated with multiple `chan`s.
"]
enum port<T: send> {
port_t(@port_ptr<T>)
}
#[doc = "Constructs a port"]
fn port<T: send>() -> port<T> {
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
}
class port_ptr<T:send> {
let po: *rust_port;
new(po: *rust_port) {
#debug("in the port_ptr constructor");
self.po = po; }
drop unsafe {
#debug("in the port_ptr destructor");
task::unkillable {||
let yield = 0u;
let yieldp = ptr::addr_of(yield);
rustrt::rust_port_begin_detach(self.po, yieldp);
if yield != 0u {
task::yield();
}
rustrt::rust_port_end_detach(self.po);
while rustrt::rust_port_size(self.po) > 0u as size_t {
recv_::<T>(self.po);
}
rustrt::del_port(self.po);
}
}
}
#[doc = "
Receive from a port. If no data is available on the port then the
task will block until data becomes available.
"]
fn recv<T: send>(p: port<T>) -> T { recv_((**p).po) }
#[doc = "Receive on a raw port pointer"]
fn recv_<T: send>(p: *rust_port) -> T {
let yield = 0u;
let yieldp = ptr::addr_of(yield);
let mut res;
res = rusti::init::<T>();
rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);
if yield != 0u {
// Data isn't available yet, so res has not been initialized.
task::yield();
} else {
// In the absense of compiler-generated preemption points
// this is a good place to yield
task::yield();
}
ret res;
}
/* Implementation details */
enum rust_port {}
type port_id = int;
#[abi = "cdecl"]
native mod rustrt {
fn new_port(unit_sz: libc::size_t) -> *rust_port;
fn del_port(po: *rust_port);
fn rust_port_begin_detach(po: *rust_port,
yield: *libc::uintptr_t);
fn rust_port_end_detach(po: *rust_port);
fn rust_port_size(po: *rust_port) -> libc::size_t;
fn port_recv(dptr: *uint, po: *rust_port,
yield: *libc::uintptr_t);
}
#[abi = "rust-intrinsic"]
native mod rusti {
fn init<T>() -> T;
}

View File

@ -0,0 +1,18 @@
// aux-build:test_comm.rs
use test_comm;
fn main() {
let p = test_comm::port();
alt none::<int> {
none {}
some(_) {
if test_comm::recv(p) == 0 {
#error("floop");
}
else {
#error("bloop");
}
}}
}