Skip to content

Commit 58e9d6d

Browse files
olsonjefferybrson
authored andcommitted
---
yaml --- r: 11519 b: refs/heads/master c: 1d3e08d h: refs/heads/master i: 11517: f24ca2a 11515: 0eb3afb 11511: 3317235 11503: e6cec90 11487: 1d3de74 11455: fae8814 11391: 4d4fbd2 11263: 65833e1 v: v3
1 parent 4e26e59 commit 58e9d6d

File tree

3 files changed

+212
-31
lines changed

3 files changed

+212
-31
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: b68eb507da6a2621a74676fc9a4ca76b37561ec8
2+
refs/heads/master: 1d3e08d8c6248c4e8c668bf53ff0a308873da31d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/libstd/uvtmp.rs

Lines changed: 160 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
// process_operation() crust fn below
77
enum uv_operation {
88
op_async_init([u8]),
9-
op_close(uv_handle, *ctypes::void)
9+
op_close(uv_handle, *ctypes::void),
10+
op_timer_init([u8]),
11+
op_timer_start([u8], *ctypes::void, u32, u32),
12+
op_timer_stop([u8], *ctypes::void, fn~(uv_handle))
1013
}
1114

1215
enum uv_handle {
13-
uv_async([u8], uv_loop)
16+
uv_async([u8], uv_loop),
17+
uv_timer([u8], uv_loop)
1418
}
1519

