Skip to content

Commit

Permalink
Pack/unpack epoll_event structs.
Browse files Browse the repository at this point in the history
Rust does not support packed types at this point. Pack and unpack the arguments
to epoll_ctl() and epoll_wait() manually.
  • Loading branch information
bnoordhuis committed Feb 6, 2012
1 parent 06c62b8 commit 8fc89ae
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions epoll.rs
Expand Up @@ -47,28 +47,80 @@ type epoll_event = {
#[nolink]
native mod __glibc {
fn epoll_create1(flags: c_int) -> c_int;
/*
fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: epoll_event) -> c_int;
fn epoll_wait(epfd: c_int,
events: *mutable epoll_event,
maxevents: c_int,
timeout: c_int) -> c_int;
*/
fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *u8) -> c_int;
fn epoll_wait(epfd: c_int,
events: *mutable u8,
maxevents: c_int,
timeout: c_int) -> c_int;
}

fn epoll_create1(flags: int) -> int {
__glibc::epoll_create1(flags as c_int) as int
}

fn epoll_ctl(epfd: int, op: int, fd: int, event: epoll_event) -> int {
/*
__glibc::epoll_ctl(epfd as c_int, op as c_int, fd as c_int, event) as int
*/

let buf: [mutable u8] = vec::init_elt_mut(12u, 0u8);

// rust as of 2012-02-06 does not support packed types, hence we have to do
// the packing and unpacking ourselves
unsafe {
let p1: *mutable i32 = unsafe::reinterpret_cast(ptr::mut_addr_of(buf[0]));
let p2: *mutable u64 = unsafe::reinterpret_cast(ptr::mut_addr_of(buf[4]));
*p1 = event.events;
*p2 = event.data;
}

ret __glibc::epoll_ctl(epfd as c_int,
op as c_int,
fd as c_int,
ptr::addr_of(buf[0])) as int
}

fn epoll_wait(epfd: int, events: [mutable epoll_event], timeout: int) -> int {
/*
let pevents: *mutable epoll_event = ptr::mut_addr_of(events[0]);
let maxevents: c_int = vec::len(events) as c_int;
ret __glibc::epoll_wait(epfd as c_int,
pevents,
maxevents,
timeout as c_int) as int;
*/

let buf: [mutable u8] = vec::init_elt_mut(12u * vec::len(events), 0u8);

let nevents = __glibc::epoll_wait(epfd as c_int,
ptr::mut_addr_of(buf[0]),
vec::len(events) as c_int,
timeout as c_int) as int;

if (nevents == -1) {
ret -1;
}

// rust as of 2012-02-06 does not support packed types, hence we have to do
// the packing and unpacking ourselves
let i = 0;
while (i < nevents) {
unsafe {
let p1: *i32 = unsafe::reinterpret_cast(ptr::addr_of(buf[i * 12]));
let p2: *u64 = unsafe::reinterpret_cast(ptr::addr_of(buf[i * 12 + 4]));
events[i] = {events: *p1, data: *p2};
}
i += 1;
}

ret nevents;
}

#[test]
Expand Down

0 comments on commit 8fc89ae

Please sign in to comment.