aboutsummaryrefslogtreecommitdiffstats
path: root/src/rw.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/rw.rs')
-rw-r--r--src/rw.rs63
1 files changed, 54 insertions, 9 deletions
diff --git a/src/rw.rs b/src/rw.rs
index 1f8fa92..96031cc 100644
--- a/src/rw.rs
+++ b/src/rw.rs
@@ -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 {