From e6c6f8c7728efae0182ceebbcd72f60f3a609a6c Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 15 Oct 2014 22:40:35 +0200 Subject: Cargo-ify rust-epoll and update to v0.12. Resurrect the library and update it from Rust v0.2 (!) to v0.12. Cargo-ify it in the process. --- .gitignore | 4 +- Cargo.toml | 10 +++ epoll.rs | 255 +++++++++++++++++++++++-------------------------------------- 3 files changed, 109 insertions(+), 160 deletions(-) create mode 100644 Cargo.toml diff --git a/.gitignore b/.gitignore index 4efbeea..1e7caa9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -/epoll -/*.so +Cargo.lock +target/ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..52de5be --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] + +name = "epoll" +version = "0.0.2" +authors = ["Ben Noordhuis "] + +[lib] + +name = "epoll" +path = "epoll.rs" diff --git a/epoll.rs b/epoll.rs index 36cfcc0..b7279b4 100644 --- a/epoll.rs +++ b/epoll.rs @@ -1,169 +1,108 @@ -/* - * Copyright (c) 2012, Ben Noordhuis - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#[license = "ISC"]; - -#[link(name = "epoll", - vers = "1.0", - author = "Ben Noordhuis ")]; - -//export EPOLL_NONBLOCK; -export EPOLL_CLOEXEC; -export EPOLL_CTL_ADD; -export EPOLL_CTL_DEL; -export EPOLLIN; -export EPOLLPRI; -export EPOLLOUT; -export EPOLLERR; -export EPOLLHUP; -export EPOLLONESHOT; -export EPOLLET; -export epoll_event; -export epoll_create; -export epoll_create1; -export epoll_ctl; -export epoll_wait; - -use std; // required by the tests - -import c_int = libc::c_int; - -//const EPOLL_NONBLOCK: int = 0x800; -const EPOLL_CLOEXEC: int = 0x80000; - -const EPOLL_CTL_ADD: int = 1; -const EPOLL_CTL_DEL: int = 2; -const EPOLL_CTL_MOD: int = 3; - -const EPOLLIN: i32 = 0x01i32; -const EPOLLPRI: i32 = 0x02i32; -const EPOLLOUT: i32 = 0x04i32; -const EPOLLERR: i32 = 0x08i32; -const EPOLLHUP: i32 = 0x10i32; -const EPOLLONESHOT: i32 = 0x40000000i32; -const EPOLLET: i32 = 0x80000000i32; - -type epoll_event = { - events: i32, +// Copyright (c) 2012, Ben Noordhuis +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#![license = "ISC"] + +#![link(name = "epoll", + vers = "0.0.2", + author = "Ben Noordhuis ")] + +//pub const EPOLL_NONBLOCK: u32 = 0x800; +pub const EPOLL_CLOEXEC: u32 = 0x80000; + +pub const EPOLL_CTL_ADD: u32 = 1; +pub const EPOLL_CTL_DEL: u32 = 2; +pub const EPOLL_CTL_MOD: u32 = 3; + +pub const EPOLLIN: u32 = 0x01; +pub const EPOLLPRI: u32 = 0x02; +pub const EPOLLOUT: u32 = 0x04; +pub const EPOLLERR: u32 = 0x08; +pub const EPOLLHUP: u32 = 0x10; +pub const EPOLLONESHOT: u32 = 0x40000000; +pub const EPOLLET: u32 = 0x80000000; + +#[cfg(target_arch = "x86_64")] +#[repr(C, packed)] +pub struct epoll_event { + events: u32, data: u64 -}; - -#[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: *mut 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: *mut u8, - maxevents: c_int, - timeout: c_int) -> c_int; -} - -fn epoll_create() -> int { - epoll_create1(0) } -fn epoll_create1(flags: int) -> int { - __glibc::epoll_create1(flags as c_int) as int +#[cfg(not(target_arch = "x86_64"))] +#[repr(C)] +pub struct epoll_event { + events: i32, + data: u64 } -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: [mut u8] = vec::to_mut(vec::from_elem(12u, 0u8)); +mod __glibc { + use epoll_event; - // rust as of 2012-02-06 does not support packed types, hence we have to do - // the packing and unpacking ourselves - unsafe { - let p1: *mut i32 = unsafe::reinterpret_cast(ptr::mut_addr_of(buf[0])); - let p2: *mut u64 = unsafe::reinterpret_cast(ptr::mut_addr_of(buf[4])); - *p1 = event.events; - *p2 = event.data; + extern { + pub fn epoll_create1(flags: u32) -> i32; + pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, + event: *const epoll_event) -> i32; + pub fn epoll_wait(epfd: i32, events: *mut epoll_event, maxevents: i32, + timeout: i32) -> i32; } +} - ret __glibc::epoll_ctl(epfd as c_int, - op as c_int, - fd as c_int, - ptr::addr_of(buf[0])) as int +pub fn epoll_create() -> i32 { + unsafe { __glibc::epoll_create1(0) } } -fn epoll_wait(epfd: int, events: [mut epoll_event], timeout: int) -> int { - /* - let pevents: *mut 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: [mut u8] = vec::to_mut(vec::from_elem(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; - } +pub fn epoll_create1(flags: u32) -> i32 { + unsafe { __glibc::epoll_create1(flags) } +} - // rust as of 2012-02-06 does not support packed types, hence we have to do - // the packing and unpacking ourselves - let mut 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; - } +pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, + event: &epoll_event) -> i32 { + unsafe { __glibc::epoll_ctl(epfd, op, fd, event) } +} - ret nevents; +pub fn epoll_wait(epfd: i32, events: &mut [epoll_event], + timeout: i32) -> i32 { + unsafe { __glibc::epoll_wait(epfd, events.as_mut_slice().as_mut_ptr(), + events.len() as i32, timeout) } } #[test] fn test_epoll_create1() { - assert epoll_create1(0) >= 0; - assert epoll_create1(EPOLL_CLOEXEC) >= 0; - assert epoll_create1(-1) == -1; + assert!(epoll_create1(0) >= 0); + assert!(epoll_create1(EPOLL_CLOEXEC) >= 0); + assert!(epoll_create1(-1) == -1); } #[test] fn test_epoll_ctl() { let epfd = epoll_create1(0); - assert epfd >= 0; - - assert epoll_ctl(epfd, EPOLL_CTL_ADD, 0, {events:EPOLLIN, data:0u64}) == 0; - assert epoll_ctl(epfd, EPOLL_CTL_ADD, 0, {events:EPOLLIN, data:0u64}) == -1; - assert epoll_ctl(epfd, EPOLL_CTL_MOD, 0, {events:EPOLLOUT, data:0u64}) == 0; - assert epoll_ctl(epfd, EPOLL_CTL_DEL, 0, {events:EPOLLIN, data:0u64}) == 0; - - assert epoll_ctl(epfd, EPOLL_CTL_ADD, -1, {events:EPOLLIN, data:0u64}) == -1; - assert epoll_ctl(epfd, EPOLL_CTL_MOD, -1, {events:EPOLLIN, data:0u64}) == -1; - assert epoll_ctl(epfd, EPOLL_CTL_DEL, -1, {events:EPOLLIN, data:0u64}) == -1; + assert!(epfd >= 0); + assert!(epoll_ctl(epfd, EPOLL_CTL_ADD, 0, + &epoll_event { events: EPOLLIN, data: 0 }) == 0); + assert!(epoll_ctl(epfd, EPOLL_CTL_ADD, 0, + &epoll_event { events: EPOLLIN, data: 0}) == -1); + assert!(epoll_ctl(epfd, EPOLL_CTL_MOD, 0, + &epoll_event { events: EPOLLOUT, data: 0}) == 0); + assert!(epoll_ctl(epfd, EPOLL_CTL_DEL, 0, + &epoll_event { events: EPOLLIN, data: 0}) == 0); + assert!(epoll_ctl(epfd, EPOLL_CTL_ADD, -1, + &epoll_event { events: EPOLLIN, data: 0}) == -1); + assert!(epoll_ctl(epfd, EPOLL_CTL_MOD, -1, + &epoll_event { events: EPOLLIN, data: 0}) == -1); + assert!(epoll_ctl(epfd, EPOLL_CTL_DEL, -1, + &epoll_event { events: EPOLLIN, data: 0}) == -1); } #[test] @@ -171,17 +110,17 @@ fn test_epoll_wait() { // add stdout to epoll set and wait for it to become writable // should be immediate, it's an error if we hit the 50 ms timeout let epfd = epoll_create1(0); - assert epfd >= 0; - - let magic = 42u64; - assert epoll_ctl(epfd, EPOLL_CTL_ADD, 1, {events:EPOLLOUT, data:magic}) == 0; - assert epoll_ctl(epfd, EPOLL_CTL_ADD, 2, {events:EPOLLOUT, data:magic}) == 0; - - let events: [mut epoll_event] = [ - mut {events:0i32, data:0u64}, {events:0i32, data:0u64}]; - - let n = epoll_wait(epfd, events, 50); - assert n == 2; - assert events[0].data == magic; - assert events[0].events & EPOLLOUT == EPOLLOUT; + assert!(epfd >= 0); + + let magic = 42; + let event = epoll_event { events: EPOLLOUT, data: magic }; + assert!(epoll_ctl(epfd, EPOLL_CTL_ADD, 1, &event) == 0); + assert!(epoll_ctl(epfd, EPOLL_CTL_ADD, 2, &event) == 0); + + let mut events = [epoll_event {events: 0, data: 0}, + epoll_event {events: 0, data: 0}]; + let n = epoll_wait(epfd, &mut events, 50); + assert!(n == 2); + assert!(events[0].data == magic); + assert!(events[0].events & EPOLLOUT == EPOLLOUT); } -- cgit v1.2.3