aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/liblzma/common/stream_decoder_mt.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c
index 840051b0..295f913d 100644
--- a/src/liblzma/common/stream_decoder_mt.c
+++ b/src/liblzma/common/stream_decoder_mt.c
@@ -1169,9 +1169,16 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator,
// The downside of this is that with fail-fast apps
// cannot always distinguish between corrupt and
// truncated files.
- if (action == LZMA_FINISH && coder->fail_fast)
+ if (action == LZMA_FINISH && coder->fail_fast) {
+ // We won't produce any more output. Stop
+ // the unfinished worker threads so they
+ // won't waste CPU time.
+ threads_stop(coder);
return LZMA_DATA_ERROR;
+ }
+ // read_output_and_wait() will call threads_stop()
+ // if needed so with that we can use return_if_error.
return_if_error(read_output_and_wait(coder, allocator,
out, out_pos, out_size,
NULL, waiting_allowed,
@@ -1447,12 +1454,20 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator,
}
// Allocate memory for the output buffer in the output queue.
- return_if_error(lzma_outq_prealloc_buf(
+ lzma_ret ret = lzma_outq_prealloc_buf(
&coder->outq, allocator,
- coder->block_options.uncompressed_size));
+ coder->block_options.uncompressed_size);
+ if (ret != LZMA_OK) {
+ threads_stop(coder);
+ return ret;
+ }
// Set up coder->thr.
- return_if_error(get_thread(coder, allocator));
+ ret = get_thread(coder, allocator);
+ if (ret != LZMA_OK) {
+ threads_stop(coder);
+ return ret;
+ }
// The new Block decoder memory usage is already counted in
// coder->mem_in_use. Store it in the thread too.
@@ -1460,7 +1475,7 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator,
// Initialize the Block decoder.
coder->thr->block_options = coder->block_options;
- const lzma_ret ret = lzma_block_decoder_init(
+ ret = lzma_block_decoder_init(
&coder->thr->block_decoder, allocator,
&coder->thr->block_options);
@@ -1480,8 +1495,10 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator,
// Allocate the input buffer.
coder->thr->in_size = coder->mem_next_in;
coder->thr->in = lzma_alloc(coder->thr->in_size, allocator);
- if (coder->thr->in == NULL)
+ if (coder->thr->in == NULL) {
+ threads_stop(coder);
return LZMA_MEM_ERROR;
+ }
// Get the preallocated output buffer.
coder->thr->outbuf = lzma_outq_get_buf(
@@ -1516,8 +1533,10 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator,
const size_t in_avail = in_size - *in_pos;
const size_t in_needed = coder->thr->in_size
- coder->thr->in_filled;
- if (in_avail < in_needed)
+ if (in_avail < in_needed) {
+ threads_stop(coder);
return LZMA_DATA_ERROR;
+ }
}
// Copy input to the worker thread.