Skip to content

Commit a7f48fd

Browse files
committed
waker: use popol::Waker type directly
1 parent 97a379f commit a7f48fd

File tree

1 file changed

+30
-57
lines changed

1 file changed

+30
-57
lines changed

src/poller/popol.rs

+30-57
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@
2424
//! Poll engine provided by the [`popol`] crate.
2525
2626
use std::collections::VecDeque;
27-
use std::io;
28-
use std::io::{Error, Write};
27+
use std::io::{self, Error};
2928
use std::os::unix::io::{AsRawFd, RawFd};
30-
use std::os::unix::net::UnixStream;
3129
use std::sync::Arc;
3230
use std::time::Duration;
3331

@@ -64,7 +62,7 @@ impl Poller {
6462
}
6563

6664
impl Poll for Poller {
67-
type Waker = UnixStream;
65+
type Waker = PopolWaker;
6866

6967
fn register(&mut self, fd: &impl AsRawFd, interest: IoType) {
7068
#[cfg(feature = "log")]
@@ -162,68 +160,43 @@ impl From<IoType> for popol::Interest {
162160
}
163161
}
164162

165-
impl Waker for UnixStream {
166-
type Send = Arc<UnixStream>;
167-
type Recv = UnixStream;
163+
/// Wrapper type around the waker provided by `popol` crate.
164+
#[derive(Clone)]
165+
pub struct PopolWaker(Arc<popol::Waker>);
166+
167+
impl Waker for PopolWaker {
168+
type Send = Self;
169+
type Recv = Self;
168170

169171
fn pair() -> Result<(Self::Send, Self::Recv), Error> {
170-
let (waker_writer, waker_reader) = UnixStream::pair()?;
171-
waker_reader.set_nonblocking(true)?;
172-
waker_writer.set_nonblocking(true)?;
173-
Ok((Arc::new(waker_writer), waker_reader))
172+
let waker = Arc::new(popol::Waker::new()?);
173+
Ok((PopolWaker(waker.clone()), PopolWaker(waker)))
174174
}
175175
}
176176

177-
impl WakerRecv for UnixStream {
178-
fn reset(&self) { reset_fd(self).expect("waker failure"); }
177+
impl io::Read for PopolWaker {
178+
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
179+
self.reset();
180+
// Waker reads only when there is something which was sent.
181+
// That's why we just return here.
182+
Ok(0)
183+
}
179184
}
180185

181-
impl WakerSend for Arc<UnixStream> {
182-
fn wake(&self) -> io::Result<()> {
183-
loop {
184-
let mut waker = self.as_ref();
185-
match (&mut waker).write_all(&[0x1]) {
186-
Ok(_) => return Ok(()),
187-
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
188-
#[cfg(feature = "log")]
189-
log::error!(target: "reactor-controller", "Waker write queue got overfilled, resetting and repeating...");
190-
reset_fd(&self.as_raw_fd())?;
191-
}
192-
Err(e) if e.kind() == io::ErrorKind::Interrupted => {
193-
#[cfg(feature = "log")]
194-
log::error!(target: "reactor-controller", "Waker failure, repeating...");
195-
}
196-
Err(e) => {
197-
#[cfg(feature = "log")]
198-
log::error!(target: "reactor-controller", "Waker error: {e}");
199-
200-
return Err(e);
201-
}
202-
}
203-
}
204-
}
186+
impl AsRawFd for PopolWaker {
187+
fn as_raw_fd(&self) -> RawFd { self.0.as_ref().as_raw_fd() }
205188
}
206189

207-
fn reset_fd(fd: &impl AsRawFd) -> io::Result<()> {
208-
let mut buf = [0u8; 4096];
209-
210-
loop {
211-
// We use a low-level "read" here because the alternative is to create a `UnixStream`
212-
// from the `RawFd`, which has "drop" semantics which we want to avoid.
213-
match unsafe {
214-
libc::read(fd.as_raw_fd(), buf.as_mut_ptr() as *mut libc::c_void, buf.len())
215-
} {
216-
-1 => match io::Error::last_os_error() {
217-
e if e.kind() == io::ErrorKind::WouldBlock => return Ok(()),
218-
e => {
219-
#[cfg(feature = "log")]
220-
log::error!(target: "reactor-controller", "Unable to reset waker queue: {e}");
221-
222-
return Err(e);
223-
}
224-
},
225-
0 => return Ok(()),
226-
_ => continue,
190+
impl WakerRecv for PopolWaker {
191+
fn reset(&self) {
192+
if let Err(e) = popol::Waker::reset(self.0.as_ref()) {
193+
#[cfg(feature = "log")]
194+
log::error!(target: "reactor-controller", "Unable to reset waker queue: {e}");
195+
panic!("unable to reset waker queue. Details: {e}");
227196
}
228197
}
229198
}
199+
200+
impl WakerSend for PopolWaker {
201+
fn wake(&self) -> io::Result<()> { self.0.wake() }
202+
}

0 commit comments

Comments
 (0)