mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Queued buffering for downloads.
This commit is contained in:
parent
b5d7b90c0e
commit
c5d7464679
2
Makefile
2
Makefile
|
|
@ -39,7 +39,7 @@ INCLUDES := include ./Libraries/FsLib/Switch/FsLib/include ./Libraries/SDLLib/SD
|
|||
EXEFS_SRC := exefs_src
|
||||
APP_TITLE := JKSV
|
||||
APP_AUTHOR := JK
|
||||
APP_VERSION := 09.13.2025
|
||||
APP_VERSION := 09.21.2025
|
||||
ROMFS := romfs
|
||||
ICON := icon.jpg
|
||||
|
||||
|
|
|
|||
|
|
@ -3,21 +3,13 @@
|
|||
#include "sys/sys.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <semaphore>
|
||||
#include <vector>
|
||||
|
||||
namespace curl
|
||||
{
|
||||
inline constexpr size_t SHARED_BUFFER_SIZE = 0x500000;
|
||||
|
||||
// This is for synchronizing the buffer.
|
||||
enum class BufferState
|
||||
{
|
||||
Empty,
|
||||
Full
|
||||
};
|
||||
using DownloadPair = std::pair<std::unique_ptr<sys::Byte[]>, ssize_t>;
|
||||
|
||||
// clang-format off
|
||||
struct DownloadStruct : sys::threadpool::DataStruct
|
||||
|
|
@ -25,14 +17,8 @@ namespace curl
|
|||
/// @brief Buffer mutex.
|
||||
std::mutex lock{};
|
||||
|
||||
/// @brief Conditional for when the buffer is full.
|
||||
std::condition_variable condition{};
|
||||
|
||||
/// @brief Shared buffer that is read into.
|
||||
std::vector<sys::Byte> sharedBuffer{};
|
||||
|
||||
/// @brief Bool to signal when the buffer is ready/empty.
|
||||
BufferState bufferState{};
|
||||
/// @brief Queue of buffers to write.
|
||||
std::queue<DownloadPair> bufferQueue{};
|
||||
|
||||
/// @brief Destination file to write to.
|
||||
fslib::File *dest{};
|
||||
|
|
@ -40,9 +26,6 @@ namespace curl
|
|||
/// @brief Optional. Task to update with progress.
|
||||
sys::ProgressTask *task{};
|
||||
|
||||
/// @brief Current offset in the file.
|
||||
size_t offset{};
|
||||
|
||||
/// @brief Size of the file being downloaded.
|
||||
int64_t fileSize{};
|
||||
|
||||
|
|
@ -59,7 +42,6 @@ namespace curl
|
|||
downloadStruct->dest = &dest;
|
||||
downloadStruct->task = task;
|
||||
downloadStruct->fileSize = fileSize;
|
||||
downloadStruct->sharedBuffer.reserve(SHARED_BUFFER_SIZE);
|
||||
return downloadStruct;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace
|
|||
/// @brief Build month.
|
||||
constexpr uint8_t BUILD_MON = 9;
|
||||
/// @brief Build day.
|
||||
constexpr uint8_t BUILD_DAY = 13;
|
||||
constexpr uint8_t BUILD_DAY = 21;
|
||||
/// @brief Year.
|
||||
constexpr uint16_t BUILD_YEAR = 2025;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "logging/logger.hpp"
|
||||
#include "stringutil.hpp"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
|
|
@ -67,33 +68,19 @@ size_t curl::write_data_to_file(const char *buffer, size_t size, size_t count, f
|
|||
|
||||
size_t curl::download_file_threaded(const char *buffer, size_t size, size_t count, curl::DownloadStruct *download)
|
||||
{
|
||||
std::mutex &lock = download->lock;
|
||||
std::condition_variable &condition = download->condition;
|
||||
auto &sharedBuffer = download->sharedBuffer;
|
||||
curl::BufferState &bufferState = download->bufferState;
|
||||
sys::ProgressTask *task = download->task;
|
||||
size_t &offset = download->offset;
|
||||
int64_t fileSize = download->fileSize;
|
||||
std::mutex &lock = download->lock;
|
||||
auto &bufferQueue = download->bufferQueue;
|
||||
|
||||
const size_t downloadSize = size * count;
|
||||
auto chunkBuffer = std::make_unique<sys::Byte[]>(downloadSize);
|
||||
std::copy(buffer, buffer + downloadSize, chunkBuffer.get());
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> bufferLock{lock};
|
||||
condition.wait(bufferLock, [&]() { return bufferState == curl::BufferState::Empty; });
|
||||
|
||||
sharedBuffer.insert(sharedBuffer.end(), buffer, buffer + downloadSize);
|
||||
|
||||
const int64_t nextOffset = offset + downloadSize;
|
||||
if (sharedBuffer.size() >= SIZE_DOWNLOAD_THRESHOLD || nextOffset >= fileSize)
|
||||
{
|
||||
bufferState = curl::BufferState::Full;
|
||||
condition.notify_one();
|
||||
}
|
||||
offset += downloadSize;
|
||||
std::lock_guard queueGuard{lock};
|
||||
auto queuePair = std::make_pair(std::move(chunkBuffer), downloadSize);
|
||||
bufferQueue.push(std::move(queuePair));
|
||||
}
|
||||
|
||||
if (task) { task->increase_current(static_cast<double>(downloadSize)); }
|
||||
|
||||
return downloadSize;
|
||||
}
|
||||
|
||||
|
|
@ -101,33 +88,31 @@ void curl::download_write_thread_function(sys::threadpool::JobData jobData)
|
|||
{
|
||||
auto castData = std::static_pointer_cast<curl::DownloadStruct>(jobData);
|
||||
|
||||
std::mutex &lock = castData->lock;
|
||||
std::condition_variable &condition = castData->condition;
|
||||
auto &sharedBuffer = castData->sharedBuffer;
|
||||
curl::BufferState &bufferState = castData->bufferState;
|
||||
fslib::File &dest = *castData->dest;
|
||||
int64_t fileSize = castData->fileSize;
|
||||
auto &writeComplete = castData->writeComplete;
|
||||
|
||||
std::vector<sys::Byte> localBuffer{};
|
||||
localBuffer.reserve(curl::SHARED_BUFFER_SIZE);
|
||||
std::mutex &lock = castData->lock;
|
||||
auto &bufferQueue = castData->bufferQueue;
|
||||
fslib::File &dest = *castData->dest;
|
||||
sys::ProgressTask *task = castData->task;
|
||||
int64_t fileSize = castData->fileSize;
|
||||
auto &writeComplete = castData->writeComplete;
|
||||
|
||||
for (int64_t i = 0; i < fileSize;)
|
||||
{
|
||||
curl::DownloadPair downloadPair{};
|
||||
{
|
||||
std::unique_lock<std::mutex> bufferLock{lock};
|
||||
condition.wait(bufferLock, [&]() { return bufferState == curl::BufferState::Full; });
|
||||
std::lock_guard queueGuard{lock};
|
||||
if (bufferQueue.empty()) { continue; }
|
||||
|
||||
// Copy and reset the offset.
|
||||
localBuffer.assign_range(sharedBuffer);
|
||||
sharedBuffer.clear();
|
||||
|
||||
bufferState = curl::BufferState::Empty;
|
||||
condition.notify_one();
|
||||
downloadPair = std::move(bufferQueue.front());
|
||||
bufferQueue.pop();
|
||||
}
|
||||
|
||||
dest.write(localBuffer.data(), localBuffer.size());
|
||||
i += localBuffer.size();
|
||||
auto &[chunkBuffer, bufferSize] = downloadPair;
|
||||
|
||||
dest.write(chunkBuffer.get(), bufferSize);
|
||||
|
||||
i += bufferSize;
|
||||
|
||||
if (task) { task->update_current(static_cast<double>(i)); }
|
||||
}
|
||||
|
||||
writeComplete.release();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "sys/sys.hpp"
|
||||
#include "ui/PopMessageManager.hpp"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user