diff options
| author | Jeff Olson <olson.jeffery@gmail.com> | 2012-02-22 14:00:34 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-02-28 17:56:15 -0800 |
| commit | bb5960aa57a04920614fce021c6792ad8a9a0305 (patch) | |
| tree | 0ab7ded812141b2a858e623d39af36e9034f7788 /src/libstd/uvtmp.rs | |
| parent | cf08ed64584cd13eb3fb98ca07d3e3b987103c16 (diff) | |
| download | rust-bb5960aa57a04920614fce021c6792ad8a9a0305.tar.gz rust-bb5960aa57a04920614fce021c6792ad8a9a0305.zip | |
moving new uv stuff into uv.rs and rust_uv.cpp
- removing the remains of uvtmp.rs and rust_uvtmp.rs - removing the displaced, low-level libuv bindings in uv.rs and rust_uv.cpp
Diffstat (limited to 'src/libstd/uvtmp.rs')
| -rw-r--r-- | src/libstd/uvtmp.rs | 730 |
1 files changed, 0 insertions, 730 deletions
diff --git a/src/libstd/uvtmp.rs b/src/libstd/uvtmp.rs deleted file mode 100644 index b64de837b09..00000000000 --- a/src/libstd/uvtmp.rs +++ /dev/null @@ -1,730 +0,0 @@ -// Some temporary libuv hacks for servo - -// UV2 - -// these are processed solely in the -// process_operation() crust fn below -enum uv_operation { - op_async_init([u8]), - 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_timer([u8], uv_loop) -} - -enum uv_msg { - // requests from library users - msg_run(comm::chan<bool>), - msg_run_in_bg(), - 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() -} - -type uv_loop_data = { - operation_port: comm::port<uv_operation>, - rust_loop_chan: comm::chan<uv_msg> -}; - -type uv_loop = comm::chan<uv_msg>; - -#[nolink] -native mod rustrt { - fn rust_uvtmp_create_thread() -> thread; - fn rust_uvtmp_start_thread(thread: thread); - fn rust_uvtmp_join_thread(thread: thread); - fn rust_uvtmp_delete_thread(thread: thread); - fn rust_uvtmp_connect( - thread: thread, - req_id: u32, - ip: str::sbuf, - chan: comm::chan<iomsg>) -> connect_data; - fn rust_uvtmp_close_connection(thread: thread, req_id: u32); - fn rust_uvtmp_write( - thread: thread, - req_id: u32, - buf: *u8, - len: ctypes::size_t, - chan: comm::chan<iomsg>); - fn rust_uvtmp_read_start( - thread: thread, - req_id: u32, - chan: comm::chan<iomsg>); - fn rust_uvtmp_timer( - thread: thread, - timeout: u32, - req_id: u32, - chan: comm::chan<iomsg>); - fn rust_uvtmp_delete_buf(buf: *u8); - fn rust_uvtmp_get_req_id(cd: connect_data) -> u32; - - fn rust_uvtmp_uv_loop_new() -> *ctypes::void; - fn rust_uvtmp_uv_loop_set_data( - loop: *ctypes::void, - data: *uv_loop_data); - fn rust_uvtmp_uv_bind_op_cb(loop: *ctypes::void, cb: *u8) - -> *ctypes::void; - fn rust_uvtmp_uv_stop_op_cb(handle: *ctypes::void); - 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_start, timer_stop; - - // public functions - fn loop_new() -> uv_loop unsafe { - let ret_recv_port: comm::port<uv_loop> = - comm::port(); - let ret_recv_chan: comm::chan<uv_loop> = - comm::chan(ret_recv_port); - - task::spawn_sched(task::manual_threads(4u)) {|| - // our beloved uv_loop_t ptr - let loop_handle = rustrt:: - rust_uvtmp_uv_loop_new(); - - // this port/chan pair are used to send messages to - // libuv. libuv processes any pending messages on the - // port (via crust) after receiving an async "wakeup" - // on a special uv_async_t handle created below - let operation_port = comm::port::<uv_operation>(); - let operation_chan = comm::chan::<uv_operation>( - operation_port); - - // this port/chan pair as used in the while() loop - // below. It takes dispatches, originating from libuv - // callbacks, to invoke handles registered by the - // user - let rust_loop_port = comm::port::<uv_msg>(); - let rust_loop_chan = - comm::chan::<uv_msg>(rust_loop_port); - // let the task-spawner return - comm::send(ret_recv_chan, copy(rust_loop_chan)); - - // create our "special" async handle that will - // allow all operations against libuv to be - // "buffered" in the operation_port, for processing - // from the thread that libuv runs on - let loop_data: uv_loop_data = { - operation_port: operation_port, - rust_loop_chan: rust_loop_chan - }; - rustrt::rust_uvtmp_uv_loop_set_data( - loop_handle, - ptr::addr_of(loop_data)); // pass an opaque C-ptr - // to libuv, this will be - // in the process_operation - // crust fn - let op_handle = rustrt::rust_uvtmp_uv_bind_op_cb( - loop_handle, - process_operation); - - // all state goes here - let handles: map::map<[u8], *ctypes::void> = - map::new_bytes_hash(); - let id_to_handle: map::map<[u8], uv_handle> = - map::new_bytes_hash(); - 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 - // event loop. - let keep_going = true; - while (keep_going) { - alt comm::recv(rust_loop_port) { - msg_run(end_chan) { - // start the libuv event loop - // we'll also do a uv_async_send with - // the operation handle to have the - // loop process any pending operations - // once its up and running - task::spawn_sched(task::manual_threads(1u)) {|| - // this call blocks - rustrt::rust_uvtmp_uv_run(loop_handle); - // when we're done, msg the - // end chan - rustrt::rust_uvtmp_uv_stop_op_cb(op_handle); - comm::send(end_chan, true); - comm::send(rust_loop_chan, uv_end); - }; - } - - msg_run_in_bg { - task::spawn_sched(task::manual_threads(1u)) {|| - // this call blocks - rustrt::rust_uvtmp_uv_run(loop_handle); - }; - } - - msg_close(handle, cb) { - let id = get_id_from_handle(handle); - close_callbacks.insert(id, cb); - let handle_ptr = handles.get(id); - let op = op_close(handle, handle_ptr); - - pass_to_libuv(op_handle, operation_chan, op); - } - uv_close(id) { - handles.remove(id); - let handle = id_to_handle.get(id); - id_to_handle.remove(id); - alt handle { - 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"; - } - } - let cb = close_callbacks.get(id); - close_callbacks.remove(id); - task::spawn {|| - cb(); - }; - } - - msg_async_init(callback, after_cb) { - // create a new async handle - // with the id as the handle's - // data and save the callback for - // invocation on msg_async_send - let id = gen_handle_id(); - async_cbs.insert(id, callback); - after_cbs.insert(id, after_cb); - let op = op_async_init(id); - pass_to_libuv(op_handle, operation_chan, op); - } - uv_async_init(id, async_handle) { - // libuv created a handle, which is - // passed back to us. save it and - // then invoke the supplied callback - // for after completion - handles.insert(id, async_handle); - 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 {|| - after_cb(async); - }; - } - - msg_async_send(id) { - let async_handle = handles.get(id); - do_send(async_handle); - } - uv_async_send(id) { - let async_cb = async_cbs.get(id); - task::spawn {|| - 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; - } - - _ { fail "unknown form of uv_msg received"; } - } - } - }; - ret comm::recv(ret_recv_port); - } - - fn run(loop: uv_loop) { - let end_port = comm::port::<bool>(); - let end_chan = comm::chan::<bool>(end_port); - comm::send(loop, msg_run(end_chan)); - comm::recv(end_port); - } - - fn run_in_bg(loop: uv_loop) { - comm::send(loop, msg_run_in_bg); - } - - fn async_init ( - loop: uv_loop, - async_cb: fn~(uv_handle), - after_cb: fn~(uv_handle)) { - let msg = msg_async_init(async_cb, after_cb); - comm::send(loop, msg); - } - - fn async_send(async: uv_handle) { - alt async { - uv_async(id, loop) { - comm::send(loop, msg_async_send(id)); - } - _ { - fail "attempting to call async_send() with a" + - " uv_async uv_handle"; - } - } - } - - fn close(h: uv_handle, cb: fn~()) { - let loop_chan = get_loop_chan_from_handle(h); - comm::send(loop_chan, msg_close(h, cb)); - } - - fn timer_init(loop: uv_loop, after_cb: fn~(uv_handle)) { - let msg = msg_timer_init(after_cb); - 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, - operation_chan: comm::chan<uv_operation>, - op: uv_operation) unsafe { - comm::send(operation_chan, copy(op)); - do_send(op_handle); - } - fn do_send(h: *ctypes::void) { - rustrt::rust_uvtmp_uv_async_send(h); - } - fn gen_handle_id() -> [u8] { - ret rand::mk_rng().gen_bytes(16u); - } - fn get_handle_id_from(buf: *u8) -> [u8] unsafe { - ret vec::unsafe::from_buf(buf, 16u); - } - - fn get_loop_chan_from_data(data: *uv_loop_data) - -> uv_loop unsafe { - ret (*data).rust_loop_chan; - } - - fn get_loop_chan_from_handle(handle: uv_handle) - -> uv_loop { - alt handle { - uv_async(id,loop) | uv_timer(id,loop) { - ret loop; - } - _ { - fail "unknown form of uv_handle for get_loop_chan_from " - + " handle"; - } - } - } - - fn get_id_from_handle(handle: uv_handle) -> [u8] { - alt handle { - uv_async(id,loop) | uv_timer(id,loop) { - ret id; - } - _ { - fail "unknown form of uv_handle for get_id_from handle"; - } - } - } - - // crust - crust fn process_operation( - loop: *ctypes::void, - data: *uv_loop_data) unsafe { - let op_port = (*data).operation_port; - let loop_chan = get_loop_chan_from_data(data); - let op_pending = comm::peek(op_port); - while(op_pending) { - alt comm::recv(op_port) { - op_async_init(id) { - let id_ptr = vec::unsafe::to_ptr(id); - let async_handle = rustrt::rust_uvtmp_uv_async_init( - loop, - process_async_send, - id_ptr); - comm::send(loop_chan, uv_async_init( - id, - async_handle)); - } - 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"; } - } - op_pending = comm::peek(op_port); - } - } - - fn handle_op_close(handle: uv_handle, handle_ptr: *ctypes::void) { - // it's just like im doing C - alt handle { - uv_async(id, loop) { - let cb = process_close_async; - 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"; - } - } - } - - crust fn process_async_send(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_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 - // the caller will invoke a per-handle-type c++ func to - // free allocated memory - let loop_chan = get_loop_chan_from_data(data); - comm::send(loop_chan, uv_close(id)); - } - - crust fn process_close_async( - 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_async(handle_ptr); - // at this point, the handle and its data has been - // released. notify the rust loop to remove the - // handle and its data and call the user-supplied - // 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); - } - -} - -#[test] -fn test_uvtmp_uv_new_loop_no_handles() { - let test_loop = uv::loop_new(); - uv::run(test_loop); // this should return immediately - // since there aren't any handles.. -} - -#[test] -fn test_uvtmp_uv_simple_async() { - let test_loop = uv::loop_new(); - let exit_port = comm::port::<bool>(); - let exit_chan = comm::chan::<bool>(exit_port); - uv::async_init(test_loop, {|new_async| - uv::close(new_async) {|| - comm::send(exit_chan, true); - }; - }, {|new_async| - uv::async_send(new_async); - }); - uv::run(test_loop); - assert comm::recv(exit_port); -} - -#[test] -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_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); -} - -// END OF UV2 - -type thread = *ctypes::void; - -type connect_data = *ctypes::void; - -enum iomsg { - whatever, - connected(connect_data), - wrote(connect_data), - read(connect_data, *u8, ctypes::ssize_t), - timer(u32), - exit -} - -fn create_thread() -> thread { - rustrt::rust_uvtmp_create_thread() -} - -fn start_thread(thread: thread) { - rustrt::rust_uvtmp_start_thread(thread) -} - -fn join_thread(thread: thread) { - rustrt::rust_uvtmp_join_thread(thread) -} - -fn delete_thread(thread: thread) { - rustrt::rust_uvtmp_delete_thread(thread) -} - -fn connect(thread: thread, req_id: u32, - ip: str, ch: comm::chan<iomsg>) -> connect_data { - str::as_buf(ip) {|ipbuf| - rustrt::rust_uvtmp_connect(thread, req_id, ipbuf, ch) - } -} - -fn close_connection(thread: thread, req_id: u32) { - rustrt::rust_uvtmp_close_connection(thread, req_id); -} - -fn write(thread: thread, req_id: u32, bytes: [u8], - chan: comm::chan<iomsg>) unsafe { - rustrt::rust_uvtmp_write( - thread, req_id, vec::to_ptr(bytes), vec::len(bytes), chan); -} - -fn read_start(thread: thread, req_id: u32, - chan: comm::chan<iomsg>) { - rustrt::rust_uvtmp_read_start(thread, req_id, chan); -} - -fn timer_start(thread: thread, timeout: u32, req_id: u32, - chan: comm::chan<iomsg>) { - rustrt::rust_uvtmp_timer(thread, timeout, req_id, chan); -} - -fn delete_buf(buf: *u8) { - rustrt::rust_uvtmp_delete_buf(buf); -} - -fn get_req_id(cd: connect_data) -> u32 { - ret rustrt::rust_uvtmp_get_req_id(cd); -} - -#[test] -fn test_start_stop() { - let thread = create_thread(); - start_thread(thread); - join_thread(thread); - delete_thread(thread); -} - -#[test] -#[ignore] -fn test_connect() { - let thread = create_thread(); - start_thread(thread); - let port = comm::port(); - let chan = comm::chan(port); - connect(thread, 0u32, "74.125.224.146", chan); - alt comm::recv(port) { - connected(cd) { - close_connection(thread, 0u32); - } - _ { fail "test_connect: port isn't connected"; } - } - join_thread(thread); - delete_thread(thread); -} - -#[test] -#[ignore] -fn test_http() { - let thread = create_thread(); - start_thread(thread); - let port = comm::port(); - let chan = comm::chan(port); - connect(thread, 0u32, "74.125.224.146", chan); - alt comm::recv(port) { - connected(cd) { - write(thread, 0u32, str::bytes("GET / HTTP/1.0\n\n"), chan); - alt comm::recv(port) { - wrote(cd) { - read_start(thread, 0u32, chan); - let keep_going = true; - while keep_going { - alt comm::recv(port) { - read(_, buf, -1) { - keep_going = false; - delete_buf(buf); - } - read(_, buf, len) { - unsafe { - log(error, len); - let buf = vec::unsafe::from_buf(buf, - len as uint); - let str = str::from_bytes(buf); - #error("read something"); - io::println(str); - } - delete_buf(buf); - } - _ { fail "test_http: protocol error"; } - } - } - close_connection(thread, 0u32); - } - _ { fail "test_http: expected `wrote`"; } - } - } - _ { fail "test_http: port not connected"; } - } - join_thread(thread); - delete_thread(thread); -} |
