Skip to content

Commit

Permalink
Add workaround for rust-lang/rust#107002
Browse files Browse the repository at this point in the history
  • Loading branch information
fasterthanlime committed Feb 2, 2023
1 parent 1f36329 commit 2cae637
Showing 1 changed file with 44 additions and 53 deletions.
97 changes: 44 additions & 53 deletions crates/hring-buffet/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ pub trait WriteOwned {
let mut written = 0;
let len = buf.bytes_init();
while written < len {
eprintln!(
"WriteOwned::write_all, calling write with range {:?}",
written..len
);
let (res, slice) = self.write(buf.slice(written..len)).await;
buf = slice.into_inner();
let n = res?;
Expand All @@ -43,7 +39,6 @@ pub trait WriteOwned {
/// Write a list of buffers, taking ownership for the duration of the write.
/// Might perform a partial write, see [WriteOwned::writev_all]
async fn writev<B: IoBuf>(&self, list: Vec<B>) -> BufResult<usize, Vec<B>> {
eprintln!("WriteOwned::write_v with {} buffers", list.len());
let mut out_list = Vec::with_capacity(list.len());
let mut list = list.into_iter();
let mut total = 0;
Expand Down Expand Up @@ -85,50 +80,55 @@ pub trait WriteOwned {

/// Write a list of buffers, re-trying the write if the kernel does a partial write.
async fn writev_all<B: IoBuf>(&self, list: Vec<B>) -> std::io::Result<()> {
let mut list: Vec<_> = list.into_iter().map(BufOrSlice::Buf).collect();

while !list.is_empty() {
eprintln!(
"WriteOwned::writev_all, calling writev with {} items",
list.len()
);
eprintln!("self's type is {}", std::any::type_name::<Self>());
let res;
(res, list) = self.writev(list).await;
let n = res?;
// Workaround for https://github.com/rust-lang/rust/issues/107002,
// remove after https://github.com/rust-lang/rust/pull/107013 is merged
writev_all(self, list).await
}
}

if n == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::WriteZero,
"write zero",
));
}
/// Write a list of buffers, re-trying the write if the kernel does a partial write.
async fn writev_all<B: IoBuf>(
this: &(impl WriteOwned + ?Sized),
list: Vec<B>,
) -> std::io::Result<()> {
let mut list: Vec<_> = list.into_iter().map(BufOrSlice::Buf).collect();

while !list.is_empty() {
let res;
(res, list) = this.writev(list).await;
let n = res?;

if n == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::WriteZero,
"write zero",
));
}

let mut n = n;
list = list
.into_iter()
.filter_map(|item| {
if n == 0 {
Some(item)
let mut n = n;
list = list
.into_iter()
.filter_map(|item| {
if n == 0 {
Some(item)
} else {
let item_len = item.len();

if n >= item_len {
n -= item_len;
None
} else {
let item_len = item.len();

if n >= item_len {
n -= item_len;
None
} else {
let item = item.consume(n);
n = 0;
Some(item)
}
let item = item.consume(n);
n = 0;
Some(item)
}
})
.collect();
assert_eq!(n, 0);
}

Ok(())
}
})
.collect();
assert_eq!(n, 0);
}

Ok(())
}

enum BufOrSlice<B: IoBuf> {
Expand Down Expand Up @@ -170,13 +170,6 @@ impl<B: IoBuf> BufOrSlice<B> {
/// Consume the first `n` bytes of the buffer (assuming they've been written).
/// This turns a `BufOrSlice::Buf` into a `BufOrSlice::Slice`
fn consume(self, n: usize) -> Self {
eprintln!(
"consuming {n}, we're a {}",
match self {
BufOrSlice::Buf(_) => "Buf",
BufOrSlice::Slice(_) => "Slice",
}
);
assert!(n <= self.len());

match self {
Expand All @@ -200,12 +193,10 @@ impl ReadOwned for TcpStream {

impl WriteOwned for TcpStream {
async fn write<B: IoBuf>(&self, buf: B) -> BufResult<usize, B> {
eprintln!("TcpStream::write, bytes_init = {}", buf.bytes_init());
TcpStream::write(self, buf).await
}

async fn writev<B: IoBuf>(&self, list: Vec<B>) -> BufResult<usize, Vec<B>> {
eprintln!("TcpStream::write_v with {} buffers", list.len());
TcpStream::writev(self, list).await
}
}
Expand Down

0 comments on commit 2cae637

Please sign in to comment.