diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2020-01-26 14:13:42 +0200 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2020-01-26 14:13:42 +0200 |
commit | 5a49e081a098455bcdbd95cefb90e9b18780fe58 (patch) | |
tree | 323ddab03fabed2e00828eaaed8a29598eb06887 /src/xz/file_io.c | |
parent | xz: Refactor io_read() a bit. (diff) | |
download | xz-5a49e081a098455bcdbd95cefb90e9b18780fe58.tar.xz |
xz: Fix semi-busy-waiting in xz --flush-timeout.
When input blocked, xz --flush-timeout=1 would wake up every
millisecond and initiate flushing which would have nothing to
flush and thus would just waste CPU time. The fix disables the
timeout when no input has been seen since the previous flush.
Diffstat (limited to '')
-rw-r--r-- | src/xz/file_io.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/xz/file_io.c b/src/xz/file_io.c index 5d140750..7e9a4e67 100644 --- a/src/xz/file_io.c +++ b/src/xz/file_io.c @@ -749,6 +749,7 @@ io_open_src(const char *src_name) .src_fd = -1, .dest_fd = -1, .src_eof = false, + .src_has_seen_input = false, .dest_try_sparse = false, .dest_pending_sparse = 0, }; @@ -1133,10 +1134,15 @@ io_read(file_pair *pair, io_buf *buf, size_t size) #ifndef TUKLIB_DOSLIKE if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) { - const io_wait_ret ret = io_wait(pair, - mytime_get_flush_timeout(), - true); - switch (ret) { + // Disable the flush-timeout if no input has + // been seen since the previous flush and thus + // there would be nothing to flush after the + // timeout expires (avoids busy waiting). + const int timeout = pair->src_has_seen_input + ? mytime_get_flush_timeout() + : -1; + + switch (io_wait(pair, timeout, true)) { case IO_WAIT_MORE: continue; @@ -1160,6 +1166,7 @@ io_read(file_pair *pair, io_buf *buf, size_t size) } pos += (size_t)(amount); + pair->src_has_seen_input = true; } return pos; |