diff options
Diffstat (limited to '')
-rw-r--r-- | src/liblzma/common/common.h | 7 | ||||
-rw-r--r-- | src/liblzma/common/stream_decoder_mt.c | 50 |
2 files changed, 32 insertions, 25 deletions
diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h index 67996228..36366dbc 100644 --- a/src/liblzma/common/common.h +++ b/src/liblzma/common/common.h @@ -67,14 +67,15 @@ #define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62) -/// Supported flags that can be passed to lzma_stream_decoder() -/// or lzma_auto_decoder(). +/// Supported flags that can be passed to lzma_stream_decoder(), +/// lzma_auto_decoder(), or lzma_stream_decoder_mt(). #define LZMA_SUPPORTED_FLAGS \ ( LZMA_TELL_NO_CHECK \ | LZMA_TELL_UNSUPPORTED_CHECK \ | LZMA_TELL_ANY_CHECK \ | LZMA_IGNORE_CHECK \ - | LZMA_CONCATENATED ) + | LZMA_CONCATENATED \ + | LZMA_FAIL_FAST ) /// Largest valid lzma_action value as unsigned integer. diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c index 7f445982..32e0b892 100644 --- a/src/liblzma/common/stream_decoder_mt.c +++ b/src/liblzma/common/stream_decoder_mt.c @@ -300,6 +300,10 @@ struct lzma_stream_coder { /// Stream Padding is a multiple of four bytes. bool concatenated; + /// If true, we will return any errors immediately instead of first + /// producing all output before the location of the error. + bool fail_fast; + /// When decoding concatenated Streams, this is true as long as we /// are decoding the first Stream. This is needed to avoid misleading @@ -711,13 +715,12 @@ read_output_and_wait(struct lzma_stream_coder *coder, coder->pending_error = coder->thread_error; - // FIXME? Add a flag to do this conditionally? - // That way errors would get reported to the - // application without a delay. -// if (coder->fast_errors) { -// ret = coder->thread_error; -// break; -// } + // If LZMA_FAIL_FAST was used, report errors + // from worker threads immediately. + if (coder->fail_fast) { + ret = coder->thread_error; + break; + } } // Check if decoding of the next Block can be started. @@ -1690,22 +1693,24 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator, break; case SEQ_ERROR: - // Let the application get all data before the point where - // the error was detected. This matches the behavior of - // single-threaded use. - // - // FIXME? Some errors (LZMA_MEM_ERROR) don't get here, - // they are returned immediately. Thus in rare cases the - // output will be less than in single-threaded mode. But - // maybe this doesn't matter much in practice. - return_if_error(read_output_and_wait(coder, allocator, - out, out_pos, out_size, - NULL, true, &wait_abs, &has_blocked)); + if (!coder->fail_fast) { + // Let the application get all data before the point + // where the error was detected. This matches the + // behavior of single-threaded use. + // + // FIXME? Some errors (LZMA_MEM_ERROR) don't get here, + // they are returned immediately. Thus in rare cases + // the output will be less than in the single-threaded + // mode. Maybe this doesn't matter much in practice. + return_if_error(read_output_and_wait(coder, allocator, + out, out_pos, out_size, + NULL, true, &wait_abs, &has_blocked)); - // We get here only if the error happened in the main thread, - // for example, unsupported Block Header. - if (!lzma_outq_is_empty(&coder->outq)) - return LZMA_OK; + // We get here only if the error happened in the main + // thread, for example, unsupported Block Header. + if (!lzma_outq_is_empty(&coder->outq)) + return LZMA_OK; + } return coder->pending_error; @@ -1900,6 +1905,7 @@ stream_decoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator, coder->tell_any_check = (options->flags & LZMA_TELL_ANY_CHECK) != 0; coder->ignore_check = (options->flags & LZMA_IGNORE_CHECK) != 0; coder->concatenated = (options->flags & LZMA_CONCATENATED) != 0; + coder->fail_fast = (options->flags & LZMA_FAIL_FAST) != 0; coder->first_stream = true; coder->out_was_filled = false; |