virtfs pipe: implement Clone correctly

* The underlying `R`/`W` doesnt need to be Clone, since we just need to
  clone the Arc it sits behind.
* The rights actually shouldn't be behind an Arc - those get mutated
  separately in each clone.
This commit is contained in:
Pat Hickey
2020-07-01 17:54:30 -07:00
parent cf303d91fc
commit e7869c7320

View File

@@ -26,12 +26,21 @@ use std::sync::{Arc, RwLock};
/// let stdin = ReadPipe::from("hello from stdin!"); /// let stdin = ReadPipe::from("hello from stdin!");
/// ctx.stdin(stdin); /// ctx.stdin(stdin);
/// ``` /// ```
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct ReadPipe<R: Read + Any> { pub struct ReadPipe<R: Read + Any> {
rights: Arc<RwLock<HandleRights>>, rights: RwLock<HandleRights>,
reader: Arc<RwLock<R>>, reader: Arc<RwLock<R>>,
} }
impl<R: Read + Any> Clone for ReadPipe<R> {
fn clone(&self) -> Self {
Self {
rights: RwLock::new(*self.rights.read().unwrap()),
reader: self.reader.clone(),
}
}
}
impl<R: Read + Any> ReadPipe<R> { impl<R: Read + Any> ReadPipe<R> {
/// Create a new pipe from a `Read` type. /// Create a new pipe from a `Read` type.
/// ///
@@ -46,14 +55,14 @@ impl<R: Read + Any> ReadPipe<R> {
pub fn from_shared(reader: Arc<RwLock<R>>) -> Self { pub fn from_shared(reader: Arc<RwLock<R>>) -> Self {
use types::Rights; use types::Rights;
Self { Self {
rights: Arc::new(RwLock::new(HandleRights::from_base( rights: RwLock::new(HandleRights::from_base(
Rights::FD_DATASYNC Rights::FD_DATASYNC
| Rights::FD_FDSTAT_SET_FLAGS | Rights::FD_FDSTAT_SET_FLAGS
| Rights::FD_READ | Rights::FD_READ
| Rights::FD_SYNC | Rights::FD_SYNC
| Rights::FD_FILESTAT_GET | Rights::FD_FILESTAT_GET
| Rights::POLL_FD_READWRITE, | Rights::POLL_FD_READWRITE,
))), )),
reader, reader,
} }
} }
@@ -102,10 +111,7 @@ impl<R: Read + Any> Handle for ReadPipe<R> {
} }
fn try_clone(&self) -> io::Result<Box<dyn Handle>> { fn try_clone(&self) -> io::Result<Box<dyn Handle>> {
Ok(Box::new(Self { Ok(Box::new(self.clone()))
rights: self.rights.clone(),
reader: self.reader.clone(),
}))
} }
fn get_file_type(&self) -> types::Filetype { fn get_file_type(&self) -> types::Filetype {
@@ -113,7 +119,7 @@ impl<R: Read + Any> Handle for ReadPipe<R> {
} }
fn get_rights(&self) -> HandleRights { fn get_rights(&self) -> HandleRights {
self.rights.read().unwrap().clone() *self.rights.read().unwrap()
} }
fn set_rights(&self, rights: HandleRights) { fn set_rights(&self, rights: HandleRights) {
@@ -222,12 +228,21 @@ impl<R: Read + Any> Handle for ReadPipe<R> {
} }
/// A virtual pipe write end. /// A virtual pipe write end.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct WritePipe<W: Write + Any> { pub struct WritePipe<W: Write + Any> {
rights: Arc<RwLock<HandleRights>>, rights: RwLock<HandleRights>,
writer: Arc<RwLock<W>>, writer: Arc<RwLock<W>>,
} }
impl<W: Write + Any> Clone for WritePipe<W> {
fn clone(&self) -> Self {
Self {
rights: RwLock::new(*self.rights.read().unwrap()),
writer: self.writer.clone(),
}
}
}
impl<W: Write + Any> WritePipe<W> { impl<W: Write + Any> WritePipe<W> {
/// Create a new pipe from a `Write` type. /// Create a new pipe from a `Write` type.
/// ///
@@ -242,14 +257,14 @@ impl<W: Write + Any> WritePipe<W> {
pub fn from_shared(writer: Arc<RwLock<W>>) -> Self { pub fn from_shared(writer: Arc<RwLock<W>>) -> Self {
use types::Rights; use types::Rights;
Self { Self {
rights: Arc::new(RwLock::new(HandleRights::from_base( rights: RwLock::new(HandleRights::from_base(
Rights::FD_DATASYNC Rights::FD_DATASYNC
| Rights::FD_FDSTAT_SET_FLAGS | Rights::FD_FDSTAT_SET_FLAGS
| Rights::FD_SYNC | Rights::FD_SYNC
| Rights::FD_WRITE | Rights::FD_WRITE
| Rights::FD_FILESTAT_GET | Rights::FD_FILESTAT_GET
| Rights::POLL_FD_READWRITE, | Rights::POLL_FD_READWRITE,
))), )),
writer, writer,
} }
} }
@@ -281,10 +296,7 @@ impl<W: Write + Any> Handle for WritePipe<W> {
} }
fn try_clone(&self) -> io::Result<Box<dyn Handle>> { fn try_clone(&self) -> io::Result<Box<dyn Handle>> {
Ok(Box::new(Self { Ok(Box::new(self.clone()))
rights: self.rights.clone(),
writer: self.writer.clone(),
}))
} }
fn get_file_type(&self) -> types::Filetype { fn get_file_type(&self) -> types::Filetype {
@@ -292,7 +304,7 @@ impl<W: Write + Any> Handle for WritePipe<W> {
} }
fn get_rights(&self) -> HandleRights { fn get_rights(&self) -> HandleRights {
self.rights.read().unwrap().clone() *self.rights.read().unwrap()
} }
fn set_rights(&self, rights: HandleRights) { fn set_rights(&self, rights: HandleRights) {