From: Lasse Collin Date: Thu, 3 Apr 2025 11:34:42 +0000 (+0300) Subject: liblzma: mt dec: Fix lack of parallelization in single-shot decoding X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e918d09ad01cc83911eac7147c3d7d8c7f6bd9a;p=thirdparty%2Fxz.git liblzma: mt dec: Fix lack of parallelization in single-shot decoding Single-shot decoding means calling lzma_code() by giving it the whole input at once and enough output buffer space to store the uncompressed data, and combining this with LZMA_FINISH and no timeout (lzma_mt.timeout = 0). This way the file is decoded with a single lzma_code() call if possible. The bug prevented the decoder from starting more than one worker thread in single-shot mode. The issue was noticed when reviewing the code; there are no bug reports. Thus maybe few have tried this mode. Fixes: 64b6d496dc81 ("liblzma: Threaded decoder: Always wait for output if LZMA_FINISH is used.") (cherry picked from commit 0c80045ab82c406858d9d5bcea9f48ebc3d0a81d) --- diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c index 0cdb47d3..5da9a275 100644 --- a/src/liblzma/common/stream_decoder_mt.c +++ b/src/liblzma/common/stream_decoder_mt.c @@ -1543,10 +1543,17 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator, // Read output from the output queue. Just like in // SEQ_BLOCK_HEADER, we wait to fill the output buffer // only if waiting_allowed was set to true in the beginning - // of this function (see the comment there). + // of this function (see the comment there) and there is + // no input available. In SEQ_BLOCK_HEADER, there is never + // input available when read_output_and_wait() is called, + // but here there can be when LZMA_FINISH is used, thus we + // need to check if *in_pos == in_size. Otherwise we would + // wait here instead of using the available input to start + // a new thread. return_if_error(read_output_and_wait(coder, allocator, out, out_pos, out_size, - NULL, waiting_allowed, + NULL, + waiting_allowed && *in_pos == in_size, &wait_abs, &has_blocked)); if (coder->pending_error != LZMA_OK) {