signalfd cleanup
- add comment about the boxed file descriptor (and others) - reexport SigSet and Signal for convenience - remove Result wrapper (only used once) - enforce drop order of the PollEvented2 struct with respect to the boxed fd Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
b6b012e3c0
commit
4ba7b6099c
@ -1,18 +1,19 @@
|
|||||||
//! signalfd handling for tokio
|
//! signalfd handling for tokio, with some re-exports for convenience
|
||||||
|
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
|
|
||||||
use failure::*;
|
use failure::*;
|
||||||
use nix::sys::signalfd::{self, SigSet};
|
use nix::sys::signalfd;
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
use tokio::reactor::PollEvented2;
|
use tokio::reactor::PollEvented2;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
pub use nix::sys::signal::{SigSet, Signal};
|
||||||
|
|
||||||
|
/// Wrapper for `nix::sys::signal::SignalFd` to provide an async `Stream` of `siginfo`.
|
||||||
pub struct SignalFd {
|
pub struct SignalFd {
|
||||||
inner: signalfd::SignalFd,
|
inner: signalfd::SignalFd,
|
||||||
pinned_fd: Box<RawFd>,
|
pinned_fd: Box<RawFd>,
|
||||||
wakeup: PollEvented2<mio::unix::EventedFd<'static>>,
|
wakeup: Option<PollEvented2<mio::unix::EventedFd<'static>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for SignalFd {
|
impl std::ops::Deref for SignalFd {
|
||||||
@ -30,20 +31,23 @@ impl std::ops::DerefMut for SignalFd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SignalFd {
|
impl SignalFd {
|
||||||
pub fn new(mask: &SigSet) -> Result<Self> {
|
pub fn new(mask: &SigSet) -> Result<Self, Error> {
|
||||||
let inner = signalfd::SignalFd::with_flags(
|
let inner = signalfd::SignalFd::with_flags(
|
||||||
mask,
|
mask,
|
||||||
signalfd::SfdFlags::SFD_CLOEXEC | signalfd::SfdFlags::SFD_NONBLOCK,
|
signalfd::SfdFlags::SFD_CLOEXEC | signalfd::SfdFlags::SFD_NONBLOCK,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// box the signalfd's Rawfd, turn it into a raw pointer and create a &'static reference so
|
// EventedFd takes a reference and therefore a lifetime parameter. Since we want to
|
||||||
// we can store it inthe SignalFd struct...
|
// reference something that is part of our own Self, we need to find a work around:
|
||||||
|
// Pin the file descriptor in memory by boxing it and fake a &'static lifetime.
|
||||||
|
//
|
||||||
|
// Note that we must not provide access to this lifetime to the outside!
|
||||||
let pinned_fd = Box::new(inner.as_raw_fd());
|
let pinned_fd = Box::new(inner.as_raw_fd());
|
||||||
let fd_ptr: *const RawFd = &*pinned_fd;
|
let fd_ptr: *const RawFd = &*pinned_fd;
|
||||||
let static_fd: &'static RawFd = unsafe { &*fd_ptr };
|
let static_fd: &'static RawFd = unsafe { &*fd_ptr };
|
||||||
let evented = mio::unix::EventedFd(static_fd);
|
let evented = mio::unix::EventedFd(static_fd);
|
||||||
|
|
||||||
let wakeup = PollEvented2::new(evented);
|
let wakeup = Some(PollEvented2::new(evented));
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner,
|
inner,
|
||||||
@ -60,7 +64,7 @@ impl Stream for SignalFd {
|
|||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
let ready = mio::Ready::readable();
|
let ready = mio::Ready::readable();
|
||||||
|
|
||||||
match self.wakeup.poll_read_ready(ready) {
|
match self.wakeup.as_mut().unwrap().poll_read_ready(ready) {
|
||||||
Ok(Async::Ready(_)) => (), // go on
|
Ok(Async::Ready(_)) => (), // go on
|
||||||
Ok(Async::NotReady) => return Ok(Async::NotReady),
|
Ok(Async::NotReady) => return Ok(Async::NotReady),
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
@ -69,7 +73,7 @@ impl Stream for SignalFd {
|
|||||||
match self.inner.read_signal() {
|
match self.inner.read_signal() {
|
||||||
Ok(Some(signal)) => Ok(Async::Ready(Some(signal))),
|
Ok(Some(signal)) => Ok(Async::Ready(Some(signal))),
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
self.wakeup.clear_read_ready(ready)?;
|
self.wakeup.as_mut().unwrap().clear_read_ready(ready)?;
|
||||||
Ok(Async::NotReady)
|
Ok(Async::NotReady)
|
||||||
}
|
}
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
@ -82,3 +86,9 @@ impl AsRawFd for SignalFd {
|
|||||||
*self.pinned_fd
|
*self.pinned_fd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for SignalFd {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.wakeup = None; // enforce drop order
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user