Mio 0.7.0 update (#435)
This commit is contained in:
parent
dfafcc09ac
commit
c5fc1a1493
@ -1,6 +1,7 @@
|
||||
# Version 0.17.5
|
||||
- Improved support of keymodifier for linux, arrow keys, function keys, home keys etc.
|
||||
- Add `SetTitle` command to change the terminal title.
|
||||
- Mio 0.7 update
|
||||
|
||||
# Version 0.17.4
|
||||
- Add macros for `Colorize` and `Styler` impls, add an impl for `String`
|
||||
|
@ -54,8 +54,8 @@ crossterm_winapi = "0.6.1"
|
||||
#
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
mio = "0.6"
|
||||
signal-hook = { version = "0.1.15", features = ["mio-support"] }
|
||||
mio = {version="0.7", features=["os-poll"]}
|
||||
signal-hook = { version = "0.1.15", features = ["mio-0_7-support"] }
|
||||
|
||||
#
|
||||
# Dev dependencies (examples, ...)
|
||||
|
@ -1,8 +1,8 @@
|
||||
use mio::{unix::EventedFd, Events, Poll, PollOpt, Ready, Token};
|
||||
use mio::{unix::SourceFd, Events, Interest, Poll, Token};
|
||||
use signal_hook::iterator::Signals;
|
||||
use std::{collections::VecDeque, time::Duration};
|
||||
use std::{collections::VecDeque, io, time::Duration};
|
||||
|
||||
use crate::Result;
|
||||
use crate::{ErrorKind, Result};
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
use super::super::sys::Waker;
|
||||
@ -45,34 +45,17 @@ impl UnixInternalEventSource {
|
||||
|
||||
pub(crate) fn from_file_descriptor(input_fd: FileDesc) -> Result<Self> {
|
||||
let poll = Poll::new()?;
|
||||
let mut registry = poll.registry();
|
||||
|
||||
// PollOpt::level vs PollOpt::edge mio documentation:
|
||||
//
|
||||
// > With edge-triggered events, operations must be performed on the Evented type until
|
||||
// > WouldBlock is returned.
|
||||
//
|
||||
// TL;DR - DO NOT use PollOpt::edge.
|
||||
//
|
||||
// Because of the `try_read` nature (loop with returns) we can't use `PollOpt::edge`. All
|
||||
// `Evented` handles MUST be registered with the `PollOpt::level`.
|
||||
//
|
||||
// If you have to use `PollOpt::edge` and there's no way how to do it with the `PollOpt::level`,
|
||||
// be aware that the whole `TtyInternalEventSource` have to be rewritten
|
||||
// (read everything from each `Evented`, process without returns, store all InternalEvent events
|
||||
// into a buffer and then return first InternalEvent, etc.). Even these changes wont be
|
||||
// enough, because `Poll::poll` wont fire again until additional `Evented` event happens and
|
||||
// we can still have a buffer filled with InternalEvent events.
|
||||
let tty_raw_fd = input_fd.raw_fd();
|
||||
let tty_ev = EventedFd(&tty_raw_fd);
|
||||
poll.register(&tty_ev, TTY_TOKEN, Ready::readable(), PollOpt::level())?;
|
||||
let mut tty_ev = SourceFd(&tty_raw_fd);
|
||||
registry.register(&mut tty_ev, TTY_TOKEN, Interest::READABLE)?;
|
||||
|
||||
let signals = Signals::new(&[signal_hook::SIGWINCH])?;
|
||||
poll.register(&signals, SIGNAL_TOKEN, Ready::readable(), PollOpt::level())?;
|
||||
let mut signals = Signals::new(&[signal_hook::SIGWINCH])?;
|
||||
registry.register(&mut signals, SIGNAL_TOKEN, Interest::READABLE)?;
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
let waker = Waker::new()?;
|
||||
#[cfg(feature = "event-stream")]
|
||||
poll.register(&waker, WAKE_TOKEN, Ready::readable(), PollOpt::level())?;
|
||||
let mut waker = Waker::new(registry, WAKE_TOKEN)?;
|
||||
|
||||
Ok(UnixInternalEventSource {
|
||||
poll,
|
||||
@ -107,20 +90,28 @@ impl EventSource for UnixInternalEventSource {
|
||||
for token in self.events.iter().map(|x| x.token()) {
|
||||
match token {
|
||||
TTY_TOKEN => {
|
||||
let read_count = self.tty_fd.read(&mut self.tty_buffer, TTY_BUFFER_SIZE)?;
|
||||
|
||||
if read_count > 0 {
|
||||
self.poll
|
||||
.poll(&mut additional_input_events, Some(Duration::from_secs(0)))?;
|
||||
|
||||
let additional_input_available = additional_input_events
|
||||
.iter()
|
||||
.any(|event| event.token() == TTY_TOKEN);
|
||||
|
||||
self.parser.advance(
|
||||
&self.tty_buffer[..read_count],
|
||||
additional_input_available,
|
||||
);
|
||||
loop {
|
||||
match self.tty_fd.read(&mut self.tty_buffer, TTY_BUFFER_SIZE) {
|
||||
Ok(read_count) => {
|
||||
if read_count > 0 {
|
||||
self.parser.advance(
|
||||
&self.tty_buffer[..read_count],
|
||||
read_count == TTY_BUFFER_SIZE,
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(ErrorKind::IoError(e)) => {
|
||||
// No more data to read at the moment. We will receive another event
|
||||
if e.kind() == io::ErrorKind::WouldBlock {
|
||||
break;
|
||||
}
|
||||
// once more data is available to read.
|
||||
else if e.kind() == io::ErrorKind::Interrupted {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
if let Some(event) = self.parser.next() {
|
||||
return Ok(Some(event));
|
||||
@ -149,7 +140,6 @@ impl EventSource for UnixInternalEventSource {
|
||||
}
|
||||
#[cfg(feature = "event-stream")]
|
||||
WAKE_TOKEN => {
|
||||
let _ = self.waker.reset();
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Interrupted,
|
||||
"Poll operation was woken up by `Waker::wake`",
|
||||
|
@ -1,101 +1,39 @@
|
||||
// TODO Replace with `mio::Waker` when the 0.7 is released (not available in 0.6).
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use mio::{Evented, Poll, PollOpt, Ready, Registration, SetReadiness, Token};
|
||||
use mio::{Registry, Token};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WakerInner {
|
||||
registration: Registration,
|
||||
set_readiness: SetReadiness,
|
||||
}
|
||||
|
||||
impl WakerInner {
|
||||
fn new() -> Self {
|
||||
let (registration, set_readiness) = Registration::new2();
|
||||
|
||||
Self {
|
||||
registration,
|
||||
set_readiness,
|
||||
}
|
||||
}
|
||||
|
||||
fn wake(&self) -> Result<()> {
|
||||
self.set_readiness.set_readiness(Ready::readable())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset(&self) -> Result<()> {
|
||||
self.set_readiness.set_readiness(Ready::empty())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
use crate::{ErrorKind, Result};
|
||||
|
||||
/// Allows to wake up the `mio::Poll::poll()` method.
|
||||
/// This type wraps `mio::Waker`, for more information see its documentation.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct Waker {
|
||||
inner: Arc<Mutex<WakerInner>>,
|
||||
inner: Arc<Mutex<mio::Waker>>,
|
||||
}
|
||||
|
||||
impl Waker {
|
||||
/// Creates a new waker.
|
||||
///
|
||||
/// `Waker` implements the `mio::Evented` trait and you have to register
|
||||
/// it in order to use it.
|
||||
pub(crate) fn new() -> Result<Self> {
|
||||
/// Create a new `Waker`.
|
||||
pub(crate) fn new(registry: &Registry, waker_token: Token) -> Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Arc::new(Mutex::new(WakerInner::new())),
|
||||
inner: Arc::new(Mutex::new(mio::Waker::new(registry, waker_token)?)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Wakes the `mio::Poll.poll()` method.
|
||||
/// Wake up the [`Poll`] associated with this `Waker`.
|
||||
///
|
||||
/// Readiness is set to `Ready::readable()`.
|
||||
pub(crate) fn wake(&self) -> Result<()> {
|
||||
self.inner.lock().unwrap().wake()
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.wake()
|
||||
.map_err(|e| ErrorKind::IoError(e))
|
||||
}
|
||||
|
||||
/// Resets the state so the same waker can be reused.
|
||||
///
|
||||
/// Readiness is set back to `Ready::empty()`.
|
||||
/// This function is not impl
|
||||
pub(crate) fn reset(&self) -> Result<()> {
|
||||
self.inner.lock().unwrap().reset()
|
||||
}
|
||||
}
|
||||
|
||||
impl Evented for Waker {
|
||||
fn register(
|
||||
&self,
|
||||
poll: &Poll,
|
||||
token: Token,
|
||||
interest: Ready,
|
||||
opts: PollOpt,
|
||||
) -> ::std::io::Result<()> {
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.registration
|
||||
.register(poll, token, interest, opts)
|
||||
}
|
||||
|
||||
fn reregister(
|
||||
&self,
|
||||
poll: &Poll,
|
||||
token: Token,
|
||||
interest: Ready,
|
||||
opts: PollOpt,
|
||||
) -> ::std::io::Result<()> {
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.registration
|
||||
.reregister(poll, token, interest, opts)
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn deregister(&self, poll: &Poll) -> ::std::io::Result<()> {
|
||||
self.inner.lock().unwrap().registration.deregister(poll)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user