Improve open files tracking implementation

This commit is contained in:
Maschell 2022-04-27 19:42:25 +02:00
parent 0785f08953
commit d1774b8015
4 changed files with 68 additions and 48 deletions

View File

@ -1,20 +1,17 @@
#include "FileUtils.h"
#include "utils/FileReader.h"
#include "utils/FileReaderCompressed.h"
#include "utils/utils.h"
#include <map>
#include <mutex>
#include <wuhb_utils/utils.h>
#include <wums/exports.h>
std::vector<FileReader *> openFiles;
std::forward_list<std::unique_ptr<FileReader>> openFiles;
std::map<std::string, std::string> mountedWUHB;
std::mutex mutex;
void WUHBUtils_CleanUp() {
std::lock_guard<std::mutex> lock(mutex);
for (auto &file : openFiles) {
delete file;
}
openFiles.clear();
for (const auto &[name, path] : mountedWUHB) {
@ -69,22 +66,24 @@ WUHBUtilsApiErrorType WUU_FileOpen(const char *name, uint32_t *outHandle) {
return WUHB_UTILS_API_ERROR_INVALID_ARG;
}
std::lock_guard<std::mutex> lock(mutex);
FileReader *reader;
std::unique_ptr<FileReader> reader;
std::string path = std::string(name);
std::string pathGZ = path + ".gz";
if (CheckFile(path.c_str())) {
reader = new (std::nothrow) FileReader(path);
reader = make_unique_nothrow<FileReader>(path);
} else if (CheckFile(pathGZ.c_str())) {
reader = new (std::nothrow) FileReaderCompressed(pathGZ);
reader = make_unique_nothrow<FileReaderCompressed>(pathGZ);
} else {
return WUHB_UTILS_API_ERROR_FILE_NOT_FOUND;
}
if (reader == nullptr) {
if (!reader || !reader->isReady()) {
return WUHB_UTILS_API_ERROR_NO_MEMORY;
}
openFiles.push_back(reader);
*outHandle = (uint32_t) reader;
*outHandle = reader->getHandle();
openFiles.push_front(std::move(reader));
return WUHB_UTILS_API_ERROR_NONE;
}
@ -93,43 +92,22 @@ WUHBUtilsApiErrorType WUU_FileRead(uint32_t handle, uint8_t *buffer, uint32_t si
return WUHB_UTILS_API_ERROR_INVALID_ARG;
}
std::lock_guard<std::mutex> lock(mutex);
auto found = false;
FileReader *reader;
for (auto &cur : openFiles) {
if ((uint32_t) cur == handle) {
found = true;
reader = cur;
break;
}
}
if (!found) {
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
}
for (auto &reader : openFiles) {
if ((uint32_t) reader.get() == (uint32_t) handle) {
*outRes = (int32_t) reader->read(buffer, size);
return WUHB_UTILS_API_ERROR_NONE;
}
}
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
}
WUHBUtilsApiErrorType WUU_FileClose(uint32_t handle) {
std::lock_guard<std::mutex> lock(mutex);
auto count = 0;
auto found = false;
FileReader *reader;
for (auto &cur : openFiles) {
if ((uint32_t) cur == handle) {
found = true;
reader = cur;
break;
}
count++;
}
if (!found) {
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
}
openFiles.erase(openFiles.begin() + count);
delete reader;
if (remove_locked_first_if(mutex, openFiles, [handle](auto &cur) { return cur->getHandle() == handle; })) {
return WUHB_UTILS_API_ERROR_NONE;
}
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
}
WUHBUtilsApiErrorType WUU_FileExists(const char *name, int32_t *outRes) {

View File

@ -24,6 +24,14 @@ int64_t FileReader::read(uint8_t *buffer, uint32_t size) {
return -2;
}
FileReader::FileReader(uint8_t *buffer, uint32_t size) {
this->input_buffer = buffer;
this->input_size = size;
this->input_pos = 0;
this->isReadFromBuffer = true;
this->isReadFromFile = false;
}
FileReader::FileReader(std::string &path) {
int fd;
if ((fd = open(path.c_str(), O_RDONLY)) >= 0) {
@ -41,10 +49,7 @@ FileReader::~FileReader() {
}
}
FileReader::FileReader(uint8_t *buffer, uint32_t size) {
this->input_buffer = buffer;
this->input_size = size;
this->input_pos = 0;
this->isReadFromBuffer = true;
this->isReadFromFile = false;
bool FileReader::isReady() {
return this->isReadFromFile || this->isReadFromBuffer;
}

View File

@ -17,6 +17,12 @@ public:
virtual int64_t read(uint8_t *buffer, uint32_t size);
virtual bool isReady();
virtual uint32_t getHandle() {
return reinterpret_cast<uint32_t>(this);
}
private:
bool isReadFromBuffer = false;
uint8_t *input_buffer = nullptr;

31
src/utils/utils.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <cstdint>
#include <forward_list>
#include <malloc.h>
#include <memory>
#include <mutex>
template<class T, class... Args>
std::unique_ptr<T> make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}
template<class T, class... Args>
std::shared_ptr<T> make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}
template<typename T, class Allocator, class Predicate>
bool remove_locked_first_if(std::mutex &mutex, std::forward_list<T, Allocator> &list, Predicate pred) {
std::lock_guard<std::mutex> lock(mutex);
auto oit = list.before_begin(), it = std::next(oit);
while (it != list.end()) {
if (pred(*it)) {
list.erase_after(oit);
return true;
}
oit = it++;
}
return false;
}