summaryrefslogtreecommitdiffstats
path: root/tokio/src/signal/unix/driver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/signal/unix/driver.rs')
-rw-r--r--tokio/src/signal/unix/driver.rs43
1 files changed, 28 insertions, 15 deletions
diff --git a/tokio/src/signal/unix/driver.rs b/tokio/src/signal/unix/driver.rs
index 0458893c..639a483e 100644
--- a/tokio/src/signal/unix/driver.rs
+++ b/tokio/src/signal/unix/driver.rs
@@ -1,13 +1,15 @@
//! Signal driver
use crate::io::driver::Driver as IoDriver;
-use crate::io::Registration;
+use crate::io::PollEvented;
use crate::park::Park;
use crate::runtime::context;
use crate::signal::registry::globals;
use mio_uds::UnixStream;
use std::io::{self, Read};
+use std::ptr;
use std::sync::{Arc, Weak};
+use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
use std::time::Duration;
/// Responsible for registering wakeups when an OS signal is received, and
@@ -21,11 +23,7 @@ pub(crate) struct Driver {
park: IoDriver,
/// A pipe for receiving wake events from the signal handler
- receiver: UnixStream,
-
- /// The actual registraiton for `receiver` when active.
- /// Lazily bound at the first signal registration.
- registration: Registration,
+ receiver: PollEvented<UnixStream>,
/// Shared state
inner: Arc<Inner>,
@@ -58,13 +56,12 @@ impl Driver {
// either, since we can't compare Handles or assume they will always
// point to the exact same reactor.
let receiver = globals().receiver.try_clone()?;
- let registration =
- Registration::new_with_ready_and_handle(&receiver, mio::Ready::all(), park.handle())?;
+ let receiver =
+ PollEvented::new_with_ready_and_handle(receiver, mio::Ready::all(), park.handle())?;
Ok(Self {
park,
receiver,
- registration,
inner: Arc::new(Inner(())),
})
}
@@ -79,17 +76,23 @@ impl Driver {
fn process(&self) {
// Check if the pipe is ready to read and therefore has "woken" us up
- match self.registration.take_read_ready() {
- Ok(Some(ready)) => assert!(ready.is_readable()),
- Ok(None) => return, // No wake has arrived, bail
- Err(e) => panic!("reactor gone: {}", e),
- }
+ //
+ // To do so, we will `poll_read_ready` with a noop waker, since we don't
+ // need to actually be notified when read ready...
+ let waker = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE)) };
+ let mut cx = Context::from_waker(&waker);
+
+ let ev = match self.receiver.poll_read_ready(&mut cx) {
+ Poll::Ready(Ok(ev)) => ev,
+ Poll::Ready(Err(e)) => panic!("reactor gone: {}", e),
+ Poll::Pending => return, // No wake has arrived, bail
+ };
// Drain the pipe completely so we can receive a new readiness event
// if another signal has come in.
let mut buf = [0; 128];
loop {
- match (&self.receiver).read(&mut buf) {
+ match self.receiver.get_ref().read(&mut buf) {
Ok(0) => panic!("EOF on self-pipe"),
Ok(_) => continue, // Keep reading
Err(e) if e.kind() == io::ErrorKind::WouldBlock => break,
@@ -97,11 +100,21 @@ impl Driver {
}
}
+ self.receiver.clear_readiness(ev);
+
// Broadcast any signals which were received
globals().broadcast();
}
}
+const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
+
+unsafe fn noop_clone(_data: *const ()) -> RawWaker {
+ RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE)
+}
+
+unsafe fn noop(_data: *const ()) {}
+
// ===== impl Park for Driver =====
impl Park for Driver {