diff options
Diffstat (limited to 'src/rw.rs')
| -rw-r--r-- | src/rw.rs | 63 |
1 files changed, 54 insertions, 9 deletions
@@ -4,6 +4,10 @@ use std::{ io::{self, PipeReader, PipeWriter, Read, Write}, os::fd::{AsFd, BorrowedFd}, process::Stdio, + sync::{ + Arc, + atomic::{AtomicBool, Ordering::SeqCst}, + }, }; use nix::poll::{PollFd, PollFlags}; @@ -40,6 +44,26 @@ impl From<Output> for Stdio { } } +impl Input { + pub fn try_clone(&self) -> io::Result<Self> { + Ok(match self { + Input::Stdin => Input::Stdin, + Input::Pipe(pr) => Input::Pipe(pr.try_clone()?), + Input::File(f) => Input::File(f.try_clone()?), + }) + } +} + +impl Output { + pub fn try_clone(&self) -> io::Result<Self> { + Ok(match self { + Output::Stdout => Output::Stdout, + Output::Pipe(pw) => Output::Pipe(pw.try_clone()?), + Output::File(f) => Output::File(f.try_clone()?), + }) + } +} + pub struct Canceler { tx: PipeWriter, } @@ -53,7 +77,7 @@ impl Canceler { pub struct InputReader { input: Input, cancel: PipeReader, - canceled: bool, + canceled: Arc<AtomicBool>, } impl InputReader { @@ -63,11 +87,22 @@ impl InputReader { Self { input, cancel, - canceled: false, + canceled: Arc::new(AtomicBool::new(false)), }, Canceler { tx }, ) } + + pub fn try_clone(&self) -> io::Result<Self> { + let input = self.input.try_clone()?; + let cancel = self.cancel.try_clone()?; + let canceled = self.canceled.clone(); + Ok(Self { + input, + cancel, + canceled, + }) + } } const TIMEOUT_MS: u16 = 1000; @@ -79,12 +114,12 @@ enum PollStatus { } fn check<'a>( - canceled: &mut bool, + canceled: &AtomicBool, cancel: &PipeReader, fd: BorrowedFd<'a>, flags: PollFlags, ) -> PollStatus { - if *canceled { + if canceled.load(SeqCst) { return PollStatus::Cancel; } @@ -94,13 +129,13 @@ fn check<'a>( ]; if nix::poll::poll(&mut poll_fds, TIMEOUT_MS).is_err() { - *canceled = true; + canceled.store(true, SeqCst); return PollStatus::Cancel; }; if let Some(event) = poll_fds[0].revents() { if event.contains(PollFlags::POLLIN) { - *canceled = true; + canceled.store(true, SeqCst); return PollStatus::Cancel; } } @@ -122,7 +157,7 @@ impl InputReader { Input::Pipe(pipe) => pipe.as_fd(), Input::File(file) => file.as_fd(), }; - check(&mut self.canceled, &self.cancel, read_fd, PollFlags::POLLIN) + check(&*self.canceled, &self.cancel, read_fd, PollFlags::POLLIN) } } @@ -157,7 +192,7 @@ impl Read for InputReader { pub struct OutputWriter { output: Output, cancel: PipeReader, - canceled: bool, + canceled: Arc<AtomicBool>, } impl OutputWriter { @@ -167,7 +202,7 @@ impl OutputWriter { Self { output, cancel, - canceled: false, + canceled: Arc::new(AtomicBool::new(false)), }, Canceler { tx }, ) @@ -186,6 +221,16 @@ impl OutputWriter { PollFlags::POLLOUT, ) } + pub fn try_clone(&self) -> io::Result<Self> { + let output = self.output.try_clone()?; + let cancel = self.cancel.try_clone()?; + let canceled = self.canceled.clone(); + Ok(Self { + output, + cancel, + canceled, + }) + } } impl Write for OutputWriter { |
