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:
		@ -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
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user