Skip to content

Commit

Permalink
Fix NetBSD build failure due to kevent type difference (tokio-rs#621)
Browse files Browse the repository at this point in the history
* Add NetBSD to the CI run

* Adapt to kevent type difference on NetBSD

* In struct kevent,
  filter is uint32_t on NetBSD, while short on other platforms.
  And udata is intptr_t on NetBSD, while void * on other platforms.

* In kevent() function,
  nchanges and nevents are size_t on NetBSD, while int on other
  platforms.
  • Loading branch information
iquiw authored and carllerche committed Jul 27, 2017
1 parent c4d3fc9 commit 0cab6ca
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 12 deletions.
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ matrix:
script:
- bash ci/trust/script.sh

- os: linux
env: TARGET=x86_64-unknown-netbsd DISABLE_TESTS=1
install:
- sh ci/trust/install.sh
- source ~/.cargo/env || true
script:
- bash ci/trust/script.sh

env:
global:
- CRATE_NAME=mio
Expand Down
45 changes: 33 additions & 12 deletions src/sys/unix/kqueue.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{cmp, fmt, ptr};
use std::os::raw::c_int;
#[cfg(not(target_os = "netbsd"))]
use std::os::raw::{c_int, c_short};
use std::os::unix::io::AsRawFd;
use std::os::unix::io::RawFd;
use std::collections::HashMap;
Expand All @@ -20,15 +21,29 @@ use sys::unix::io::set_cloexec;
/// operation will return with an error. This matches windows behavior.
static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

#[cfg(not(target_os = "netbsd"))]
type Filter = c_short;
#[cfg(not(target_os = "netbsd"))]
type UData = *mut ::libc::c_void;
#[cfg(not(target_os = "netbsd"))]
type Count = c_int;

#[cfg(target_os = "netbsd")]
type Filter = u32;
#[cfg(target_os = "netbsd")]
type UData = ::libc::intptr_t;
#[cfg(target_os = "netbsd")]
type Count = usize;

macro_rules! kevent {
($id: expr, $filter: expr, $flags: expr, $data: expr) => {
libc::kevent {
ident: $id as ::libc::uintptr_t,
filter: $filter,
filter: $filter as Filter,
flags: $flags,
fflags: 0,
data: 0,
udata: $data as *mut _,
udata: $data as UData,
}
}
}
Expand Down Expand Up @@ -70,7 +85,7 @@ impl Selector {
0,
evts.sys_events.0.as_mut_ptr(),
// FIXME: needs a saturating cast here.
evts.sys_events.0.capacity() as c_int,
evts.sys_events.0.capacity() as Count,
timeout)));
evts.sys_events.0.set_len(cnt as usize);
Ok(evts.coalesce(awakener))
Expand All @@ -91,8 +106,8 @@ impl Selector {
kevent!(fd, libc::EVFILT_READ, flags | r, usize::from(token)),
kevent!(fd, libc::EVFILT_WRITE, flags | w, usize::from(token)),
];
try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
changes.as_mut_ptr(), changes.len() as c_int,
try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as Count,
changes.as_mut_ptr(), changes.len() as Count,
::std::ptr::null())));
for change in changes.iter() {
debug_assert_eq!(change.flags & libc::EV_ERROR, libc::EV_ERROR);
Expand All @@ -116,12 +131,12 @@ impl Selector {
//
// More info can be found at carllerche/mio#582
if change.data as i32 == libc::EPIPE &&
change.filter == libc::EVFILT_WRITE {
change.filter == libc::EVFILT_WRITE as Filter {
continue
}

// ignore ENOENT error for EV_DELETE
let orig_flags = if change.filter == libc::EVFILT_READ { r } else { w };
let orig_flags = if change.filter == libc::EVFILT_READ as Filter { r } else { w };
if change.data as i32 == libc::ENOENT && orig_flags & libc::EV_DELETE != 0 {
continue
}
Expand All @@ -143,12 +158,18 @@ impl Selector {
// EV_RECEIPT is a nice way to apply changes and get back per-event results while not
// draining the actual changes.
let filter = libc::EV_DELETE | libc::EV_RECEIPT;
#[cfg(not(target_os = "netbsd"))]
let mut changes = [
kevent!(fd, libc::EVFILT_READ, filter, ptr::null_mut()),
kevent!(fd, libc::EVFILT_WRITE, filter, ptr::null_mut()),
];
try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
changes.as_mut_ptr(), changes.len() as c_int,
#[cfg(target_os = "netbsd")]
let mut changes = [
kevent!(fd, libc::EVFILT_READ, filter, 0),
kevent!(fd, libc::EVFILT_WRITE, filter, 0),
];
try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as Count,
changes.as_mut_ptr(), changes.len() as Count,
::std::ptr::null())).map(|_| ()));
if changes[0].data as i32 == libc::ENOENT && changes[1].data as i32 == libc::ENOENT {
return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
Expand Down Expand Up @@ -255,9 +276,9 @@ impl Events {
event::kind_mut(&mut self.events[idx]).insert(*UnixReady::error());
}

if e.filter == libc::EVFILT_READ {
if e.filter == libc::EVFILT_READ as Filter {
event::kind_mut(&mut self.events[idx]).insert(Ready::readable());
} else if e.filter == libc::EVFILT_WRITE {
} else if e.filter == libc::EVFILT_WRITE as Filter {
event::kind_mut(&mut self.events[idx]).insert(Ready::writable());
}
#[cfg(any(target_os = "dragonfly",
Expand Down

0 comments on commit 0cab6ca

Please sign in to comment.