1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-29 21:44:24 +03:00

mux: bounded number of fds for ServerPollable

It was possible to exhaust the number of fds on the server by
opening a vertical vim split and aggressively sliding it left
and right.

This commit allows the produce side to clone an arbitrary number
of senders without using up file descriptors.
This commit is contained in:
Wez Furlong 2020-01-10 07:44:36 -08:00
parent b722dd178f
commit 88c3d620bf

View File

@ -5,6 +5,7 @@ use filedescriptor::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::net::TcpStream; use std::net::TcpStream;
use std::sync::{Arc, Mutex};
pub trait ReadAndWrite: std::io::Read + std::io::Write + Send + AsPollFd { pub trait ReadAndWrite: std::io::Read + std::io::Write + Send + AsPollFd {
fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()>; fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()>;
@ -42,12 +43,12 @@ impl ReadAndWrite for openssl::ssl::SslStream<std::net::TcpStream> {
pub struct PollableSender<T> { pub struct PollableSender<T> {
sender: Sender<T>, sender: Sender<T>,
write: RefCell<FileDescriptor>, write: Arc<Mutex<FileDescriptor>>,
} }
impl<T: Send + Sync + 'static> PollableSender<T> { impl<T: Send + Sync + 'static> PollableSender<T> {
pub fn send(&self, item: T) -> anyhow::Result<()> { pub fn send(&self, item: T) -> anyhow::Result<()> {
self.write.borrow_mut().write_all(b"x")?; self.write.lock().unwrap().write_all(b"x")?;
self.sender.send(item).map_err(Error::msg)?; self.sender.send(item).map_err(Error::msg)?;
Ok(()) Ok(())
} }
@ -57,12 +58,7 @@ impl<T> Clone for PollableSender<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
sender: self.sender.clone(), sender: self.sender.clone(),
write: RefCell::new( write: self.write.clone(),
self.write
.borrow()
.try_clone()
.expect("failed to clone PollableSender fd"),
),
} }
} }
} }
@ -98,7 +94,7 @@ pub fn pollable_channel<T>() -> anyhow::Result<(PollableSender<T>, PollableRecei
Ok(( Ok((
PollableSender { PollableSender {
sender, sender,
write: RefCell::new(FileDescriptor::new(write)), write: Arc::new(Mutex::new(FileDescriptor::new(write))),
}, },
PollableReceiver { PollableReceiver {
receiver, receiver,