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