Skip to content

Commit 61841e4

Browse files
olsonjefferybrson
authored andcommitted
---
yaml --- r: 15587 b: refs/heads/try c: 7ac8c30 h: refs/heads/master i: 15585: 6693ec8 15583: 62455ac v: v3
1 parent 84ce1cb commit 61841e4

File tree

3 files changed

+116
-2
lines changed

3 files changed

+116
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: a1c43cc7c92f98acd9b45e36b7dfc3407ca5f3fe
5+
refs/heads/try: 7ac8c3081c5d4d7b1c79942e426770c1c3e1c0b3
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/libstd/std.rc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use core(vers = "0.2");
1414
import core::*;
1515

1616
export net, uv;
17-
export c_vec, util;
17+
export c_vec, util, timer;
1818
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
1919
export rope, arena;
2020
export ebml, dbg, getopts, json, rand, sha1, term, time, prettyprint;
@@ -35,6 +35,7 @@ mod uv_global_loop;
3535

3636
mod c_vec;
3737
mod util;
38+
mod timer;
3839

3940

4041
// Collections

branches/try/src/libstd/timer.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#[doc ="
2+
Utilities that leverage libuv's `uv_timer_*` API
3+
"];
4+
5+
import uv = uv;
6+
export delayed_send, sleep;
7+
8+
#[doc = "
9+
Wait for timeout period then send provided value over a channel
10+
11+
This call returns immediately. Useful as the building block for a number
12+
of higher-level timer functions.
13+
14+
Is not guaranteed to wait for exactly the specified time, but will wait
15+
for *at least* that period of time.
16+
17+
# Arguments
18+
19+
msecs - a timeout period, in milliseconds, to wait
20+
ch - a channel of type T to send a `val` on
21+
val - a value of type T to send over the provided `ch`
22+
"]
23+
fn delayed_send<T: send>(msecs: uint, ch: comm::chan<T>, val: T) {
24+
task::spawn() {||
25+
unsafe {
26+
let timer_done_po = comm::port::<()>();
27+
let timer_done_ch = comm::chan(timer_done_po);
28+
let timer_done_ch_ptr = ptr::addr_of(timer_done_ch);
29+
let timer = uv::ll::timer_t();
30+
let timer_ptr = ptr::addr_of(timer);
31+
let hl_loop = uv::global_loop::get();
32+
uv::hl::interact(hl_loop) {|loop_ptr|
33+
uv::hl::ref(hl_loop, timer_ptr);
34+
let init_result = uv::ll::timer_init(loop_ptr, timer_ptr);
35+
if (init_result == 0i32) {
36+
let start_result = uv::ll::timer_start(
37+
timer_ptr, delayed_send_cb, msecs, 0u);
38+
if (start_result == 0i32) {
39+
uv::ll::set_data_for_uv_handle(
40+
timer_ptr,
41+
timer_done_ch_ptr as *libc::c_void);
42+
}
43+
else {
44+
let error_msg = uv::ll::get_last_err_info(loop_ptr);
45+
fail "timer::delayed_send() start failed: "+error_msg;
46+
}
47+
}
48+
else {
49+
let error_msg = uv::ll::get_last_err_info(loop_ptr);
50+
fail "timer::delayed_send() init failed: "+error_msg;
51+
}
52+
};
53+
// delayed_send_cb has been processed by libuv
54+
comm::recv(timer_done_po);
55+
// notify the caller immediately
56+
comm::send(ch, copy(val));
57+
// then clean up our handle
58+
uv::hl::unref_and_close(hl_loop, timer_ptr,
59+
delayed_send_close_cb);
60+
// uv_close for this timer has been processed
61+
comm::recv(timer_done_po);
62+
}
63+
};
64+
}
65+
66+
#[doc = "
67+
Blocks the current task for (at least) the specified time period.
68+
69+
Is not guaranteed to sleep for exactly the specified time, but will sleep
70+
for *at least* that period of time.
71+
72+
# Arguments
73+
74+
* msecs - an amount of time, in milliseconds, for the current task to block
75+
"]
76+
fn sleep(msecs: uint) {
77+
let exit_po = comm::port::<()>();
78+
let exit_ch = comm::chan(exit_po);
79+
delayed_send(msecs, exit_ch, ());
80+
comm::recv(exit_po);
81+
}
82+
83+
// INTERNAL API
84+
crust fn delayed_send_cb(handle: *uv::ll::uv_timer_t,
85+
status: libc::c_int) unsafe {
86+
log(debug, #fmt("delayed_send_cb handle %? status %?", handle, status));
87+
let timer_done_ch =
88+
*(uv::ll::get_data_for_uv_handle(handle) as *comm::chan<()>);
89+
let stop_result = uv::ll::timer_stop(handle);
90+
if (stop_result == 0i32) {
91+
comm::send(timer_done_ch, ());
92+
}
93+
else {
94+
let loop_ptr = uv::ll::get_loop_for_uv_handle(handle);
95+
let error_msg = uv::ll::get_last_err_info(loop_ptr);
96+
fail "timer::sleep() init failed: "+error_msg;
97+
}
98+
}
99+
100+
crust fn delayed_send_close_cb(handle: *uv::ll::uv_timer_t) unsafe {
101+
log(debug, #fmt("delayed_send_close_cb handle %?", handle));
102+
let timer_done_ch =
103+
*(uv::ll::get_data_for_uv_handle(handle) as *comm::chan<()>);
104+
comm::send(timer_done_ch, ());
105+
}
106+
107+
#[cfg(test)]
108+
mod test {
109+
#[test]
110+
fn test_timer_simple_sleep_test() {
111+
sleep(2000u);
112+
}
113+
}

0 commit comments

Comments
 (0)