stdlib: Implement some preliminary libuv bindings
std::uv is intended to be low-level, exactly mirroring the C API. Difficult to continue the implementation now without scheduler improvements.
This commit is contained in:
parent
b2fd6121c0
commit
7476a39e47
1
mk/rt.mk
1
mk/rt.mk
@ -47,6 +47,7 @@ RUNTIME_CS_$(1) := \
|
||||
rt/rust_task_list.cpp \
|
||||
rt/rust_port.cpp \
|
||||
rt/rust_upcall.cpp \
|
||||
rt/rust_uv.cpp \
|
||||
rt/rust_log.cpp \
|
||||
rt/rust_timer.cpp \
|
||||
rt/circular_buffer.cpp \
|
||||
|
@ -364,3 +364,26 @@
|
||||
fun:_Znwj
|
||||
fun:_ZN4llvm4UsernwEjj
|
||||
}
|
||||
|
||||
{
|
||||
libuv-0-byte-realloc1
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:realloc
|
||||
fun:ev_realloc_emul
|
||||
fun:ev_realloc
|
||||
fun:epoll_destroy
|
||||
fun:ev_loop_destroy
|
||||
fun:uv_loop_delete
|
||||
}
|
||||
|
||||
{
|
||||
libuv-0-byte-realloc2
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:realloc
|
||||
fun:ev_realloc_emul
|
||||
fun:ev_realloc
|
||||
fun:ev_loop_destroy
|
||||
fun:uv_loop_delete
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ Definitions useful for C interop
|
||||
|
||||
type c_int = i32;
|
||||
|
||||
type void = int; // Not really the same as C
|
||||
type long = int;
|
||||
type unsigned = u32;
|
||||
type ulong = uint;
|
||||
@ -23,3 +24,6 @@ type off_t = uint;
|
||||
|
||||
type fd_t = i32; // not actually a C type, but should be.
|
||||
type pid_t = i32;
|
||||
|
||||
// enum is implementation-defined, but is 32-bits in practice
|
||||
type enum = u32;
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
export box, char, float, int, str, ptr;
|
||||
export uint, u8, u32, u64, vec, bool;
|
||||
export comm, fs, io, net, run, sys, task;
|
||||
export comm, fs, io, net, run, sys, task, uv;
|
||||
export c_vec, ctypes, either, option, result, four, tri, util;
|
||||
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
|
||||
export rope;
|
||||
@ -46,6 +46,7 @@ mod net;
|
||||
mod run;
|
||||
mod sys;
|
||||
mod task;
|
||||
mod uv;
|
||||
|
||||
|
||||
// Utility modules
|
||||
|
150
src/lib/uv.rs
Normal file
150
src/lib/uv.rs
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
This is intended to be a low-level binding to libuv that very closely mimics
|
||||
the C libuv API. Does very little right now pending scheduler improvements.
|
||||
*/
|
||||
|
||||
#[cfg(target_os = "linux")];
|
||||
#[cfg(target_os = "macos")];
|
||||
|
||||
export sanity_check;
|
||||
export loop_t, idle_t;
|
||||
export loop_new, loop_delete, default_loop, run, unref;
|
||||
export idle_init, idle_start;
|
||||
export idle_new;
|
||||
|
||||
#[link_name = "rustrt"]
|
||||
native mod uv {
|
||||
fn rust_uv_loop_new() -> *loop_t;
|
||||
fn rust_uv_loop_delete(loop: *loop_t);
|
||||
fn rust_uv_default_loop() -> *loop_t;
|
||||
fn rust_uv_run(loop: *loop_t) -> ctypes::c_int;
|
||||
fn rust_uv_unref(loop: *loop_t);
|
||||
fn rust_uv_idle_init(loop: *loop_t, idle: *idle_t) -> ctypes::c_int;
|
||||
fn rust_uv_idle_start(idle: *idle_t, cb: idle_cb) -> ctypes::c_int;
|
||||
}
|
||||
|
||||
#[link_name = "rustrt"]
|
||||
native mod helpers {
|
||||
fn rust_uv_size_of_idle_t() -> ctypes::size_t;
|
||||
}
|
||||
|
||||
type opaque_cb = *ctypes::void;
|
||||
|
||||
type handle_type = ctypes::enum;
|
||||
|
||||
type close_cb = opaque_cb;
|
||||
type idle_cb = opaque_cb;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "macos")]
|
||||
type handle_private_fields = {
|
||||
a00: ctypes::c_int,
|
||||
a01: ctypes::c_int,
|
||||
a02: ctypes::c_int,
|
||||
a03: ctypes::c_int,
|
||||
a04: ctypes::c_int,
|
||||
a05: ctypes::c_int,
|
||||
a06: int,
|
||||
a07: int,
|
||||
a08: int,
|
||||
a09: int,
|
||||
a10: int,
|
||||
a11: int,
|
||||
a12: int
|
||||
};
|
||||
|
||||
type handle_fields = {
|
||||
loop: *loop_t,
|
||||
type_: handle_type,
|
||||
close_cb: close_cb,
|
||||
data: *ctypes::void,
|
||||
private: handle_private_fields
|
||||
};
|
||||
|
||||
type handle_t = {
|
||||
fields: handle_fields
|
||||
};
|
||||
|
||||
type loop_t = int;
|
||||
|
||||
|
||||
|
||||
|
||||
type idle_t = {
|
||||
fields: handle_fields
|
||||
/* private: idle_private_fields */
|
||||
};
|
||||
|
||||
fn idle_init(loop: *loop_t, idle: *idle_t) -> ctypes::c_int {
|
||||
uv::rust_uv_idle_init(loop, idle)
|
||||
}
|
||||
|
||||
fn idle_start(idle: *idle_t, cb: idle_cb) -> ctypes::c_int {
|
||||
uv::rust_uv_idle_start(idle, cb)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fn default_loop() -> *loop_t {
|
||||
uv::rust_uv_default_loop()
|
||||
}
|
||||
|
||||
fn loop_new() -> *loop_t {
|
||||
uv::rust_uv_loop_new()
|
||||
}
|
||||
|
||||
fn loop_delete(loop: *loop_t) {
|
||||
uv::rust_uv_loop_delete(loop)
|
||||
}
|
||||
|
||||
fn run(loop: *loop_t) -> ctypes::c_int {
|
||||
uv::rust_uv_run(loop)
|
||||
}
|
||||
|
||||
fn unref(loop: *loop_t) {
|
||||
uv::rust_uv_unref(loop)
|
||||
}
|
||||
|
||||
|
||||
fn sanity_check() {
|
||||
fn check_size(t: str, uv: ctypes::size_t, rust: ctypes::size_t) {
|
||||
log #fmt("size of %s: uv: %u, rust: %u", t, uv, rust);
|
||||
assert uv == rust;
|
||||
}
|
||||
check_size("idle_t",
|
||||
helpers::rust_uv_size_of_idle_t(),
|
||||
sys::size_of::<idle_t>());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn handle_fields_new() -> handle_fields {
|
||||
{
|
||||
loop: ptr::null(),
|
||||
type_: 0u32,
|
||||
close_cb: ptr::null(),
|
||||
data: ptr::null(),
|
||||
private: {
|
||||
a00: 0i32,
|
||||
a01: 0i32,
|
||||
a02: 0i32,
|
||||
a03: 0i32,
|
||||
a04: 0i32,
|
||||
a05: 0i32,
|
||||
a06: 0,
|
||||
a07: 0,
|
||||
a08: 0,
|
||||
a09: 0,
|
||||
a10: 0,
|
||||
a11: 0,
|
||||
a12: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn idle_new() -> idle_t {
|
||||
{
|
||||
fields: handle_fields_new()
|
||||
}
|
||||
}
|
50
src/rt/rust_uv.cpp
Normal file
50
src/rt/rust_uv.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#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
|
||||
*/
|
||||
|
||||
extern "C" CDECL uv_loop_t*
|
||||
rust_uv_default_loop() {
|
||||
return uv_default_loop();
|
||||
}
|
||||
|
||||
extern "C" CDECL uv_loop_t*
|
||||
rust_uv_loop_new() {
|
||||
return uv_loop_new();
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
rust_uv_loop_delete(uv_loop_t *loop) {
|
||||
return uv_loop_delete(loop);
|
||||
}
|
||||
|
||||
extern "C" CDECL int
|
||||
rust_uv_run(uv_loop_t *loop) {
|
||||
return uv_run(loop);
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
rust_uv_unref(uv_loop_t *loop) {
|
||||
return uv_unref(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" CDECL int
|
||||
rust_uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
|
||||
return uv_idle_start(idle, cb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" CDECL size_t
|
||||
rust_uv_size_of_idle_t() {
|
||||
return sizeof(uv_idle_t);
|
||||
}
|
@ -68,4 +68,12 @@ upcall_vec_push
|
||||
upcall_call_shim_on_c_stack
|
||||
upcall_new_stack
|
||||
upcall_del_stack
|
||||
asm_call_on_stack
|
||||
asm_call_on_stack
|
||||
rust_uv_default_loop
|
||||
rust_uv_loop_new
|
||||
rust_uv_loop_delete
|
||||
rust_uv_run
|
||||
rust_uv_unref
|
||||
rust_uv_idle_init
|
||||
rust_uv_idle_start
|
||||
rust_uv_size_of_idle_t
|
@ -40,6 +40,7 @@ mod tri;
|
||||
mod treemap;
|
||||
mod uint;
|
||||
mod unsafe;
|
||||
mod uv;
|
||||
mod vec;
|
||||
|
||||
// Local Variables:
|
||||
|
44
src/test/stdtest/uv.rs
Normal file
44
src/test/stdtest/uv.rs
Normal file
@ -0,0 +1,44 @@
|
||||
#[cfg(target_os = "linux")];
|
||||
#[cfg(target_os = "macos")];
|
||||
|
||||
import std::uv;
|
||||
import std::ptr;
|
||||
|
||||
#[test]
|
||||
fn sanity_check() {
|
||||
uv::sanity_check();
|
||||
}
|
||||
|
||||
// From test-ref.c
|
||||
mod test_ref {
|
||||
|
||||
#[test]
|
||||
fn ref() {
|
||||
let loop = uv::loop_new();
|
||||
uv::run(loop);
|
||||
uv::loop_delete(loop);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn idle_ref() {
|
||||
let loop = uv::loop_new();
|
||||
let h = uv::idle_new();
|
||||
uv::idle_init(loop, ptr::addr_of(h));
|
||||
uv::idle_start(ptr::addr_of(h), ptr::null());
|
||||
uv::unref(loop);
|
||||
uv::run(loop);
|
||||
uv::loop_delete(loop);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn async_ref() {
|
||||
/*
|
||||
let loop = uv::loop_new();
|
||||
let h = uv::async_new();
|
||||
uv::async_init(loop, ptr::addr_of(h), ptr::null());
|
||||
uv::unref(loop);
|
||||
uv::run(loop);
|
||||
uv::loop_delete(loop);
|
||||
*/
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user