Skip to content

Commit

Permalink
encoder: instead of using write_all, keep track of partial writes
Browse files Browse the repository at this point in the history
Non-blocking IO can cause the write_all to partially succeed. To retry in
potential future attempts, keep track of how much was written.

This has no impact on blocking IO.
  • Loading branch information
sunshowers committed Apr 8, 2017
1 parent 520d146 commit 02dc9d9
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions src/stream/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ impl<W: Write> Encoder<W> {
// Need to flush?
panic!("Need to flush, but I'm lazy.");
}
self.offset = 0;

// Write the end out
self.writer.write_all(&self.buffer)?;
self.write_from_offset()?;

// Return the writer, because why not
Ok(self.writer)
Expand All @@ -217,6 +217,18 @@ impl<W: Write> Encoder<W> {
pub fn recommended_input_size() -> usize {
unsafe { zstd_sys::ZSTD_CStreamInSize() }
}

/// write_all, except keep track of partial writes for non-blocking IO.
fn write_from_offset(&mut self) -> io::Result<()> {
while self.offset < self.buffer.len() {
match self.writer.write(&self.buffer[self.offset..]) {
Ok(n) => self.offset += n,
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
Err(e) => return Err(e),
}
}
Ok(())
}
}

impl<W: Write> Write for Encoder<W> {
Expand Down Expand Up @@ -284,8 +296,9 @@ impl<W: Write> Write for Encoder<W> {
self.buffer.set_len(buffer.pos);
let _ = parse_code(code)?;
}
self.offset = 0;

self.writer.write_all(&self.buffer)?;
self.write_from_offset()?;
Ok(())
}
}

0 comments on commit 02dc9d9

Please sign in to comment.