rt: Simplify the recv interface
This commit is contained in:
@@ -46,8 +46,7 @@ native mod rustrt {
|
||||
fn get_port_id(po: *rust_port) -> port_id;
|
||||
fn rust_port_size(po: *rust_port) -> ctypes::size_t;
|
||||
fn port_recv(dptr: *uint, po: *rust_port,
|
||||
yield: *ctypes::uintptr_t,
|
||||
killed: *ctypes::uintptr_t);
|
||||
yield: *ctypes::uintptr_t);
|
||||
fn rust_port_select(dptr: **rust_port, ports: **rust_port,
|
||||
n_ports: ctypes::size_t,
|
||||
yield: *ctypes::uintptr_t);
|
||||
@@ -142,21 +141,19 @@ fn recv_<T: send>(p: *rust_port) -> T {
|
||||
// that will grab the value of the return pointer, then call this
|
||||
// function, which we will then use to call the runtime.
|
||||
fn recv(dptr: *uint, port: *rust_port,
|
||||
yield: *ctypes::uintptr_t,
|
||||
killed: *ctypes::uintptr_t) unsafe {
|
||||
rustrt::port_recv(dptr, port, yield, killed);
|
||||
yield: *ctypes::uintptr_t) unsafe {
|
||||
rustrt::port_recv(dptr, port, yield);
|
||||
}
|
||||
let yield = 0u;
|
||||
let yieldp = ptr::addr_of(yield);
|
||||
let killed = 0u;
|
||||
let killedp = ptr::addr_of(killed);
|
||||
let res = rusti::call_with_retptr(bind recv(_, p, yieldp, killedp));
|
||||
if killed != 0u {
|
||||
fail "killed";
|
||||
}
|
||||
let res = rusti::call_with_retptr(bind recv(_, 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;
|
||||
}
|
||||
@@ -186,6 +183,10 @@ fn select2<A: send, B: send>(
|
||||
if yield != 0u {
|
||||
// Wait for data
|
||||
task::yield();
|
||||
} else {
|
||||
// As in recv, this is a good place to yield anyway until
|
||||
// the compiler generates yield calls
|
||||
task::yield();
|
||||
}
|
||||
|
||||
// Now we know the port we're supposed to receive from
|
||||
|
||||
@@ -543,10 +543,8 @@ rust_task_yield(rust_task *task, bool *killed) {
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
port_recv(uintptr_t *dptr, rust_port *port,
|
||||
uintptr_t *yield, uintptr_t *killed) {
|
||||
port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) {
|
||||
*yield = false;
|
||||
*killed = false;
|
||||
rust_task *task = rust_task_thread::get_task();
|
||||
{
|
||||
scoped_lock with(port->lock);
|
||||
@@ -559,13 +557,6 @@ port_recv(uintptr_t *dptr, rust_port *port,
|
||||
return;
|
||||
}
|
||||
|
||||
// If this task has been killed then we're not going to bother
|
||||
// blocking, we have to unwind.
|
||||
if (task->must_fail_from_being_killed()) {
|
||||
*killed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// No data was buffered on any incoming channel, so block this task on
|
||||
// the port. Remember the rendezvous location so that any sender task
|
||||
// can write to it before waking up this task.
|
||||
|
||||
Reference in New Issue
Block a user