You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.1 KiB
111 lines
3.1 KiB
diff --git a/rpmio/rpmio.c b/rpmio/rpmio.c |
|
index cd223e8..f23fc11 100644 |
|
--- a/rpmio/rpmio.c |
|
+++ b/rpmio/rpmio.c |
|
@@ -5,6 +5,7 @@ |
|
#include "system.h" |
|
#include <stdarg.h> |
|
#include <errno.h> |
|
+#include <ctype.h> |
|
|
|
#include <rpm/rpmlog.h> |
|
#include <rpm/rpmmacro.h> |
|
@@ -873,7 +874,12 @@ static const char * getFdErrstr (FD_t fd) |
|
|
|
#include <sys/types.h> |
|
#include <inttypes.h> |
|
+#define LZMA_UNSTABLE |
|
#include <lzma.h> |
|
+/* Multithreading support in stable API since xz 5.2.0 */ |
|
+#if LZMA_VERSION >= 50010020 |
|
+#define HAVE_LZMA_MT |
|
+#endif |
|
|
|
#define kBufferSize (1 << 15) |
|
|
|
@@ -897,7 +902,10 @@ static LZFILE *lzopen_internal(const char *path, const char *mode, int fd, int x |
|
LZFILE *lzfile; |
|
lzma_ret ret; |
|
lzma_stream init_strm = LZMA_STREAM_INIT; |
|
- |
|
+ uint64_t mem_limit = rpmExpandNumeric("%{_xz_memlimit}"); |
|
+#ifdef HAVE_LZMA_MT |
|
+ int threads = 0; |
|
+#endif |
|
for (; *mode; mode++) { |
|
if (*mode == 'w') |
|
encoding = 1; |
|
@@ -905,6 +913,21 @@ static LZFILE *lzopen_internal(const char *path, const char *mode, int fd, int x |
|
encoding = 0; |
|
else if (*mode >= '1' && *mode <= '9') |
|
level = *mode - '0'; |
|
+ else if (*mode == 'T') { |
|
+ if (isdigit(*(mode+1))) { |
|
+#ifdef HAVE_LZMA_MT |
|
+ threads = atoi(++mode); |
|
+#endif |
|
+ /* skip past rest of digits in string that atoi() |
|
+ * should've processed |
|
+ * */ |
|
+ while(isdigit(*++mode)); |
|
+ } |
|
+#ifdef HAVE_LZMA_MT |
|
+ else |
|
+ threads = -1; |
|
+#endif |
|
+ } |
|
} |
|
if (fd != -1) |
|
fp = fdopen(fd, encoding ? "w" : "r"); |
|
@@ -924,16 +947,48 @@ static LZFILE *lzopen_internal(const char *path, const char *mode, int fd, int x |
|
lzfile->strm = init_strm; |
|
if (encoding) { |
|
if (xz) { |
|
- ret = lzma_easy_encoder(&lzfile->strm, level, LZMA_CHECK_SHA256); |
|
+#ifdef HAVE_LZMA_MT |
|
+ if (!threads) { |
|
+#endif |
|
+ ret = lzma_easy_encoder(&lzfile->strm, level, LZMA_CHECK_SHA256); |
|
+#ifdef HAVE_LZMA_MT |
|
+ } else { |
|
+ if (threads == -1) |
|
+ threads = sysconf(_SC_NPROCESSORS_ONLN); |
|
+ lzma_mt mt_options = { |
|
+ .flags = 0, |
|
+ .threads = threads, |
|
+ .block_size = 0, |
|
+ .timeout = 0, |
|
+ .preset = level, |
|
+ .filters = NULL, |
|
+ .check = LZMA_CHECK_SHA256 }; |
|
+ |
|
+ ret = lzma_stream_encoder_mt(&lzfile->strm, &mt_options); |
|
+ } |
|
+#endif |
|
} else { |
|
lzma_options_lzma options; |
|
lzma_lzma_preset(&options, level); |
|
ret = lzma_alone_encoder(&lzfile->strm, &options); |
|
} |
|
- } else { /* lzma_easy_decoder_memusage(level) is not ready yet, use hardcoded limit for now */ |
|
- ret = lzma_auto_decoder(&lzfile->strm, 100<<20, 0); |
|
+ } else { /* lzma_easy_decoder_memusage(level) is not ready yet, use hardcoded limit for now */ |
|
+ ret = lzma_auto_decoder(&lzfile->strm, mem_limit ? mem_limit : 100<<20, 0); |
|
} |
|
if (ret != LZMA_OK) { |
|
+ switch (ret) { |
|
+ case LZMA_MEM_ERROR: |
|
+ rpmlog(RPMLOG_ERR, "liblzma: Memory allocation failed"); |
|
+ break; |
|
+ |
|
+ case LZMA_DATA_ERROR: |
|
+ rpmlog(RPMLOG_ERR, "liblzma: File size limits exceeded"); |
|
+ break; |
|
+ |
|
+ default: |
|
+ rpmlog(RPMLOG_ERR, "liblzma: <Unknown error (%d), possibly a bug", ret); |
|
+ break; |
|
+ } |
|
fclose(fp); |
|
free(lzfile); |
|
return 0;
|
|
|