1620
enum uv_msg {
@@ -20,11 +24,17 @@ enum uv_msg {
2024
msg_async_init(fn~(uv_handle), fn~(uv_handle)),
2125
msg_async_send([u8]),
2226
msg_close(uv_handle, fn~()),
27+
msg_timer_init(fn~(uv_handle)),
28+
msg_timer_start([u8], u32, u32, fn~(uv_handle)),
29+
msg_timer_stop([u8], fn~(uv_handle)),
2330

2431
// dispatches from libuv
2532
uv_async_init([u8], *ctypes::void),
2633
uv_async_send([u8]),
2734
uv_close([u8]),
35+
uv_timer_init([u8], *ctypes::void),
36+
uv_timer_call([u8]),
37+
uv_timer_stop([u8], fn~(uv_handle)),
2838
uv_end()
2939
}
3040

@@ -74,16 +84,26 @@ native mod rustrt {
7484
fn rust_uvtmp_uv_run(loop_handle: *ctypes::void);
7585
fn rust_uvtmp_uv_close(handle: *ctypes::void, cb: *u8);
7686
fn rust_uvtmp_uv_close_async(handle: *ctypes::void);
87+
fn rust_uvtmp_uv_close_timer(handle: *ctypes::void);
7788
fn rust_uvtmp_uv_async_send(handle: *ctypes::void);
7889
fn rust_uvtmp_uv_async_init(
7990
loop_handle: *ctypes::void,
8091
cb: *u8,
8192
id: *u8) -> *ctypes::void;
93+
fn rust_uvtmp_uv_timer_init(
94+
loop_handle: *ctypes::void,
95+
cb: *u8,
96+
id: *u8) -> *ctypes::void;
97+
fn rust_uvtmp_uv_timer_start(
98+
timer_handle: *ctypes::void,
99+
timeout: ctypes::c_uint,
100+
repeat: ctypes::c_uint);
101+
fn rust_uvtmp_uv_timer_stop(handle: *ctypes::void);
82102
}
83103

84104
mod uv {
85105
export loop_new, run, close, run_in_bg, async_init, async_send,
86-
timer_init;
106+
timer_init, timer_start, timer_stop;
87107

88108
// public functions
89109
fn loop_new() -> uv_loop unsafe {
@@ -92,9 +112,7 @@ mod uv {
92112
let ret_recv_chan: comm::chan<uv_loop> =
93113
comm::chan(ret_recv_port);
94114

95-
let num_threads = 4u; // would be cool to tie this to
96-
// the number of logical procs
97-
task::spawn_sched(num_threads) {||
115+
task::spawn_sched(task::manual_threads(4u)) {||
98116
// our beloved uv_loop_t ptr
99117
let loop_handle = rustrt::
100118
rust_uvtmp_uv_loop_new();
@@ -140,13 +158,15 @@ mod uv {
140158
map::new_bytes_hash();
141159
let id_to_handle: map::map<[u8], uv_handle> =
142160
map::new_bytes_hash();
143-
let async_cbs: map::map<[u8], fn~(uv_handle)> =
144-
map::new_bytes_hash();
145-
let async_init_after_cbs: map::map<[u8],
146-
fn~(uv_handle)> =
161+
let after_cbs: map::map<[u8], fn~(uv_handle)> =
147162
map::new_bytes_hash();
148163
let close_callbacks: map::map<[u8], fn~()> =
149164
map::new_bytes_hash();
165+
166+
let async_cbs: map::map<[u8], fn~(uv_handle)> =
167+
map::new_bytes_hash();
168+
let timer_cbs: map::map<[u8], fn~(uv_handle)> =
169+
map::new_bytes_hash();
150170

151171
// the main loop that this task blocks on.
152172
// should have the same lifetime as the C libuv
@@ -160,7 +180,7 @@ mod uv {
160180
// the operation handle to have the
161181
// loop process any pending operations
162182
// once its up and running
163-
task::spawn_sched(1u) {||
183+
task::spawn_sched(task::manual_threads(1u)) {||
164184
// this call blocks
165185
rustrt::rust_uvtmp_uv_run(loop_handle);
166186
// when we're done, msg the
@@ -172,7 +192,7 @@ mod uv {
172192
}
173193

174194
msg_run_in_bg {
175-
task::spawn_sched(1u) {||
195+
task::spawn_sched(task::manual_threads(1u)) {||
176196
// this call blocks
177197
rustrt::rust_uvtmp_uv_run(loop_handle);
178198
};
@@ -194,6 +214,9 @@ mod uv {
194214
uv_async(id, _) {
195215
async_cbs.remove(id);
196216
}
217+
uv_timer(id, _) {
218+
timer_cbs.remove(id);
219+
}
197220
_ {
198221
fail "unknown form of uv_handle encountered "
199222
+ "in uv_close handler";
@@ -213,7 +236,7 @@ mod uv {
213236
// invocation on msg_async_send
214237
let id = gen_handle_id();
215238
async_cbs.insert(id, callback);
216-
async_init_after_cbs.insert(id, after_cb);
239+
after_cbs.insert(id, after_cb);
217240
let op = op_async_init(id);
218241
pass_to_libuv(op_handle, operation_chan, op);
219242
}
@@ -223,8 +246,8 @@ mod uv {
223246
// then invoke the supplied callback
224247
// for after completion
225248
handles.insert(id, async_handle);
226-
let after_cb = async_init_after_cbs.get(id);
227-
async_init_after_cbs.remove(id);
249+
let after_cb = after_cbs.get(id);
250+
after_cbs.remove(id);
228251
let async = uv_async(id, rust_loop_chan);
229252
id_to_handle.insert(id, copy(async));
230253
task::spawn {||
@@ -242,6 +265,50 @@ mod uv {
242265
async_cb(uv_async(id, rust_loop_chan));
243266
};
244267
}
268+
269+
msg_timer_init(after_cb) {
270+
let id = gen_handle_id();
271+
after_cbs.insert(id, after_cb);
272+
let op = op_timer_init(id);
273+
pass_to_libuv(op_handle, operation_chan, op);
274+
}
275+
uv_timer_init(id, handle) {
276+
handles.insert(id, handle);
277+
let after_cb = after_cbs.get(id);
278+
after_cbs.remove(id);
279+
let new_timer = uv_timer(id, rust_loop_chan);
280+
id_to_handle.insert(id, copy(new_timer));
281+
task::spawn {||
282+
after_cb(new_timer);
283+
};
284+
}
285+
286+
uv_timer_call(id) {
287+
let cb = timer_cbs.get(id);
288+
let the_timer = id_to_handle.get(id);
289+
task::spawn {||
290+
cb(the_timer);
291+
};
292+
}
293+
294+
msg_timer_start(id, timeout, repeat, timer_call_cb) {
295+
timer_cbs.insert(id, timer_call_cb);
296+
let handle = handles.get(id);
297+
let op = op_timer_start(id, handle, timeout,
298+
repeat);
299+
pass_to_libuv(op_handle, operation_chan, op);
300+
}
301+
302+
msg_timer_stop(id, after_cb) {
303+
let handle = handles.get(id);
304+
let op = op_timer_stop(id, handle, after_cb);
305+
pass_to_libuv(op_handle, operation_chan, op);
306+
}
307+
uv_timer_stop(id, after_cb) {
308+
let the_timer = id_to_handle.get(id);
309+
after_cb(the_timer);
310+
}
311+
245312
uv_end() {
246313
keep_going = false;
247314
}
@@ -294,6 +361,33 @@ mod uv {
294361
comm::send(loop, msg);
295362
}
296363

364+
fn timer_start(the_timer: uv_handle, timeout: u32, repeat:u32,
365+
timer_cb: fn~(uv_handle)) {
366+
alt the_timer {
367+
uv_timer(id, loop_chan) {
368+
let msg = msg_timer_start(id, timeout, repeat, timer_cb);
369+
comm::send(loop_chan, msg);
370+
}
371+
_ {
372+
fail "can only pass a uv_timer form of uv_handle to "+
373+
" uv::timer_start()";
374+
}
375+
}
376+
}
377+
378+
fn timer_stop(the_timer: uv_handle, after_cb: fn~(uv_handle)) {
379+
alt the_timer {
380+
uv_timer(id, loop_chan) {
381+
let msg = msg_timer_stop(id, after_cb);
382+
comm::send(loop_chan, msg);
383+
}
384+
_ {
385+
fail "only uv_timer form is allowed in calls to "+
386+
" uv::timer_stop()";
387+
}
388+
}
389+
}
390+
297391
// internal functions
298392
fn pass_to_libuv(
299393
op_handle: *ctypes::void,
@@ -320,7 +414,7 @@ mod uv {
320414
fn get_loop_chan_from_handle(handle: uv_handle)
321415
-> uv_loop {
322416
alt handle {
323-
uv_async(id,loop) {
417+
uv_async(id,loop) | uv_timer(id,loop) {
324418
ret loop;
325419
}
326420
_ {
@@ -332,7 +426,7 @@ mod uv {
332426

333427
fn get_id_from_handle(handle: uv_handle) -> [u8] {
334428
alt handle {
335-
uv_async(id,loop) {
429+
uv_async(id,loop) | uv_timer(id,loop) {
336430
ret id;
337431
}
338432
_ {
@@ -363,6 +457,24 @@ mod uv {
363457
op_close(handle, handle_ptr) {
364458
handle_op_close(handle, handle_ptr);
365459
}
460+
op_timer_init(id) {
461+
let id_ptr = vec::unsafe::to_ptr(id);
462+
let timer_handle = rustrt::rust_uvtmp_uv_timer_init(
463+
loop,
464+
process_timer_call,
465+
id_ptr);
466+
comm::send(loop_chan, uv_timer_init(
467+
id,
468+
timer_handle));
469+
}
470+
op_timer_start(id, handle, timeout, repeat) {
471+
rustrt::rust_uvtmp_uv_timer_start(handle, timeout,
472+
repeat);
473+
}
474+
op_timer_stop(id, handle, after_cb) {
475+
rustrt::rust_uvtmp_uv_timer_stop(handle);
476+
comm::send(loop_chan, uv_timer_stop(id, after_cb));
477+
}
366478

367479
_ { fail "unknown form of uv_operation received"; }
368480
}
@@ -378,6 +490,11 @@ mod uv {
378490
rustrt::rust_uvtmp_uv_close(
379491
handle_ptr, cb);
380492
}
493+
uv_timer(id, loop) {
494+
let cb = process_close_timer;
495+
rustrt::rust_uvtmp_uv_close(
496+
handle_ptr, cb);
497+
}
381498
_ {
382499
fail "unknown form of uv_handle encountered " +
383500
"in process_operation/op_close";
@@ -386,12 +503,19 @@ mod uv {
386503
}
387504

388505
crust fn process_async_send(id_buf: *u8, data: *uv_loop_data)
389-
unsafe {
506+
unsafe {
390507
let handle_id = get_handle_id_from(id_buf);
391508
let loop_chan = get_loop_chan_from_data(data);
392509
comm::send(loop_chan, uv_async_send(handle_id));
393510
}
394511

512+
crust fn process_timer_call(id_buf: *u8, data: *uv_loop_data)
513+
unsafe {
514+
let handle_id = get_handle_id_from(id_buf);
515+
let loop_chan = get_loop_chan_from_data(data);
516+
comm::send(loop_chan, uv_timer_call(handle_id));
517+
}
518+
395519
fn process_close_common(id: [u8], data: *uv_loop_data)
396520
unsafe {
397521
// notify the rust loop that their handle is closed, then
@@ -414,6 +538,16 @@ mod uv {
414538
// close cb
415539
process_close_common(id, data);
416540
}
541+
542+
crust fn process_close_timer(
543+
id_buf: *u8,
544+
handle_ptr: *ctypes::void,
545+
data: *uv_loop_data)
546+
unsafe {
547+
let id = get_handle_id_from(id_buf);
548+
rustrt::rust_uvtmp_uv_close_timer(handle_ptr);
549+
process_close_common(id, data);
550+
}
417551

418552

419553
}
@@ -446,11 +580,15 @@ fn test_uvtmp_uv_timer() {
446580
let test_loop = uv::loop_new();
447581
let exit_port = comm::port::<bool>();
448582
let exit_chan = comm::chan::<bool>(exit_port);
449-
uv::timer(test_loop, {|new_timer|
450-
uv::timer_start(new_async) {||
451-
comm::send(exit_chan, true);
583+
uv::timer_init(test_loop) {|new_timer|
584+
uv::timer_start(new_timer, 1u32, 0u32) {|started_timer|
585+
uv::timer_stop(started_timer) {|stopped_timer|
586+
uv::close(stopped_timer) {||
587+
comm::send(exit_chan, true);
588+
};
589+
};
452590
};
453-
});
591+
};
454592
uv::run(test_loop);
455593
assert comm::recv(exit_port);
456594
}

0 commit comments

Comments
 (0)