aboutsummaryrefslogtreecommitdiff
path: root/src/xz/coder.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2013-07-04 14:18:46 +0300
committerLasse Collin <lasse.collin@tukaani.org>2013-07-04 14:18:46 +0300
commitdee6ad3d5915422bc30a6821efeacaeb8ca8ef00 (patch)
tree1d7ed417efbe88860df208afaf0b96ed7ed07afd /src/xz/coder.c
parentxz: Don't set src_eof=true after an I/O error because it's useless. (diff)
downloadxz-dee6ad3d5915422bc30a6821efeacaeb8ca8ef00.tar.xz
xz: Add preliminary support for --flush-timeout=TIMEOUT.
When --flush-timeout=TIMEOUT is used, xz will use LZMA_SYNC_FLUSH if read() would block and at least TIMEOUT milliseconds has elapsed since the previous flush. This can be useful in realtime-like use cases where the data is simultanously decompressed by another process (possibly on a different computer). If new uncompressed input data is produced slowly, without this option xz could buffer the data for a long time until it would become decompressible from the output. If TIMEOUT is 0, the feature is disabled. This is the default. This commit affects the compression side. Using xz for the decompression side for the above purpose doesn't work yet so well because there is quite a bit of input and output buffering when decompressing. The --long-help or man page were not updated yet. The details of this feature may change.
Diffstat (limited to 'src/xz/coder.c')
-rw-r--r--src/xz/coder.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/src/xz/coder.c b/src/xz/coder.c
index d29e40f4..5d422d60 100644
--- a/src/xz/coder.c
+++ b/src/xz/coder.c
@@ -586,6 +586,9 @@ coder_normal(file_pair *pair)
if (block_remaining == 0)
action = LZMA_FULL_FLUSH;
}
+
+ if (action == LZMA_RUN && flush_needed)
+ action = LZMA_SYNC_FLUSH;
}
// Let liblzma do the actual work.
@@ -601,21 +604,42 @@ coder_normal(file_pair *pair)
strm.avail_out = IO_BUFFER_SIZE;
}
- if (ret == LZMA_STREAM_END && action == LZMA_FULL_FLUSH) {
- // Start a new Block.
- action = LZMA_RUN;
+ if (ret == LZMA_STREAM_END && (action == LZMA_SYNC_FLUSH
+ || action == LZMA_FULL_FLUSH)) {
+ // Flushing completed. Write the pending data out
+ // immediatelly so that the reading side can
+ // decompress everything compressed so far. Do this
+ // also with LZMA_FULL_FLUSH because if it is combined
+ // with timed LZMA_SYNC_FLUSH the same flushing
+ // timer can be used.
+ if (io_write(pair, &out_buf, IO_BUFFER_SIZE
+ - strm.avail_out))
+ break;
- if (opt_block_list == NULL) {
- block_remaining = opt_block_size;
- } else {
- // FIXME: Make it work together with
- // --block-size.
- if (opt_block_list[list_pos + 1] != 0)
- ++list_pos;
+ strm.next_out = out_buf.u8;
+ strm.avail_out = IO_BUFFER_SIZE;
- block_remaining = opt_block_list[list_pos];
+ if (action == LZMA_FULL_FLUSH) {
+ if (opt_block_list == NULL) {
+ block_remaining = opt_block_size;
+ } else {
+ // FIXME: Make it work together with
+ // --block-size.
+ if (opt_block_list[list_pos + 1] != 0)
+ ++list_pos;
+
+ block_remaining
+ = opt_block_list[list_pos];
+ }
}
+ // Set the time of the most recent flushing.
+ mytime_set_flush_time();
+
+ // Start a new Block after LZMA_FULL_FLUSH or continue
+ // the same block after LZMA_SYNC_FLUSH.
+ action = LZMA_RUN;
+
} else if (ret != LZMA_OK) {
// Determine if the return value indicates that we
// won't continue coding.