From a17b2544947fe6842b298e3da8d4565095e58c3b Mon Sep 17 00:00:00 2001 From: tarsin Date: Sun, 7 Aug 2022 15:23:32 +0800 Subject: [PATCH] Call mmap/munmap in native code --- app/src/main/cpp/archive.c | 38 +++++++++++++------ .../java/com/hippo/UriArchiveAccessor.java | 10 +---- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/src/main/cpp/archive.c b/app/src/main/cpp/archive.c index 556269a94..714738554 100644 --- a/app/src/main/cpp/archive.c +++ b/app/src/main/cpp/archive.c @@ -17,15 +17,17 @@ * EhViewer. If not, see . */ -#include +#include #include #include +#include +#include + +#include #include + #include #include -#include -#include -#include #define LOG_TAG "libarchive_wrapper" #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG ,__VA_ARGS__) @@ -98,11 +100,14 @@ static int archive_alloc() { } JNIEXPORT jint JNICALL -Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *_, jobject thiz, jlong addr, jlong size) { - archiveAddr = (void *) addr; +Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *_, jobject thiz, jint fd, jlong size) { + archiveAddr = mmap64(0, size, PROT_READ, MAP_PRIVATE, fd, 0); + if (archiveAddr == MAP_FAILED) { + LOGE("%s%d", "mmap64 failed with errno ", errno); + return 0; + } archiveSize = size; env = _; - madvise(archiveAddr, archiveSize, MADV_SEQUENTIAL | MADV_WILLNEED); long r = archive_alloc(); if (r) { r = 0; @@ -121,7 +126,18 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *_, jobject thiz, jlong add default: need_encrypt = false; } - LOGI("%s%d", "archive_read_has_encrypted_entries returns ", encryptRet); + + // madvise for readahead optimization + int format = archive_format(arc); + switch (format) { + case ARCHIVE_FORMAT_ZIP: + case ARCHIVE_FORMAT_RAR: + case ARCHIVE_FORMAT_RAR_V5: + madvise(archiveAddr, archiveSize, MADV_SEQUENTIAL | MADV_WILLNEED); + break; + default: + ; + } } archive_release(); return r; @@ -145,7 +161,7 @@ Java_com_hippo_UriArchiveAccessor_extracttoOutputStream(JNIEnv *_, jobject thiz, if (!filename_is_playable_file(archive_entry_pathname(entry))) continue; if (cur_index++ == index) { - memarea->size = archive_entry_size(entry); + memarea->size = (long) archive_entry_size(entry); memarea->buffer = malloc(memarea->size); ret = archive_read_data(arc, memarea->buffer, memarea->size); if (ret != memarea->size) @@ -162,6 +178,7 @@ JNIEXPORT void JNICALL Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *jniEnv, jobject thiz) { archive_release(); free(passwd); + munmap(archiveAddr, archiveSize); } JNIEXPORT jboolean JNICALL @@ -179,17 +196,16 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *_, jobject thiz, jstri passwd = calloc(len, sizeof(char)); strcpy(passwd, (*env)->GetStringUTFChars(env, str, NULL)); archive_alloc(); + void *tmpBuf = alloca(4096); while (archive_read_next_header(arc, &entry) == ARCHIVE_OK) { if (!filename_is_playable_file(archive_entry_pathname(entry))) continue; if (!archive_entry_is_encrypted(entry)) continue; - void *tmpBuf = malloc(4096); if (archive_read_data(arc, tmpBuf, 4096) < ARCHIVE_OK) { LOGE("%s%s", "Archive read failed:", archive_error_string(arc)); ret = false; } - free(tmpBuf); break; } archive_release(); diff --git a/app/src/main/java/com/hippo/UriArchiveAccessor.java b/app/src/main/java/com/hippo/UriArchiveAccessor.java index 92f6ca849..d913922e4 100644 --- a/app/src/main/java/com/hippo/UriArchiveAccessor.java +++ b/app/src/main/java/com/hippo/UriArchiveAccessor.java @@ -28,8 +28,6 @@ import java.io.FileDescriptor; public class UriArchiveAccessor { ParcelFileDescriptor pfd; - FileDescriptor fd; - long archiveAddr; Context ctx; Uri uri; @@ -40,12 +38,10 @@ public class UriArchiveAccessor { public int open() throws Exception { pfd = ctx.getContentResolver().openFileDescriptor(uri, "r"); - fd = pfd.getFileDescriptor(); - archiveAddr = Os.mmap(0, pfd.getStatSize(), OsConstants.PROT_READ, OsConstants.MAP_PRIVATE, fd, 0); - return openArchive(archiveAddr, pfd.getStatSize()); + return openArchive(pfd.getFd(), pfd.getStatSize()); } - private native int openArchive(long addr, long size); + private native int openArchive(int fd, long size); public native long extracttoOutputStream(int index); @@ -57,8 +53,6 @@ public class UriArchiveAccessor { public void close() throws Exception { closeArchive(); - Os.munmap(archiveAddr, pfd.getStatSize()); - Os.close(fd); pfd.close(); } }