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 get_port_id(po: *rust_port) -> port_id;
|
||||||
fn rust_port_size(po: *rust_port) -> ctypes::size_t;
|
fn rust_port_size(po: *rust_port) -> ctypes::size_t;
|
||||||
fn port_recv(dptr: *uint, po: *rust_port,
|
fn port_recv(dptr: *uint, po: *rust_port,
|
||||||
yield: *ctypes::uintptr_t,
|
yield: *ctypes::uintptr_t);
|
||||||
killed: *ctypes::uintptr_t);
|
|
||||||
fn rust_port_select(dptr: **rust_port, ports: **rust_port,
|
fn rust_port_select(dptr: **rust_port, ports: **rust_port,
|
||||||
n_ports: ctypes::size_t,
|
n_ports: ctypes::size_t,
|
||||||
yield: *ctypes::uintptr_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
|
// that will grab the value of the return pointer, then call this
|
||||||
// function, which we will then use to call the runtime.
|
// function, which we will then use to call the runtime.
|
||||||
fn recv(dptr: *uint, port: *rust_port,
|
fn recv(dptr: *uint, port: *rust_port,
|
||||||
yield: *ctypes::uintptr_t,
|
yield: *ctypes::uintptr_t) unsafe {
|
||||||
killed: *ctypes::uintptr_t) unsafe {
|
rustrt::port_recv(dptr, port, yield);
|
||||||
rustrt::port_recv(dptr, port, yield, killed);
|
|
||||||
}
|
}
|
||||||
let yield = 0u;
|
let yield = 0u;
|
||||||
let yieldp = ptr::addr_of(yield);
|
let yieldp = ptr::addr_of(yield);
|
||||||
let killed = 0u;
|
let res = rusti::call_with_retptr(bind recv(_, p, yieldp));
|
||||||
let killedp = ptr::addr_of(killed);
|
|
||||||
let res = rusti::call_with_retptr(bind recv(_, p, yieldp, killedp));
|
|
||||||
if killed != 0u {
|
|
||||||
fail "killed";
|
|
||||||
}
|
|
||||||
if yield != 0u {
|
if yield != 0u {
|
||||||
// Data isn't available yet, so res has not been initialized.
|
// Data isn't available yet, so res has not been initialized.
|
||||||
task::yield();
|
task::yield();
|
||||||
|
} else {
|
||||||
|
// In the absense of compiler-generated preemption points
|
||||||
|
// this is a good place to yield
|
||||||
|
task::yield();
|
||||||
}
|
}
|
||||||
ret res;
|
ret res;
|
||||||
}
|
}
|
||||||
@@ -186,6 +183,10 @@ fn select2<A: send, B: send>(
|
|||||||
if yield != 0u {
|
if yield != 0u {
|
||||||
// Wait for data
|
// Wait for data
|
||||||
task::yield();
|
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
|
// 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
|
extern "C" CDECL void
|
||||||
port_recv(uintptr_t *dptr, rust_port *port,
|
port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) {
|
||||||
uintptr_t *yield, uintptr_t *killed) {
|
|
||||||
*yield = false;
|
*yield = false;
|
||||||
*killed = false;
|
|
||||||
rust_task *task = rust_task_thread::get_task();
|
rust_task *task = rust_task_thread::get_task();
|
||||||
{
|
{
|
||||||
scoped_lock with(port->lock);
|
scoped_lock with(port->lock);
|
||||||
@@ -559,13 +557,6 @@ port_recv(uintptr_t *dptr, rust_port *port,
|
|||||||
return;
|
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
|
// No data was buffered on any incoming channel, so block this task on
|
||||||
// the port. Remember the rendezvous location so that any sender task
|
// the port. Remember the rendezvous location so that any sender task
|
||||||
// can write to it before waking up this task.
|
// can write to it before waking up this task.
|
||||||
|
|||||||
Reference in New Issue
Block a user