Created
October 19, 2014 12:21
-
-
Save manuels/aaaf1ef5d8a072c19f11 to your computer and use it in GitHub Desktop.
Rust Compiler Error for callbacks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate libc; | |
extern crate native; | |
use libc::{c_short, c_int}; | |
mod linux { | |
use native::io::file::FileDesc; | |
use libc::c_int; | |
pub fn socketpair(domain: int, type_: int, protocol: int) -> Result<(FileDesc, FileDesc), int> { | |
unsafe { | |
let sv: [c_int, ..2] = [0, 0]; | |
let res = internal::socketpair(domain as c_int, type_ as c_int, protocol as c_int, sv.as_ptr()); | |
if res == 0 { | |
assert!(sv[0] >= 0); | |
assert!(sv[1] >= 0); | |
let SOCK_CLOEXEC = 02000000; | |
let close_on_exec = (type_ & SOCK_CLOEXEC) > 0; | |
let left = FileDesc::new(sv[0], close_on_exec); | |
let right = FileDesc::new(sv[1], close_on_exec); | |
let pair = (left, right); | |
return Ok(pair) | |
} else { | |
return Err(res as int) | |
} | |
} | |
} | |
mod internal { | |
use native::io::file::fd_t; | |
use libc::c_int; | |
extern { | |
pub fn socketpair(domain: c_int, type_: c_int, protocol: c_int, sv: *const fd_t) -> c_int; | |
} | |
} | |
} | |
mod libevent { | |
use native::io::file::{FileDesc, fd_t}; | |
use libc::{c_short, c_int}; | |
use std::ptr::null; | |
pub struct Base { | |
ptr: *const c_int, | |
} | |
impl Base { | |
pub fn new() -> Base { | |
unsafe { | |
let ptr = event_init(); | |
assert!(!ptr.is_null()); | |
return Base { | |
ptr: ptr, | |
} | |
} | |
} | |
pub fn dispatch(&self) -> int { | |
unsafe { | |
return event_base_dispatch(self.ptr) as int | |
} | |
} | |
extern "C" | |
fn c_watch_fd_callback(ev:*const c_int, type_:c_short, cb: watch_fd_callback_t) { | |
cb(ev, type_) | |
} | |
pub fn watch_fd(&self, fd: FileDesc, cb: watch_fd_callback_t) { | |
unsafe { | |
let EV_READ:c_short = 0x02; | |
let ev = event_new(self.ptr, fd.fd(), EV_READ, Base::c_watch_fd_callback, cb); | |
assert!(!ev.is_null()); | |
let res = event_add(ev, null()); | |
assert!(res == 0); | |
} | |
} | |
} | |
impl Drop for Base { | |
fn drop(&mut self) { | |
unsafe { | |
event_base_free(self.ptr) | |
} | |
} | |
} | |
type watch_fd_callback_t = fn(*const c_int, c_short); | |
type c_watch_fd_callback_t = extern fn(*const c_int, c_short, watch_fd_callback_t); | |
#[link(name="event")] | |
extern { | |
fn event_init() -> *const c_int; | |
fn event_base_dispatch(ptr: *const c_int) -> c_int; | |
fn event_base_loop(ptr: *const c_int, flags: c_int) -> c_int; | |
fn event_base_free(ptr: *const c_int); | |
fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: c_watch_fd_callback_t, args: watch_fd_callback_t) -> *const c_int; | |
fn event_add(ev: *const c_int, timeout: *const c_int) -> c_int; | |
} | |
} | |
fn printme(ev: *const c_int, flags: i16) { | |
println!("hello"); | |
} | |
fn main() { | |
use linux::socketpair; | |
use libc::consts::os::bsd44::{AF_UNIX, SOCK_DGRAM}; | |
let AF_UNSPEC = 0 as int; | |
let domain = AF_UNIX as int; | |
let type_ = SOCK_DGRAM as int; | |
let protocol = AF_UNSPEC as int; | |
let (mut fd1, fd2) = socketpair(domain, type_, protocol).ok().expect("socketpair failed!"); | |
println!("{}, {}", fd1.fd(), fd2.fd()); | |
spawn(proc() { | |
let ev = libevent::Base::new(); | |
ev.watch_fd(fd2, printme); | |
println!("waiting..."); | |
ev.dispatch(); | |
println!("waiting done"); | |
}); | |
let buf:[u8, ..1] = [0]; | |
match fd1.inner_write(buf) { | |
Err(x) => { println!("write() err: {}", x.detail.expect("Unknown error")) }, | |
_ => {}, | |
} | |
println!("wrote!"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70c70,75 | |
< pub fn watch_fd(&self, fd: FileDesc, cb: extern fn(*const c_int, c_short, *const c_int)) { | |
--- | |
> extern "C" | |
> fn c_watch_fd_callback(ev:*const c_int, type_:c_short, cb: watch_fd_callback_t) { | |
> cb(ev, type_) | |
> } | |
> | |
> pub fn watch_fd(&self, fd: FileDesc, cb: watch_fd_callback_t) { | |
73c78 | |
< let ev = event_new(self.ptr, fd.fd(), EV_READ, cb, null()); | |
--- | |
> let ev = event_new(self.ptr, fd.fd(), EV_READ, Base::c_watch_fd_callback, cb); | |
89a95,97 | |
> type watch_fd_callback_t = fn(*const c_int, c_short); | |
> type c_watch_fd_callback_t = extern fn(*const c_int, c_short, watch_fd_callback_t); | |
> | |
97c105 | |
< fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: extern fn(*const c_int, c_short, *const c_int), args: *const c_int) -> *const c_int; | |
--- | |
> fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: c_watch_fd_callback_t, args: watch_fd_callback_t) -> *const c_int; | |
102,103c110 | |
< extern "C" | |
< fn printme(ev: *const c_int, flags: c_short, args: *const c_int) { | |
--- | |
> fn printme(ev: *const c_int, flags: i16) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate libc; | |
extern crate native; | |
use libc::{c_short, c_int}; | |
mod linux { | |
use native::io::file::FileDesc; | |
use libc::c_int; | |
pub fn socketpair(domain: int, type_: int, protocol: int) -> Result<(FileDesc, FileDesc), int> { | |
unsafe { | |
let sv: [c_int, ..2] = [0, 0]; | |
let res = internal::socketpair(domain as c_int, type_ as c_int, protocol as c_int, sv.as_ptr()); | |
if res == 0 { | |
assert!(sv[0] >= 0); | |
assert!(sv[1] >= 0); | |
let SOCK_CLOEXEC = 02000000; | |
let close_on_exec = (type_ & SOCK_CLOEXEC) > 0; | |
let left = FileDesc::new(sv[0], close_on_exec); | |
let right = FileDesc::new(sv[1], close_on_exec); | |
let pair = (left, right); | |
return Ok(pair) | |
} else { | |
return Err(res as int) | |
} | |
} | |
} | |
mod internal { | |
use native::io::file::fd_t; | |
use libc::c_int; | |
extern { | |
pub fn socketpair(domain: c_int, type_: c_int, protocol: c_int, sv: *const fd_t) -> c_int; | |
} | |
} | |
} | |
mod libevent { | |
use native::io::file::{FileDesc, fd_t}; | |
use libc::{c_short, c_int}; | |
use std::ptr::null; | |
pub struct Base { | |
ptr: *const c_int, | |
} | |
impl Base { | |
pub fn new() -> Base { | |
unsafe { | |
let ptr = event_init(); | |
assert!(!ptr.is_null()); | |
return Base { | |
ptr: ptr, | |
} | |
} | |
} | |
pub fn dispatch(&self) -> int { | |
unsafe { | |
return event_base_dispatch(self.ptr) as int | |
} | |
} | |
pub fn watch_fd(&self, fd: FileDesc, cb: extern fn(*const c_int, c_short, *const c_int)) { | |
unsafe { | |
let EV_READ:c_short = 0x02; | |
let ev = event_new(self.ptr, fd.fd(), EV_READ, cb, null()); | |
assert!(!ev.is_null()); | |
let res = event_add(ev, null()); | |
assert!(res == 0); | |
} | |
} | |
} | |
impl Drop for Base { | |
fn drop(&mut self) { | |
unsafe { | |
event_base_free(self.ptr) | |
} | |
} | |
} | |
#[link(name="event")] | |
extern { | |
fn event_init() -> *const c_int; | |
fn event_base_dispatch(ptr: *const c_int) -> c_int; | |
fn event_base_loop(ptr: *const c_int, flags: c_int) -> c_int; | |
fn event_base_free(ptr: *const c_int); | |
fn event_new(base: *const c_int, fd: fd_t, events: c_short, cb: extern fn(*const c_int, c_short, *const c_int), args: *const c_int) -> *const c_int; | |
fn event_add(ev: *const c_int, timeout: *const c_int) -> c_int; | |
} | |
} | |
extern "C" | |
fn printme(ev: *const c_int, flags: c_short, args: *const c_int) { | |
println!("hello"); | |
} | |
fn main() { | |
use linux::socketpair; | |
use libc::consts::os::bsd44::{AF_UNIX, SOCK_DGRAM}; | |
let AF_UNSPEC = 0 as int; | |
let domain = AF_UNIX as int; | |
let type_ = SOCK_DGRAM as int; | |
let protocol = AF_UNSPEC as int; | |
let (mut fd1, fd2) = socketpair(domain, type_, protocol).ok().expect("socketpair failed!"); | |
println!("{}, {}", fd1.fd(), fd2.fd()); | |
spawn(proc() { | |
let ev = libevent::Base::new(); | |
ev.watch_fd(fd2, printme); | |
println!("waiting..."); | |
ev.dispatch(); | |
println!("waiting done"); | |
}); | |
let buf:[u8, ..1] = [0]; | |
match fd1.inner_write(buf) { | |
Err(x) => { println!("write() err: {}", x.detail.expect("Unknown error")) }, | |
_ => {}, | |
} | |
println!("wrote!"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment