From 7dbd2cecd86f4e3ecbac4163dbdebd2a9b547a22 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 8 Apr 2018 08:14:07 -0700 Subject: [PATCH] Android: Avoid pread64 for > 2GB offsets. Appears to not actually work as advertised. See #10862. --- Core/FileLoaders/LocalFileLoader.cpp | 14 ++++++++++++-- Core/FileLoaders/LocalFileLoader.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index d720bf61cf..389f47d652 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -37,7 +37,7 @@ LocalFileLoader::LocalFileLoader(const std::string &filename) if (fd_ == -1) { return; } -#if defined(__ANDROID__) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64) +#if PPSSPP_PLATFORM(ANDROID) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64) off64_t off = lseek64(fd_, 0, SEEK_END); filesize_ = off; lseek64(fd_, 0, SEEK_SET); @@ -112,7 +112,17 @@ std::string LocalFileLoader::Path() const { } size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) { -#ifndef _WIN32 +#if PPSSPP_PLATFORM(ANDROID) + // pread64 doesn't appear to actually be 64-bit safe, though such ISOs are uncommon. See #10862. + if (absolutePos <= 0x7FFFFFFF) { + return pread64(fd_, data, bytes * count, absolutePos) / bytes; + } else { + // Since pread64 doesn't change the file offset, it should be safe to avoid the lock in the common case. + std::lock_guard guard(readLock_); + lseek64(fd_, absolutePos, SEEK_SET); + return read(fd_, data, bytes * count) / bytes; + } +#elif !defined(_WIN32) #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64 return pread64(fd_, data, bytes * count, absolutePos) / bytes; #else diff --git a/Core/FileLoaders/LocalFileLoader.h b/Core/FileLoaders/LocalFileLoader.h index d5203656ea..bb5910494f 100644 --- a/Core/FileLoaders/LocalFileLoader.h +++ b/Core/FileLoaders/LocalFileLoader.h @@ -17,6 +17,7 @@ #pragma once +#include #include "Common/CommonTypes.h" #include "Core/Loaders.h" #ifdef _WIN32 @@ -42,4 +43,5 @@ private: #endif u64 filesize_; std::string filename_; + std::mutex readLock_; };