-
Notifications
You must be signed in to change notification settings - Fork 681
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combing Epoll and Inotify? #1998
Comments
Note: This is probably related to issue #1750 and may be an oversight in how to combine things. |
I think you're asking for a way to use |
I would want to use I have this workaround for now (horrible mess, and probably not sound, but it works): // Workaround for missing AsFd for Inotify in nix!
//
// There is no way to get the FD out of inotify and into epoll. We have to stupidly resort to unsafe code.
//
// This is based on Inotify::init
//
// SAFETY: Well, it actully isn't unsafe, since we aren't doing silly things like mmaping
// this etc. It won't lead to memory issues.
// HOWEVER: The IO safety is wrong, we are creating two copies of the same FD.
// This can only be fixed in nix itself. But the way we use it below is okay.
unsafe fn create_inotify<'a>(
flags: InitFlags,
) -> Result<(Inotify, BorrowedFd<'a>), Box<dyn Error>> {
let fd = Errno::result(unsafe { libc::inotify_init1(flags.bits()) })?;
Ok(unsafe { (Inotify::from_raw_fd(fd), BorrowedFd::borrow_raw(fd)) })
}
// [Lots of code elided here.]
pub(crate) fn monitor(
mut listeners: Vec<Box<dyn Listener>>,
timeout: Duration,
) -> Result<(), Box<dyn Error>> {
// SAFETY: Epoll and inotify lives equally long. This is safe.
let (inotify, ifd) = unsafe { create_inotify(InitFlags::IN_CLOEXEC | InitFlags::IN_NONBLOCK)? };
let epoll = Epoll::new(EpollCreateFlags::EPOLL_CLOEXEC)?;
epoll.add(
ifd,
EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, INOTIFY_HANDLE),
)?;
// [Add other things to epoll here]
// [Also add things to inotify]
loop {
let mut events = [EpollEvent::empty(); 32];
epoll.wait(&mut events, timeout.as_millis() as isize)?;
// Process events
for ref event in events {
match event.data() {
INOTIFY_HANDLE => {
for ievent in inotify.read_events()? {
// [Process inotify stuff here]
}
}
// [Process other file descriptors here]
}
}
}
} |
The way to fix this would be to add EDIT: Oh and that lifetime on |
Side note: I find it weird that the Also the docs for |
This is incorrect, in general. If the fd is used after it has been close, the same fd number may be reallocated to something else, which may be mmaped. So it could in principle cause soundness issues in combination with other code that is correctly using mmap. Though I don't believe it's normal to
|
I think |
So apparently the crate is transitioning
Epoll
to a new safer (and better documented!) abstraction. But this has yet to be released. Fine I thought, since I'm starting a new project, I will just use the latest master for now and switch to the next release that contains this.However, it seems that
Inotify
(which I also need) has lostAsRawFd
, but not gained a replacement to allow it to be used together withEpoll
? For my use case I need to epoll a few FDs, one of which is an inotify FD (that monitors a few files). Thus I need a way to combine these. I would prefer to avoid threads for this.Is there no way to do this currently or am I missing something obvious?
The text was updated successfully, but these errors were encountered: