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/rt/rust_uv.cpp | |
| 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/rt/rust_uv.cpp')
| -rw-r--r-- | src/rt/rust_uv.cpp | 186 |
1 files changed, 159 insertions, 27 deletions
diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 9ee1b844add..03cd75d4805 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -1,51 +1,183 @@ #include "rust_internal.h" #include "uv.h" -/* - Wrappers of uv_* functions. These can be eliminated by figuring - out how to build static uv with externs, or by just using dynamic libuv - */ +// crust fn pointers +typedef void (*crust_async_op_cb)(uv_loop_t* loop, void* data); +typedef void (*crust_simple_cb)(uint8_t* id_buf, void* loop_data); +typedef void (*crust_close_cb)(uint8_t* id_buf, void* handle, + void* data); -extern "C" CDECL uv_loop_t* -rust_uv_default_loop() { - return uv_default_loop(); +// data types +#define RUST_UV_HANDLE_LEN 16 + +struct handle_data { + uint8_t id_buf[RUST_UV_HANDLE_LEN]; + crust_simple_cb cb; + crust_close_cb close_cb; +}; + +// helpers +static void* +current_kernel_malloc(size_t size, const char* tag) { + void* ptr = rust_task_thread::get_task()->kernel->malloc(size, tag); + return ptr; +} + +static void +current_kernel_free(void* ptr) { + rust_task_thread::get_task()->kernel->free(ptr); +} + +static handle_data* +new_handle_data_from(uint8_t* buf, crust_simple_cb cb) { + handle_data* data = (handle_data*)current_kernel_malloc( + sizeof(handle_data), + "handle_data"); + memcpy(data->id_buf, buf, RUST_UV_HANDLE_LEN); + data->cb = cb; + return data; +} + +// libuv callback impls +static void +native_crust_async_op_cb(uv_async_t* handle, int status) { + crust_async_op_cb cb = (crust_async_op_cb)handle->data; + void* loop_data = handle->loop->data; + cb(handle->loop, loop_data); +} + +static void +native_async_cb(uv_async_t* handle, int status) { + handle_data* handle_d = (handle_data*)handle->data; + void* loop_data = handle->loop->data; + handle_d->cb(handle_d->id_buf, loop_data); +} + +static void +native_timer_cb(uv_timer_t* handle, int status) { + handle_data* handle_d = (handle_data*)handle->data; + void* loop_data = handle->loop->data; + handle_d->cb(handle_d->id_buf, loop_data); +} + +static void +native_close_cb(uv_handle_t* handle) { + handle_data* data = (handle_data*)handle->data; + data->close_cb(data->id_buf, handle, handle->loop->data); } -extern "C" CDECL uv_loop_t* +static void +native_close_op_cb(uv_handle_t* op_handle) { + uv_loop_t* loop = op_handle->loop; + current_kernel_free(op_handle); + loop->data = 0; // a ptr to some stack-allocated rust mem + uv_loop_delete(loop); +} + +// native fns bound in rust +extern "C" void* rust_uv_loop_new() { - return uv_loop_new(); + return (void*)uv_loop_new(); +} + +extern "C" void +rust_uv_loop_set_data(uv_loop_t* loop, void* data) { + loop->data = data; } -extern "C" CDECL void -rust_uv_loop_delete(uv_loop_t *loop) { - return uv_loop_delete(loop); +extern "C" void* +rust_uv_bind_op_cb(uv_loop_t* loop, crust_async_op_cb cb) { + uv_async_t* async = (uv_async_t*)current_kernel_malloc( + sizeof(uv_async_t), + "uv_async_t"); + uv_async_init(loop, async, native_crust_async_op_cb); + async->data = (void*)cb; + // decrement the ref count, so that our async bind + // doesn't count towards keeping the loop alive + uv_unref(loop); + return async; } -extern "C" CDECL int -rust_uv_run(uv_loop_t *loop) { - return uv_run(loop); +extern "C" void +rust_uv_stop_op_cb(uv_handle_t* op_handle) { + /* // this is a hack to get libuv to cleanup a + // handle that was made to not prevent the loop + // from exiting via uv_unref(). + uv_ref(op_handle->loop); + uv_close(op_handle, native_close_op_cb); + uv_run(op_handle->loop); // this should process the handle's + // close event and then return + */ + // the above code is supposed to work to cleanly close + // a handler that was uv_unref()'d. but it causes much spew + // instead. this is the ugly/quick way to deal w/ it for now. + uv_close(op_handle, native_close_op_cb); + native_close_op_cb(op_handle); } -extern "C" CDECL void -rust_uv_unref(uv_loop_t *loop) { - return uv_unref(loop); +extern "C" void +rust_uv_run(uv_loop_t* loop) { + uv_run(loop); } -extern "C" CDECL int -rust_uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) { - return uv_idle_init(loop, idle); +extern "C" void +rust_uv_close(uv_handle_t* handle, crust_close_cb cb) { + handle_data* data = (handle_data*)handle->data; + data->close_cb = cb; + uv_close(handle, native_close_cb); } -extern "C" CDECL int -rust_uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) { - return uv_idle_start(idle, cb); +extern "C" void +rust_uv_close_async(uv_async_t* handle) { + current_kernel_free(handle->data); + current_kernel_free(handle); } +extern "C" void +rust_uv_close_timer(uv_async_t* handle) { + current_kernel_free(handle->data); + current_kernel_free(handle); +} + +extern "C" void +rust_uv_async_send(uv_async_t* handle) { + uv_async_send(handle); +} +extern "C" void* +rust_uv_async_init(uv_loop_t* loop, crust_simple_cb cb, + uint8_t* buf) { + uv_async_t* async = (uv_async_t*)current_kernel_malloc( + sizeof(uv_async_t), + "uv_async_t"); + uv_async_init(loop, async, native_async_cb); + handle_data* data = new_handle_data_from(buf, cb); + async->data = data; + return async; +} + +extern "C" void* +rust_uv_timer_init(uv_loop_t* loop, crust_simple_cb cb, + uint8_t* buf) { + uv_timer_t* new_timer = (uv_timer_t*)current_kernel_malloc( + sizeof(uv_timer_t), + "uv_timer_t"); + uv_timer_init(loop, new_timer); + handle_data* data = new_handle_data_from(buf, cb); + new_timer->data = data; + + return new_timer; +} + +extern "C" void +rust_uv_timer_start(uv_timer_t* the_timer, uint32_t timeout, + uint32_t repeat) { + uv_timer_start(the_timer, native_timer_cb, timeout, repeat); +} -extern "C" CDECL size_t -rust_uv_size_of_idle_t() { - return sizeof(uv_idle_t); +extern "C" void +rust_uv_timer_stop(uv_timer_t* the_timer) { + uv_timer_stop(the_timer); } |
