From 20ec36eafddd7b3a0e014e1f4ed1b87a9105a725 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Thu, 3 Apr 2025 14:34:42 +0300 Subject: [PATCH] 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) --- src/liblzma/common/stream_decoder_mt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c index 6bbbe53b..3752440a 100644 --- a/src/liblzma/common/stream_decoder_mt.c +++ b/src/liblzma/common/stream_decoder_mt.c @@ -1544,10 +1544,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) {