From b39a43cd5c12808c615e4f65366a04687317daa1 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Mon, 2 Apr 2012 11:03:45 -0700 Subject: [PATCH] adding uv_hl module and some doc work --- src/libstd/std.rc | 1 + src/libstd/uv.rs | 34 +++++++++------- src/libstd/uv_hl.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++ src/libstd/uv_ll.rs | 22 +++++++++++ 4 files changed, 138 insertions(+), 14 deletions(-) create mode 100644 src/libstd/uv_hl.rs diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 7469e318322..b2486b41cdc 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -27,6 +27,7 @@ mod net; // libuv modules mod uv; mod uv_ll; +mod uv_hl; // Utility modules diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs index f5ee758a368..5099ef07491 100644 --- a/src/libstd/uv.rs +++ b/src/libstd/uv.rs @@ -1,23 +1,26 @@ #[doc = " Rust bindings to libuv -This crate provides a low-level mapping to libuv, a library for -running an asynchronous event loop, with extensive IO operations. +This is the base-module for various levels of bindings to +the libuv library. -This crate is seeing heavy work, currently, and the final API layout -should not be inferred from its current form. +These modules are seeing heavy work, currently, and the final +API layout should not be inferred from its current form. -The base module contains a set of safe functions for creating -an event loop that runs within a single task, but allows operations -against it from other tasks, but funneling it through a uv_async -request which reads from a port that users write to. This API should -not be considered stable and may go away in the near future. +This base module currently contains a historical, rust-based +implementation of a few libuv operations that hews closely to +the patterns of the libuv C-API. It was used, mostly, to explore +some implementation details and will most likely be deprecated +in the near future. -The 'll' module contains low-level, bare-metal mappings to the libuv -C-api. All functions within this module are marked unsafe and should -be used, primarily, for composing rust-idiomatic abstractions. In -lieu of satisfactory documention for the 'll' module, itself, libuv's -uv.h should be consulted. +The `ll` module contains low-level mappings for working directly +with the libuv C-API. + +The `hl` module contains a set of tools library developers can +use for interacting with an active libuv loop. This modules's +API is meant to be used to write high-level, +rust-idiomatic abstractions for utilizes libuv's asynchronous IO +facilities. "]; import map::hashmap; @@ -28,6 +31,9 @@ export timer_init, timer_start, timer_stop; import ll = uv_ll; export ll; +import hl = uv_hl; +export hl; + #[nolink] native mod rustrt { fn rust_uv_loop_new() -> *libc::c_void; diff --git a/src/libstd/uv_hl.rs b/src/libstd/uv_hl.rs new file mode 100644 index 00000000000..753af6f090b --- /dev/null +++ b/src/libstd/uv_hl.rs @@ -0,0 +1,95 @@ +#[doc = " +High-level bindings to work with the libuv library. + +This module is geared towards library developers who want to +provide a high-level, abstracted interface to some set of +libuv functionality. +"]; + +import ll = uv_ll; + +export high_level_loop; +export interact, prepare_loop; + +#[doc = " +Used to abstract-away direct interaction with a libuv loop. + +# Fields + +* async_handle - a pointer to a uv_async_t struct used to 'poke' +the C uv loop to process any pending callbacks + +* op_chan - a channel used to send function callbacks to be processed +by the C uv loop +"] +type high_level_loop = { + async_handle: *ll::uv_async_t, + op_chan: comm::chan +}; + +#[doc = " +Pass in a callback to be processed on the running libuv loop's thread + +# Fields + +* a_loop - a high_level_loop record that represents a channel of +communication with an active libuv loop running on a thread +somwhere in the current process + +* cb - a function callback to be processed on the running loop's +thread. The only parameter is an opaque pointer to the running +uv_loop_t. You can use this pointer to initiate or continue any +operations against the loop +"] +unsafe fn interact(a_loop: high_level_loop, + -cb: fn~(*libc::c_void)) { + comm::send(a_loop.op_chan, cb); + ll::async_send(a_loop.async_handle); +} + +#[doc = " +Prepares a clean, inactive uv_loop_t* to be used with any of the +functions in the `uv::hl` module. + +Library developers can use this function to prepare a given +`uv_loop_t*`, whose lifecycle they manage, to be used, ran +and controlled with the tools in this module. + +After this is ran against a loop, a library developer can run +the loop in its own thread and then use the returned +`high_level_loop` to interact with it. + +# Fields + +* loop_ptr - a pointer to a newly created `uv_loop_t*` with no +handles registered (this will interfere with the internal lifecycle +management this module provides). Ideally, this should be called +immediately after using `uv::ll::loop_new()` + +# Returns + +A `high_level_loop` record that can be used to interact with the +loop (after you use `uv::ll::run()` on the `uv_loop_t*`, of course +"] +unsafe fn prepare_loop(loop_ptr: *libc::c_void) + -> high_level_loop { + // will probably need to stake out a data record + // here, as well, to keep whatever state we want to + // use with the loop + + // move this into a malloc + let async = ll::async_t(); + let async_ptr = ptr::addr_of(async); + let async_result = ll::async_init(loop_ptr, + async_ptr, + interact_ptr); + if (async_result != 0i32) { + fail ll::get_last_err_info(loop_ptr); + } +} + +// this will be invoked by a called to uv::hl::interact(), so +// we'll drain the port of pending callbacks, processing each +crust fn interact_poke(async_handle: *libc::c_void) { + // nothing here, yet. +} \ No newline at end of file diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index 520298ca5c0..a3e934e1ee8 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -1,3 +1,25 @@ +#[doc = " +Low-level bindings to the libuv library. + +This module contains a set of direct, 'bare-metal' wrappers around +the libuv C-API. + +Also contained herein are a set of rust records that map, in +approximate memory-size, to the libuv data structures. The record +implementations are adjusted, per-platform, to match their respective +representations. + +There are also a collection of helper functions to ease interacting +with the low-level API (such as a function to return the latest +libuv error as a rust-formatted string). + +As new functionality, existant in uv.h, is added to the rust stdlib, +the mappings should be added in this module. + +This module's implementation will hopefully be, eventually, replaced +with per-platform, generated source files from rust-bindgen. +"]; + // libuv struct mappings type uv_ip4_addr = { ip: [u8],