mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-30 11:21:15 -03:00
Use OwnedFd in AutoClosePipes
This commit is contained in:
committed by
ridiculousfish
parent
59fe52851e
commit
971d774e67
29
src/io.rs
29
src/io.rs
@@ -21,7 +21,7 @@
|
||||
use nix::fcntl::OFlag;
|
||||
use nix::sys::stat::Mode;
|
||||
use std::cell::{RefCell, UnsafeCell};
|
||||
use std::os::fd::{AsRawFd, OwnedFd, RawFd};
|
||||
use std::os::fd::{AsRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::{Arc, Condvar, Mutex, MutexGuard};
|
||||
|
||||
@@ -296,13 +296,12 @@ fn as_ptr(&self) -> *const () {
|
||||
pub struct IoPipe {
|
||||
fd: RawFd,
|
||||
// The pipe's fd. Conceptually this is dup2'd to io_data_t::fd.
|
||||
pipe_fd: AutoCloseFd,
|
||||
pipe_fd: OwnedFd,
|
||||
/// Whether this is an input pipe. This is used only for informational purposes.
|
||||
is_input: bool,
|
||||
}
|
||||
impl IoPipe {
|
||||
pub fn new(fd: RawFd, is_input: bool, pipe_fd: AutoCloseFd) -> Self {
|
||||
assert!(pipe_fd.is_valid(), "Pipe is not valid");
|
||||
pub fn new(fd: RawFd, is_input: bool, pipe_fd: OwnedFd) -> Self {
|
||||
IoPipe {
|
||||
fd,
|
||||
pipe_fd,
|
||||
@@ -318,7 +317,7 @@ fn fd(&self) -> RawFd {
|
||||
self.fd
|
||||
}
|
||||
fn source_fd(&self) -> RawFd {
|
||||
self.pipe_fd.fd()
|
||||
self.pipe_fd.as_raw_fd()
|
||||
}
|
||||
fn print(&self) {
|
||||
eprintf!(
|
||||
@@ -338,7 +337,7 @@ pub struct IoBufferfill {
|
||||
target: RawFd,
|
||||
|
||||
/// Write end. The other end is connected to an io_buffer_t.
|
||||
write_fd: AutoCloseFd,
|
||||
write_fd: OwnedFd,
|
||||
|
||||
/// The receiving buffer.
|
||||
buffer: Arc<IoBuffer>,
|
||||
@@ -361,7 +360,7 @@ pub fn create_opts(buffer_limit: usize, target: RawFd) -> Option<Arc<IoBufferfil
|
||||
// Our buffer will read from the read end of the pipe. This end must be non-blocking. This is
|
||||
// because our fillthread needs to poll to decide if it should shut down, and also accept input
|
||||
// from direct buffer transfers.
|
||||
match make_fd_nonblocking(pipes.read.fd()) {
|
||||
match make_fd_nonblocking(pipes.read.as_raw_fd()) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
FLOG!(warning, PIPE_ERROR);
|
||||
@@ -372,7 +371,6 @@ pub fn create_opts(buffer_limit: usize, target: RawFd) -> Option<Arc<IoBufferfil
|
||||
// Our fillthread gets the read end of the pipe; out_pipe gets the write end.
|
||||
let buffer = Arc::new(IoBuffer::new(buffer_limit));
|
||||
begin_filling(&buffer, pipes.read);
|
||||
assert!(pipes.write.is_valid(), "fd is not valid");
|
||||
Some(Arc::new(IoBufferfill {
|
||||
target,
|
||||
write_fd: pipes.write,
|
||||
@@ -408,10 +406,14 @@ fn fd(&self) -> RawFd {
|
||||
self.target
|
||||
}
|
||||
fn source_fd(&self) -> RawFd {
|
||||
self.write_fd.fd()
|
||||
self.write_fd.as_raw_fd()
|
||||
}
|
||||
fn print(&self) {
|
||||
eprintf!("bufferfill %d -> %d\n", self.write_fd.fd(), self.fd())
|
||||
eprintf!(
|
||||
"bufferfill %d -> %d\n",
|
||||
self.write_fd.as_raw_fd(),
|
||||
self.fd()
|
||||
)
|
||||
}
|
||||
fn as_ptr(&self) -> *const () {
|
||||
(self as *const Self).cast()
|
||||
@@ -533,7 +535,7 @@ pub fn fillthread_running(&self) -> bool {
|
||||
}
|
||||
|
||||
/// Begin the fill operation, reading from the given fd in the background.
|
||||
fn begin_filling(iobuffer: &Arc<IoBuffer>, fd: AutoCloseFd) {
|
||||
fn begin_filling(iobuffer: &Arc<IoBuffer>, fd: OwnedFd) {
|
||||
assert!(!iobuffer.fillthread_running(), "Already have a fillthread");
|
||||
|
||||
// We want to fill buffer_ by reading from fd. fd is the read end of a pipe; the write end is
|
||||
@@ -570,14 +572,14 @@ fn begin_filling(iobuffer: &Arc<IoBuffer>, fd: AutoCloseFd) {
|
||||
if reason == ItemWakeReason::Readable {
|
||||
// select() reported us as readable; read a bit.
|
||||
let mut buf = iobuffer.buffer.lock().unwrap();
|
||||
let ret = IoBuffer::read_once(fd.fd(), &mut buf);
|
||||
let ret = IoBuffer::read_once(fd.as_raw_fd(), &mut buf);
|
||||
done = ret == 0 || (ret < 0 && ![EAGAIN, EWOULDBLOCK].contains(&errno::errno().0));
|
||||
} else if iobuffer.shutdown_fillthread.load() {
|
||||
// Here our caller asked us to shut down; read while we keep getting data.
|
||||
// This will stop when the fd is closed or if we get EAGAIN.
|
||||
let mut buf = iobuffer.buffer.lock().unwrap();
|
||||
loop {
|
||||
let ret = IoBuffer::read_once(fd.fd(), &mut buf);
|
||||
let ret = IoBuffer::read_once(fd.as_raw_fd(), &mut buf);
|
||||
if ret <= 0 {
|
||||
break;
|
||||
}
|
||||
@@ -599,6 +601,7 @@ fn begin_filling(iobuffer: &Arc<IoBuffer>, fd: AutoCloseFd) {
|
||||
})
|
||||
};
|
||||
|
||||
let fd = AutoCloseFd::new(fd.into_raw_fd());
|
||||
let item_id = fd_monitor().add(FdMonitorItem::new(fd, None, item_callback));
|
||||
iobuffer.item_id.store(u64::from(item_id), Ordering::SeqCst);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user