2016-09-26 02:49:44 +00:00
|
|
|
//! The main event loop which performs I/O on the pseudoterminal
|
|
|
|
use std::borrow::Cow;
|
2016-09-26 15:28:38 +00:00
|
|
|
use std::collections::VecDeque;
|
2016-11-20 00:16:20 +00:00
|
|
|
use std::fs::File;
|
2019-03-30 16:48:36 +00:00
|
|
|
use std::io::{self, ErrorKind, Read, Write};
|
2018-10-16 17:02:52 +00:00
|
|
|
use std::marker::Send;
|
2019-03-30 16:48:36 +00:00
|
|
|
use std::sync::Arc;
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2019-10-05 00:29:26 +00:00
|
|
|
use log::error;
|
2018-10-16 17:02:52 +00:00
|
|
|
#[cfg(not(windows))]
|
2017-08-30 18:43:37 +00:00
|
|
|
use mio::unix::UnixReady;
|
2019-10-05 00:29:26 +00:00
|
|
|
use mio::{self, Events, PollOpt, Ready};
|
|
|
|
use mio_extras::channel::{self, Receiver, Sender};
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2018-12-10 17:53:56 +00:00
|
|
|
use crate::ansi;
|
2019-10-09 21:37:48 +00:00
|
|
|
use crate::config::Config;
|
2019-10-05 00:29:26 +00:00
|
|
|
use crate::event::{self, Event, EventListener};
|
2019-03-30 16:48:36 +00:00
|
|
|
use crate::sync::FairMutex;
|
2018-12-10 17:53:56 +00:00
|
|
|
use crate::term::Term;
|
2019-03-30 16:48:36 +00:00
|
|
|
use crate::tty;
|
2018-12-10 17:53:56 +00:00
|
|
|
use crate::util::thread;
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2019-10-05 00:29:26 +00:00
|
|
|
/// Max bytes to read from the PTY
|
|
|
|
const MAX_READ: usize = 0x10_000;
|
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
/// Messages that may be sent to the `EventLoop`
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Msg {
|
|
|
|
/// Data that should be written to the pty
|
|
|
|
Input(Cow<'static, [u8]>),
|
2017-05-20 04:35:43 +00:00
|
|
|
|
2017-05-20 20:58:33 +00:00
|
|
|
/// Indicates that the `EventLoop` should shut down, as Alacritty is shutting down
|
2018-10-16 17:02:52 +00:00
|
|
|
Shutdown,
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// The main event!.. loop.
|
|
|
|
///
|
|
|
|
/// Handles all the pty I/O and runs the pty parser which updates terminal
|
|
|
|
/// state.
|
2019-10-05 00:29:26 +00:00
|
|
|
pub struct EventLoop<T: tty::EventedPty, U: EventListener> {
|
2016-09-26 02:49:44 +00:00
|
|
|
poll: mio::Poll,
|
2018-10-16 17:02:52 +00:00
|
|
|
pty: T,
|
2017-08-30 18:43:37 +00:00
|
|
|
rx: Receiver<Msg>,
|
|
|
|
tx: Sender<Msg>,
|
2019-10-05 00:29:26 +00:00
|
|
|
terminal: Arc<FairMutex<Term<U>>>,
|
|
|
|
event_proxy: U,
|
2019-10-09 21:37:48 +00:00
|
|
|
hold: bool,
|
2016-11-20 00:16:20 +00:00
|
|
|
ref_test: bool,
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
/// Helper type which tracks how much of a buffer has been written.
|
|
|
|
struct Writing {
|
|
|
|
source: Cow<'static, [u8]>,
|
|
|
|
written: usize,
|
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
/// All of the mutable state needed to run the event loop
|
|
|
|
///
|
|
|
|
/// Contains list of items to write, current write state, etc. Anything that
|
|
|
|
/// would otherwise be mutated on the `EventLoop` goes here.
|
|
|
|
pub struct State {
|
|
|
|
write_list: VecDeque<Cow<'static, [u8]>>,
|
|
|
|
writing: Option<Writing>,
|
|
|
|
parser: ansi::Processor,
|
|
|
|
}
|
|
|
|
|
2017-08-30 18:43:37 +00:00
|
|
|
pub struct Notifier(pub Sender<Msg>);
|
2016-12-26 23:33:27 +00:00
|
|
|
|
|
|
|
impl event::Notify for Notifier {
|
|
|
|
fn notify<B>(&mut self, bytes: B)
|
2019-03-30 16:48:36 +00:00
|
|
|
where
|
|
|
|
B: Into<Cow<'static, [u8]>>,
|
2016-12-26 23:33:27 +00:00
|
|
|
{
|
|
|
|
let bytes = bytes.into();
|
2017-05-21 16:25:08 +00:00
|
|
|
// terminal hangs if we send 0 bytes through.
|
|
|
|
if bytes.len() == 0 {
|
2019-03-30 16:48:36 +00:00
|
|
|
return;
|
2017-05-21 16:25:08 +00:00
|
|
|
}
|
2018-01-06 01:42:55 +00:00
|
|
|
if self.0.send(Msg::Input(bytes)).is_err() {
|
|
|
|
panic!("expected send event loop msg");
|
2016-12-26 23:33:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
impl Default for State {
|
|
|
|
fn default() -> State {
|
2019-03-30 16:48:36 +00:00
|
|
|
State { write_list: VecDeque::new(), parser: ansi::Processor::new(), writing: None }
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
impl State {
|
|
|
|
#[inline]
|
|
|
|
fn ensure_next(&mut self) {
|
|
|
|
if self.writing.is_none() {
|
|
|
|
self.goto_next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn goto_next(&mut self) {
|
2019-03-30 16:48:36 +00:00
|
|
|
self.writing = self.write_list.pop_front().map(Writing::new);
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn take_current(&mut self) -> Option<Writing> {
|
|
|
|
self.writing.take()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn needs_write(&self) -> bool {
|
|
|
|
self.writing.is_some() || !self.write_list.is_empty()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn set_current(&mut self, new: Option<Writing>) {
|
|
|
|
self.writing = new;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Writing {
|
|
|
|
#[inline]
|
|
|
|
fn new(c: Cow<'static, [u8]>) -> Writing {
|
|
|
|
Writing { source: c, written: 0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn advance(&mut self, n: usize) {
|
|
|
|
self.written += n;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn remaining_bytes(&self) -> &[u8] {
|
|
|
|
&self.source[self.written..]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn finished(&self) -> bool {
|
|
|
|
self.written >= self.source.len()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-05 00:29:26 +00:00
|
|
|
impl<T, U> EventLoop<T, U>
|
2019-03-30 16:48:36 +00:00
|
|
|
where
|
|
|
|
T: tty::EventedPty + Send + 'static,
|
2019-10-05 00:29:26 +00:00
|
|
|
U: EventListener + Send + 'static,
|
2016-09-26 02:49:44 +00:00
|
|
|
{
|
2016-09-26 15:28:38 +00:00
|
|
|
/// Create a new event loop
|
2019-10-09 21:37:48 +00:00
|
|
|
pub fn new<V>(
|
2019-10-05 00:29:26 +00:00
|
|
|
terminal: Arc<FairMutex<Term<U>>>,
|
|
|
|
event_proxy: U,
|
2018-10-16 17:02:52 +00:00
|
|
|
pty: T,
|
2019-10-09 21:37:48 +00:00
|
|
|
config: &Config<V>,
|
2019-10-05 00:29:26 +00:00
|
|
|
) -> EventLoop<T, U> {
|
2017-08-30 18:43:37 +00:00
|
|
|
let (tx, rx) = channel::channel();
|
2016-09-26 02:49:44 +00:00
|
|
|
EventLoop {
|
|
|
|
poll: mio::Poll::new().expect("create mio Poll"),
|
2018-03-04 22:40:15 +00:00
|
|
|
pty,
|
|
|
|
tx,
|
|
|
|
rx,
|
|
|
|
terminal,
|
2019-10-05 00:29:26 +00:00
|
|
|
event_proxy,
|
2019-10-09 21:37:48 +00:00
|
|
|
hold: config.hold,
|
|
|
|
ref_test: config.debug.ref_test,
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-30 18:43:37 +00:00
|
|
|
pub fn channel(&self) -> Sender<Msg> {
|
2016-09-26 02:49:44 +00:00
|
|
|
self.tx.clone()
|
|
|
|
}
|
|
|
|
|
2017-01-10 18:27:25 +00:00
|
|
|
// Drain the channel
|
|
|
|
//
|
2019-10-05 00:29:26 +00:00
|
|
|
// Returns `false` when a shutdown message was received.
|
|
|
|
fn drain_recv_channel(&self, state: &mut State) -> bool {
|
2016-09-26 15:28:38 +00:00
|
|
|
while let Ok(msg) = self.rx.try_recv() {
|
|
|
|
match msg {
|
2019-10-05 00:29:26 +00:00
|
|
|
Msg::Input(input) => state.write_list.push_back(input),
|
|
|
|
Msg::Shutdown => return false,
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2019-10-05 00:29:26 +00:00
|
|
|
true
|
2017-01-10 18:27:25 +00:00
|
|
|
}
|
|
|
|
|
2017-05-20 04:35:43 +00:00
|
|
|
// Returns a `bool` indicating whether or not the event loop should continue running
|
2017-01-10 18:27:25 +00:00
|
|
|
#[inline]
|
2019-03-12 19:44:47 +00:00
|
|
|
fn channel_event(&mut self, token: mio::Token, state: &mut State) -> bool {
|
2019-10-05 00:29:26 +00:00
|
|
|
if !self.drain_recv_channel(state) {
|
2017-05-20 04:35:43 +00:00
|
|
|
return false;
|
|
|
|
}
|
2017-01-10 18:27:25 +00:00
|
|
|
|
2018-10-16 17:02:52 +00:00
|
|
|
self.poll
|
2019-03-12 19:44:47 +00:00
|
|
|
.reregister(&self.rx, token, Ready::readable(), PollOpt::edge() | PollOpt::oneshot())
|
2018-10-16 17:02:52 +00:00
|
|
|
.unwrap();
|
2017-05-24 16:50:49 +00:00
|
|
|
|
2017-05-20 04:35:43 +00:00
|
|
|
true
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
#[inline]
|
2018-10-16 17:02:52 +00:00
|
|
|
fn pty_read<X>(
|
2016-12-17 06:48:04 +00:00
|
|
|
&mut self,
|
|
|
|
state: &mut State,
|
|
|
|
buf: &mut [u8],
|
2018-10-16 17:02:52 +00:00
|
|
|
mut writer: Option<&mut X>,
|
2017-04-04 04:27:03 +00:00
|
|
|
) -> io::Result<()>
|
2019-03-30 16:48:36 +00:00
|
|
|
where
|
|
|
|
X: Write,
|
2016-12-17 06:48:04 +00:00
|
|
|
{
|
2017-07-02 20:11:00 +00:00
|
|
|
let mut processed = 0;
|
|
|
|
let mut terminal = None;
|
|
|
|
|
2016-09-26 15:28:38 +00:00
|
|
|
loop {
|
2018-10-16 17:02:52 +00:00
|
|
|
match self.pty.reader().read(&mut buf[..]) {
|
2016-09-26 15:28:38 +00:00
|
|
|
Ok(0) => break,
|
|
|
|
Ok(got) => {
|
2017-07-02 20:11:00 +00:00
|
|
|
// Record bytes read; used to limit time spent in pty_read.
|
|
|
|
processed += got;
|
|
|
|
|
|
|
|
// Send a copy of bytes read to a subscriber. Used for
|
|
|
|
// example with ref test recording.
|
2016-11-20 00:16:20 +00:00
|
|
|
writer = writer.map(|w| {
|
2017-07-02 20:11:00 +00:00
|
|
|
w.write_all(&buf[..got]).unwrap();
|
|
|
|
w
|
2016-11-20 00:16:20 +00:00
|
|
|
});
|
|
|
|
|
2017-07-02 20:11:00 +00:00
|
|
|
// Get reference to terminal. Lock is acquired on initial
|
|
|
|
// iteration and held until there's no bytes left to parse
|
|
|
|
// or we've reached MAX_READ.
|
2019-10-05 00:29:26 +00:00
|
|
|
if terminal.is_none() {
|
2017-07-02 20:11:00 +00:00
|
|
|
terminal = Some(self.terminal.lock());
|
2019-10-05 00:29:26 +00:00
|
|
|
}
|
|
|
|
let terminal = terminal.as_mut().unwrap();
|
2017-07-02 20:11:00 +00:00
|
|
|
|
|
|
|
// Run the parser
|
2016-09-26 15:28:38 +00:00
|
|
|
for byte in &buf[..got] {
|
2019-03-30 16:48:36 +00:00
|
|
|
state.parser.advance(&mut **terminal, *byte, &mut self.pty.writer());
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2017-07-02 20:11:00 +00:00
|
|
|
// Exit if we've processed enough bytes
|
|
|
|
if processed > MAX_READ {
|
|
|
|
break;
|
2016-12-30 02:38:22 +00:00
|
|
|
}
|
2019-03-30 16:48:36 +00:00
|
|
|
},
|
2018-10-16 17:02:52 +00:00
|
|
|
Err(err) => match err.kind() {
|
|
|
|
ErrorKind::Interrupted | ErrorKind::WouldBlock => {
|
|
|
|
break;
|
2019-03-30 16:48:36 +00:00
|
|
|
},
|
2018-10-16 17:02:52 +00:00
|
|
|
_ => return Err(err),
|
|
|
|
},
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2017-04-04 04:27:03 +00:00
|
|
|
|
2019-11-16 21:11:56 +00:00
|
|
|
if processed > 0 {
|
|
|
|
// Queue terminal redraw
|
|
|
|
self.event_proxy.send_event(Event::Wakeup);
|
|
|
|
}
|
2017-07-02 20:11:00 +00:00
|
|
|
|
2017-04-04 04:27:03 +00:00
|
|
|
Ok(())
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-04-04 04:27:03 +00:00
|
|
|
fn pty_write(&mut self, state: &mut State) -> io::Result<()> {
|
2016-09-26 15:28:38 +00:00
|
|
|
state.ensure_next();
|
|
|
|
|
|
|
|
'write_many: while let Some(mut current) = state.take_current() {
|
|
|
|
'write_one: loop {
|
2018-10-16 17:02:52 +00:00
|
|
|
match self.pty.writer().write(current.remaining_bytes()) {
|
2016-09-26 15:28:38 +00:00
|
|
|
Ok(0) => {
|
|
|
|
state.set_current(Some(current));
|
|
|
|
break 'write_many;
|
2019-03-30 16:48:36 +00:00
|
|
|
},
|
2016-09-26 15:28:38 +00:00
|
|
|
Ok(n) => {
|
|
|
|
current.advance(n);
|
|
|
|
if current.finished() {
|
|
|
|
state.goto_next();
|
|
|
|
break 'write_one;
|
|
|
|
}
|
2019-03-30 16:48:36 +00:00
|
|
|
},
|
2016-09-26 15:28:38 +00:00
|
|
|
Err(err) => {
|
|
|
|
state.set_current(Some(current));
|
|
|
|
match err.kind() {
|
2018-10-16 17:02:52 +00:00
|
|
|
ErrorKind::Interrupted | ErrorKind::WouldBlock => break 'write_many,
|
2017-04-04 04:27:03 +00:00
|
|
|
_ => return Err(err),
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2019-03-30 16:48:36 +00:00
|
|
|
},
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-04 04:27:03 +00:00
|
|
|
|
|
|
|
Ok(())
|
2016-09-26 15:28:38 +00:00
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
|
2019-10-05 00:29:26 +00:00
|
|
|
pub fn spawn(mut self) -> thread::JoinHandle<(Self, State)> {
|
2016-09-26 02:49:44 +00:00
|
|
|
thread::spawn_named("pty reader", move || {
|
2019-10-05 00:29:26 +00:00
|
|
|
let mut state = State::default();
|
|
|
|
let mut buf = [0u8; MAX_READ];
|
2016-09-26 15:28:38 +00:00
|
|
|
|
2019-03-12 19:44:47 +00:00
|
|
|
let mut tokens = (0..).map(Into::into);
|
2016-09-26 15:28:38 +00:00
|
|
|
|
2019-03-12 19:44:47 +00:00
|
|
|
let poll_opts = PollOpt::edge() | PollOpt::oneshot();
|
2018-10-16 17:02:52 +00:00
|
|
|
|
2019-03-12 19:44:47 +00:00
|
|
|
let channel_token = tokens.next().unwrap();
|
2019-03-30 16:48:36 +00:00
|
|
|
self.poll.register(&self.rx, channel_token, Ready::readable(), poll_opts).unwrap();
|
2018-10-16 17:02:52 +00:00
|
|
|
|
|
|
|
// Register TTY through EventedRW interface
|
2019-03-30 16:48:36 +00:00
|
|
|
self.pty.register(&self.poll, &mut tokens, Ready::readable(), poll_opts).unwrap();
|
2016-09-26 02:49:44 +00:00
|
|
|
|
|
|
|
let mut events = Events::with_capacity(1024);
|
|
|
|
|
2016-11-20 00:16:20 +00:00
|
|
|
let mut pipe = if self.ref_test {
|
2018-10-16 17:02:52 +00:00
|
|
|
Some(File::create("./alacritty.recording").expect("create alacritty recording"))
|
2016-11-20 00:16:20 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
2016-09-26 02:49:44 +00:00
|
|
|
'event_loop: loop {
|
2017-01-06 16:21:00 +00:00
|
|
|
if let Err(err) = self.poll.poll(&mut events, None) {
|
|
|
|
match err.kind() {
|
|
|
|
ErrorKind::Interrupted => continue,
|
2018-10-16 17:02:52 +00:00
|
|
|
_ => panic!("EventLoop polling error: {:?}", err),
|
2017-01-06 16:21:00 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
|
|
|
|
for event in events.iter() {
|
|
|
|
match event.token() {
|
2019-03-12 19:44:47 +00:00
|
|
|
token if token == channel_token => {
|
|
|
|
if !self.channel_event(channel_token, &mut state) {
|
|
|
|
break 'event_loop;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
token if token == self.pty.child_event_token() => {
|
|
|
|
if let Some(tty::ChildEvent::Exited) = self.pty.next_child_event() {
|
2019-10-09 21:37:48 +00:00
|
|
|
if !self.hold {
|
|
|
|
self.terminal.lock().exit();
|
|
|
|
}
|
2019-10-05 00:29:26 +00:00
|
|
|
self.event_proxy.send_event(Event::Wakeup);
|
2019-03-12 19:44:47 +00:00
|
|
|
break 'event_loop;
|
|
|
|
}
|
2017-05-20 04:35:43 +00:00
|
|
|
},
|
2019-03-12 19:44:47 +00:00
|
|
|
|
2019-03-30 16:48:36 +00:00
|
|
|
token
|
|
|
|
if token == self.pty.read_token()
|
|
|
|
|| token == self.pty.write_token() =>
|
|
|
|
{
|
|
|
|
#[cfg(unix)]
|
|
|
|
{
|
2019-03-12 19:44:47 +00:00
|
|
|
if UnixReady::from(event.readiness()).is_hup() {
|
|
|
|
// don't try to do I/O on a dead PTY
|
|
|
|
continue;
|
2017-04-04 04:27:03 +00:00
|
|
|
}
|
2019-03-12 19:44:47 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 17:02:52 +00:00
|
|
|
if event.readiness().is_readable() {
|
2019-03-12 19:44:47 +00:00
|
|
|
if let Err(e) = self.pty_read(&mut state, &mut buf, pipe.as_mut()) {
|
2019-03-30 16:48:36 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
{
|
2019-03-12 19:44:47 +00:00
|
|
|
// On Linux, a `read` on the master side of a PTY can fail
|
|
|
|
// with `EIO` if the client side hangs up. In that case,
|
|
|
|
// just loop back round for the inevitable `Exited` event.
|
|
|
|
// This sucks, but checking the process is either racy or
|
|
|
|
// blocking.
|
|
|
|
if e.kind() == ErrorKind::Other {
|
|
|
|
continue;
|
|
|
|
}
|
2018-10-16 17:02:52 +00:00
|
|
|
}
|
2017-04-04 04:27:03 +00:00
|
|
|
|
2019-03-12 19:44:47 +00:00
|
|
|
error!("Error reading from PTY in event loop: {}", e);
|
2016-11-12 02:00:08 +00:00
|
|
|
break 'event_loop;
|
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 17:02:52 +00:00
|
|
|
if event.readiness().is_writable() {
|
2019-03-12 19:44:47 +00:00
|
|
|
if let Err(e) = self.pty_write(&mut state) {
|
|
|
|
error!("Error writing to PTY in event loop: {}", e);
|
2017-04-04 04:27:03 +00:00
|
|
|
break 'event_loop;
|
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
2018-10-16 17:02:52 +00:00
|
|
|
}
|
2016-09-26 02:49:44 +00:00
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
}
|
2018-10-16 17:02:52 +00:00
|
|
|
|
|
|
|
// Register write interest if necessary
|
|
|
|
let mut interest = Ready::readable();
|
|
|
|
if state.needs_write() {
|
|
|
|
interest.insert(Ready::writable());
|
|
|
|
}
|
|
|
|
// Reregister with new interest
|
|
|
|
self.pty.reregister(&self.poll, interest, poll_opts).unwrap();
|
2016-09-26 02:49:44 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 17:02:52 +00:00
|
|
|
// The evented instances are not dropped here so deregister them explicitly
|
2016-11-12 02:00:08 +00:00
|
|
|
let _ = self.poll.deregister(&self.rx);
|
2018-12-14 03:54:05 +00:00
|
|
|
let _ = self.pty.deregister(&self.poll);
|
2016-09-26 15:28:38 +00:00
|
|
|
|
|
|
|
(self, state)
|
2016-09-26 02:49:44 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|