std: add timer::recv_timeout() and whitespace cleanup

This commit is contained in:
Jeff Olson 2012-04-20 09:08:02 -07:00 committed by Brian Anderson
parent 7ac8c3081c
commit 707391edbc
2 changed files with 76 additions and 6 deletions

View file

@ -3,7 +3,7 @@ Utilities that leverage libuv's `uv_timer_*` API
"]; "];
import uv = uv; import uv = uv;
export delayed_send, sleep; export delayed_send, sleep, recv_timeout;
#[doc = " #[doc = "
Wait for timeout period then send provided value over a channel Wait for timeout period then send provided value over a channel
@ -16,9 +16,9 @@ for *at least* that period of time.
# Arguments # Arguments
msecs - a timeout period, in milliseconds, to wait * msecs - a timeout period, in milliseconds, to wait
ch - a channel of type T to send a `val` on * ch - a channel of type T to send a `val` on
val - a value of type T to send over the provided `ch` * val - a value of type T to send over the provided `ch`
"] "]
fn delayed_send<T: send>(msecs: uint, ch: comm::chan<T>, val: T) { fn delayed_send<T: send>(msecs: uint, ch: comm::chan<T>, val: T) {
task::spawn() {|| task::spawn() {||
@ -80,6 +80,39 @@ fn sleep(msecs: uint) {
comm::recv(exit_po); comm::recv(exit_po);
} }
#[doc = "
Receive on a port for (up to) a specified time, then return an `option<T>`
This call will block to receive on the provided port for up to the specified
timeout. Depending on whether the provided port receives in that time period,
`recv_timeout` will return an `option<T>` representing the result.
# Arguments
* msecs - an mount of time, in milliseconds, to wait to receive
* wait_port - a `comm::port<T>` to receive on
# Returns
An `option<T>` representing the outcome of the call. If the call `recv`'d on
the provided port in the allotted timeout period, then the result will be a
`some(T)`. If not, then `none` will be returned.
"]
fn recv_timeout<T: send>(msecs: uint, wait_po: comm::port<T>) -> option<T> {
let timeout_po = comm::port::<()>();
let timeout_ch = comm::chan(timeout_po);
delayed_send(msecs, timeout_ch, ());
either::either(
{|left_val|
log(debug, #fmt("recv_time .. left_val %?",
left_val));
none
}, {|right_val|
some(right_val)
}, comm::select2(timeout_po, wait_po)
)
}
// INTERNAL API // INTERNAL API
crust fn delayed_send_cb(handle: *uv::ll::uv_timer_t, crust fn delayed_send_cb(handle: *uv::ll::uv_timer_t,
status: libc::c_int) unsafe { status: libc::c_int) unsafe {
@ -108,6 +141,43 @@ crust fn delayed_send_close_cb(handle: *uv::ll::uv_timer_t) unsafe {
mod test { mod test {
#[test] #[test]
fn test_timer_simple_sleep_test() { fn test_timer_simple_sleep_test() {
sleep(2000u); sleep(1u);
}
#[test]
fn test_timer_recv_timeout_before_time_passes() {
let expected = rand::rng().gen_str(16u);
let test_po = comm::port::<str>();
let test_ch = comm::chan(test_po);
task::spawn() {||
delayed_send(1u, test_ch, expected);
};
let actual = alt recv_timeout(1000u, test_po) {
some(val) { val }
_ { fail "test_timer_recv_timeout_before_time_passes:"+
" didn't receive result before timeout"; }
};
assert actual == expected;
}
#[test]
fn test_timer_recv_timeout_after_time_passes() {
let expected = rand::rng().gen_str(16u);
let fail_msg = rand::rng().gen_str(16u);
let test_po = comm::port::<str>();
let test_ch = comm::chan(test_po);
task::spawn() {||
delayed_send(1000u, test_ch, expected);
};
let actual = alt recv_timeout(1u, test_po) {
none { fail_msg }
_ { fail "test_timer_recv_timeout_before_time_passes:"+
" didn't receive result before timeout"; }
};
assert actual == fail_msg;
} }
} }

View file

@ -841,7 +841,7 @@ mod test {
// we have data // we have data
log(debug, #fmt("CLIENT read: data! nread: %d", nread)); log(debug, #fmt("CLIENT read: data! nread: %d", nread));
read_stop(stream); read_stop(stream);
let client_data = let client_data =
get_data_for_uv_handle(stream as *libc::c_void) get_data_for_uv_handle(stream as *libc::c_void)
as *request_wrapper; as *request_wrapper;
let buf_base = get_base_from_buf(buf); let buf_base = get_base_from_buf(buf);