diff options
| author | Jeff Olson <olson.jeffery@gmail.com> | 2012-02-21 11:29:36 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-02-28 17:56:15 -0800 |
| commit | 1d3e08d8c6248c4e8c668bf53ff0a308873da31d (patch) | |
| tree | c3089b452dfd2f5127d6e81dfd0c8e3848dbdca2 /src/libstd | |
| parent | b68eb507da6a2621a74676fc9a4ca76b37561ec8 (diff) | |
| download | rust-1d3e08d8c6248c4e8c668bf53ff0a308873da31d.tar.gz rust-1d3e08d8c6248c4e8c668bf53ff0a308873da31d.zip | |
finishing up simple uv_timer impl
as it stands, basic async nad timer support is added
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/uvtmp.rs | 182 |
1 files changed, 160 insertions, 22 deletions
diff --git a/src/libstd/uvtmp.rs b/src/libstd/uvtmp.rs index 75e962bd331..123cd8ac2a8 100644 --- a/src/libstd/uvtmp.rs +++ b/src/libstd/uvtmp.rs @@ -6,11 +6,15 @@ // process_operation() crust fn below enum uv_operation { op_async_init([u8]), - op_close(uv_handle, *ctypes::void) + op_close(uv_handle, *ctypes::void), + op_timer_init([u8]), + op_timer_start([u8], *ctypes::void, u32, u32), + op_timer_stop([u8], *ctypes::void, fn~(uv_handle)) } enum uv_handle { - uv_async([u8], uv_loop) + uv_async([u8], uv_loop), + uv_timer([u8], uv_loop) } enum uv_msg { @@ -20,11 +24,17 @@ enum uv_msg { msg_async_init(fn~(uv_handle), fn~(uv_handle)), msg_async_send([u8]), msg_close(uv_handle, fn~()), + msg_timer_init(fn~(uv_handle)), + msg_timer_start([u8], u32, u32, fn~(uv_handle)), + msg_timer_stop([u8], fn~(uv_handle)), // dispatches from libuv uv_async_init([u8], *ctypes::void), uv_async_send([u8]), uv_close([u8]), + uv_timer_init([u8], *ctypes::void), + uv_timer_call([u8]), + uv_timer_stop([u8], fn~(uv_handle)), uv_end() } @@ -74,16 +84,26 @@ native mod rustrt { fn rust_uvtmp_uv_run(loop_handle: *ctypes::void); fn rust_uvtmp_uv_close(handle: *ctypes::void, cb: *u8); fn rust_uvtmp_uv_close_async(handle: *ctypes::void); + fn rust_uvtmp_uv_close_timer(handle: *ctypes::void); fn rust_uvtmp_uv_async_send(handle: *ctypes::void); fn rust_uvtmp_uv_async_init( loop_handle: *ctypes::void, cb: *u8, id: *u8) -> *ctypes::void; + fn rust_uvtmp_uv_timer_init( + loop_handle: *ctypes::void, + cb: *u8, + id: *u8) -> *ctypes::void; + fn rust_uvtmp_uv_timer_start( + timer_handle: *ctypes::void, + timeout: ctypes::c_uint, + repeat: ctypes::c_uint); + fn rust_uvtmp_uv_timer_stop(handle: *ctypes::void); } mod uv { export loop_new, run, close, run_in_bg, async_init, async_send, - timer_init; + timer_init, timer_start, timer_stop; // public functions fn loop_new() -> uv_loop unsafe { @@ -92,9 +112,7 @@ mod uv { let ret_recv_chan: comm::chan<uv_loop> = comm::chan(ret_recv_port); - let num_threads = 4u; // would be cool to tie this to - // the number of logical procs - task::spawn_sched(num_threads) {|| + task::spawn_sched(task::manual_threads(4u)) {|| // our beloved uv_loop_t ptr let loop_handle = rustrt:: rust_uvtmp_uv_loop_new(); @@ -140,13 +158,15 @@ mod uv { map::new_bytes_hash(); let id_to_handle: map::map<[u8], uv_handle> = map::new_bytes_hash(); - let async_cbs: map::map<[u8], fn~(uv_handle)> = - map::new_bytes_hash(); - let async_init_after_cbs: map::map<[u8], - fn~(uv_handle)> = + let after_cbs: map::map<[u8], fn~(uv_handle)> = map::new_bytes_hash(); let close_callbacks: map::map<[u8], fn~()> = map::new_bytes_hash(); + + let async_cbs: map::map<[u8], fn~(uv_handle)> = + map::new_bytes_hash(); + let timer_cbs: map::map<[u8], fn~(uv_handle)> = + map::new_bytes_hash(); // the main loop that this task blocks on. // should have the same lifetime as the C libuv @@ -160,7 +180,7 @@ mod uv { // the operation handle to have the // loop process any pending operations // once its up and running - task::spawn_sched(1u) {|| + task::spawn_sched(task::manual_threads(1u)) {|| // this call blocks rustrt::rust_uvtmp_uv_run(loop_handle); // when we're done, msg the @@ -172,7 +192,7 @@ mod uv { } msg_run_in_bg { - task::spawn_sched(1u) {|| + task::spawn_sched(task::manual_threads(1u)) {|| // this call blocks rustrt::rust_uvtmp_uv_run(loop_handle); }; @@ -194,6 +214,9 @@ mod uv { uv_async(id, _) { async_cbs.remove(id); } + uv_timer(id, _) { + timer_cbs.remove(id); + } _ { fail "unknown form of uv_handle encountered " + "in uv_close handler"; @@ -213,7 +236,7 @@ mod uv { // invocation on msg_async_send let id = gen_handle_id(); async_cbs.insert(id, callback); - async_init_after_cbs.insert(id, after_cb); + after_cbs.insert(id, after_cb); let op = op_async_init(id); pass_to_libuv(op_handle, operation_chan, op); } @@ -223,8 +246,8 @@ mod uv { // then invoke the supplied callback // for after completion handles.insert(id, async_handle); - let after_cb = async_init_after_cbs.get(id); - async_init_after_cbs.remove(id); + let after_cb = after_cbs.get(id); + after_cbs.remove(id); let async = uv_async(id, rust_loop_chan); id_to_handle.insert(id, copy(async)); task::spawn {|| @@ -242,6 +265,50 @@ mod uv { async_cb(uv_async(id, rust_loop_chan)); }; } + + msg_timer_init(after_cb) { + let id = gen_handle_id(); + after_cbs.insert(id, after_cb); + let op = op_timer_init(id); + pass_to_libuv(op_handle, operation_chan, op); + } + uv_timer_init(id, handle) { + handles.insert(id, handle); + let after_cb = after_cbs.get(id); + after_cbs.remove(id); + let new_timer = uv_timer(id, rust_loop_chan); + id_to_handle.insert(id, copy(new_timer)); + task::spawn {|| + after_cb(new_timer); + }; + } + + uv_timer_call(id) { + let cb = timer_cbs.get(id); + let the_timer = id_to_handle.get(id); + task::spawn {|| + cb(the_timer); + }; + } + + msg_timer_start(id, timeout, repeat, timer_call_cb) { + timer_cbs.insert(id, timer_call_cb); + let handle = handles.get(id); + let op = op_timer_start(id, handle, timeout, + repeat); + pass_to_libuv(op_handle, operation_chan, op); + } + + msg_timer_stop(id, after_cb) { + let handle = handles.get(id); + let op = op_timer_stop(id, handle, after_cb); + pass_to_libuv(op_handle, operation_chan, op); + } + uv_timer_stop(id, after_cb) { + let the_timer = id_to_handle.get(id); + after_cb(the_timer); + } + uv_end() { keep_going = false; } @@ -294,6 +361,33 @@ mod uv { comm::send(loop, msg); } + fn timer_start(the_timer: uv_handle, timeout: u32, repeat:u32, + timer_cb: fn~(uv_handle)) { + alt the_timer { + uv_timer(id, loop_chan) { + let msg = msg_timer_start(id, timeout, repeat, timer_cb); + comm::send(loop_chan, msg); + } + _ { + fail "can only pass a uv_timer form of uv_handle to "+ + " uv::timer_start()"; + } + } + } + + fn timer_stop(the_timer: uv_handle, after_cb: fn~(uv_handle)) { + alt the_timer { + uv_timer(id, loop_chan) { + let msg = msg_timer_stop(id, after_cb); + comm::send(loop_chan, msg); + } + _ { + fail "only uv_timer form is allowed in calls to "+ + " uv::timer_stop()"; + } + } + } + // internal functions fn pass_to_libuv( op_handle: *ctypes::void, @@ -320,7 +414,7 @@ mod uv { fn get_loop_chan_from_handle(handle: uv_handle) -> uv_loop { alt handle { - uv_async(id,loop) { + uv_async(id,loop) | uv_timer(id,loop) { ret loop; } _ { @@ -332,7 +426,7 @@ mod uv { fn get_id_from_handle(handle: uv_handle) -> [u8] { alt handle { - uv_async(id,loop) { + uv_async(id,loop) | uv_timer(id,loop) { ret id; } _ { @@ -363,6 +457,24 @@ mod uv { op_close(handle, handle_ptr) { handle_op_close(handle, handle_ptr); } + op_timer_init(id) { + let id_ptr = vec::unsafe::to_ptr(id); + let timer_handle = rustrt::rust_uvtmp_uv_timer_init( + loop, + process_timer_call, + id_ptr); + comm::send(loop_chan, uv_timer_init( + id, + timer_handle)); + } + op_timer_start(id, handle, timeout, repeat) { + rustrt::rust_uvtmp_uv_timer_start(handle, timeout, + repeat); + } + op_timer_stop(id, handle, after_cb) { + rustrt::rust_uvtmp_uv_timer_stop(handle); + comm::send(loop_chan, uv_timer_stop(id, after_cb)); + } _ { fail "unknown form of uv_operation received"; } } @@ -378,6 +490,11 @@ mod uv { rustrt::rust_uvtmp_uv_close( handle_ptr, cb); } + uv_timer(id, loop) { + let cb = process_close_timer; + rustrt::rust_uvtmp_uv_close( + handle_ptr, cb); + } _ { fail "unknown form of uv_handle encountered " + "in process_operation/op_close"; @@ -386,12 +503,19 @@ mod uv { } crust fn process_async_send(id_buf: *u8, data: *uv_loop_data) - unsafe { + unsafe { let handle_id = get_handle_id_from(id_buf); let loop_chan = get_loop_chan_from_data(data); comm::send(loop_chan, uv_async_send(handle_id)); } + crust fn process_timer_call(id_buf: *u8, data: *uv_loop_data) + unsafe { + let handle_id = get_handle_id_from(id_buf); + let loop_chan = get_loop_chan_from_data(data); + comm::send(loop_chan, uv_timer_call(handle_id)); + } + fn process_close_common(id: [u8], data: *uv_loop_data) unsafe { // notify the rust loop that their handle is closed, then @@ -414,6 +538,16 @@ mod uv { // close cb process_close_common(id, data); } + + crust fn process_close_timer( + id_buf: *u8, + handle_ptr: *ctypes::void, + data: *uv_loop_data) + unsafe { + let id = get_handle_id_from(id_buf); + rustrt::rust_uvtmp_uv_close_timer(handle_ptr); + process_close_common(id, data); + } } @@ -446,11 +580,15 @@ fn test_uvtmp_uv_timer() { let test_loop = uv::loop_new(); let exit_port = comm::port::<bool>(); let exit_chan = comm::chan::<bool>(exit_port); - uv::timer(test_loop, {|new_timer| - uv::timer_start(new_async) {|| - comm::send(exit_chan, true); + uv::timer_init(test_loop) {|new_timer| + uv::timer_start(new_timer, 1u32, 0u32) {|started_timer| + uv::timer_stop(started_timer) {|stopped_timer| + uv::close(stopped_timer) {|| + comm::send(exit_chan, true); + }; + }; }; - }); + }; uv::run(test_loop); assert comm::recv(exit_port); } |
