aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/AsyncImageLoader.hpp5
-rw-r--r--include/AsyncTask.hpp4
-rw-r--r--src/AsyncImageLoader.cpp66
3 files changed, 39 insertions, 36 deletions
diff --git a/include/AsyncImageLoader.hpp b/include/AsyncImageLoader.hpp
index 23c2889..c482a3a 100644
--- a/include/AsyncImageLoader.hpp
+++ b/include/AsyncImageLoader.hpp
@@ -41,6 +41,7 @@ namespace QuickMedia {
// One example of why you might not want a symlink is if |thumbnail_path| is a temporary file.
bool create_thumbnail(const Path &thumbnail_path, const Path &thumbnail_path_resized, mgl::vec2i resize_target_size, ContentType content_type, bool symlink_if_no_resize);
+ constexpr int NUM_IMAGE_DOWNLOAD_PARALLEL = 4;
constexpr int NUM_IMAGE_LOAD_PARALLEL = 4;
class AsyncImageLoader {
@@ -85,8 +86,8 @@ namespace QuickMedia {
private:
std::mutex download_mutex;
// TODO: Use curl single-threaded multi-download feature instead
- Download downloads[NUM_IMAGE_LOAD_PARALLEL];
- AsyncTask<void> load_thread;
+ Download downloads[NUM_IMAGE_DOWNLOAD_PARALLEL];
+ AsyncTask<void> load_threads[NUM_IMAGE_LOAD_PARALLEL];
MessageQueue<ThumbnailLoadData> image_thumbnail_create_queue;
std::unordered_map<std::string, std::shared_ptr<ThumbnailData>> thumbnails;
size_t counter = 0;
diff --git a/include/AsyncTask.hpp b/include/AsyncTask.hpp
index e256dc7..358e06a 100644
--- a/include/AsyncTask.hpp
+++ b/include/AsyncTask.hpp
@@ -20,14 +20,14 @@ namespace QuickMedia {
thread = std::thread(&AsyncTask::thread_handler, this, std::move(promise), std::move(callback_func), std::forward<Args>(args)...);
}
- AsyncTask(AsyncTask &&other) {
+ AsyncTask(AsyncTask &&other) noexcept {
cancel();
std::lock_guard<std::mutex> lock(mutex);
thread = std::move(other.thread);
future = std::move(other.future);
}
- AsyncTask& operator=(AsyncTask &&other) {
+ AsyncTask& operator=(AsyncTask &&other) noexcept {
cancel();
std::lock_guard<std::mutex> lock(mutex);
thread = std::move(other.thread);
diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp
index e6d0b52..b0efb05 100644
--- a/src/AsyncImageLoader.cpp
+++ b/src/AsyncImageLoader.cpp
@@ -247,47 +247,29 @@ namespace QuickMedia {
}
AsyncImageLoader::AsyncImageLoader() {
- for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) {
+ for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) {
downloads[i].read_program.pid = -1;
downloads[i].read_program.read_fd = -1;
}
- load_thread = AsyncTask<void>([this]() mutable {
- std::optional<ThumbnailLoadData> thumbnail_load_data_opt;
- while(image_thumbnail_create_queue.is_running()) {
- thumbnail_load_data_opt = image_thumbnail_create_queue.pop_if_available();
- if(thumbnail_load_data_opt) {
+ for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) {
+ load_threads[i] = AsyncTask<void>([this]() mutable {
+ std::optional<ThumbnailLoadData> thumbnail_load_data_opt;
+ while(image_thumbnail_create_queue.is_running()) {
+ thumbnail_load_data_opt = image_thumbnail_create_queue.pop_wait();
+ if(!thumbnail_load_data_opt)
+ break;
+
// TODO: Do this multithreaded because creating thumbnails is pretty slow single-threaded,
// especially video thumbnails.
process_thumbnail(thumbnail_load_data_opt.value());
if(thumbnail_load_data_opt.value().thumbnail_data->loading_state == LoadingState::READY_TO_LOAD)
load_processed_thumbnail(thumbnail_load_data_opt.value());
- thumbnail_load_data_opt = std::nullopt;
- }
- for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) {
- Download &download = downloads[i];
- if(download.read_program.pid == -1)
- continue;
-
- int status = 0;
- if(wait_program_non_blocking(download.read_program.pid, &status)) {
- Path tmp_thumbnail_path = download.thumbnail_path;
- tmp_thumbnail_path.append(".tmp");
- if(status == 0 && rename_atomic(tmp_thumbnail_path.data.c_str(), download.thumbnail_path.data.c_str()) == 0) {
- fprintf(stderr, "Download duration for %s: %ld ms\n", download.url.c_str(), get_boottime_milliseconds() - download.download_start);
- ThumbnailLoadData load_data = { std::move(download.url), std::move(download.thumbnail_path), false, download.thumbnail_data, download.resize_target_size };
- image_thumbnail_create_queue.push(std::move(load_data));
- } else {
- fprintf(stderr, "Thumbnail download failed for %s\n", download.url.c_str());
- }
- reset_download(download);
- }
+ thumbnail_load_data_opt = std::nullopt;
}
-
- std::this_thread::sleep_for(std::chrono::milliseconds(2));
- }
- });
+ });
+ }
}
AsyncImageLoader::~AsyncImageLoader() {
@@ -376,11 +358,31 @@ namespace QuickMedia {
}
void AsyncImageLoader::update() {
+ for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) {
+ Download &download = downloads[i];
+ if(download.read_program.pid == -1)
+ continue;
+
+ int status = 0;
+ if(wait_program_non_blocking(download.read_program.pid, &status)) {
+ Path tmp_thumbnail_path = download.thumbnail_path;
+ tmp_thumbnail_path.append(".tmp");
+ if(status == 0 && rename_atomic(tmp_thumbnail_path.data.c_str(), download.thumbnail_path.data.c_str()) == 0) {
+ fprintf(stderr, "Download duration for %s: %ld ms\n", download.url.c_str(), get_boottime_milliseconds() - download.download_start);
+ ThumbnailLoadData load_data = { std::move(download.url), std::move(download.thumbnail_path), false, download.thumbnail_data, download.resize_target_size };
+ image_thumbnail_create_queue.push(std::move(load_data));
+ } else {
+ fprintf(stderr, "Thumbnail download failed for %s\n", download.url.c_str());
+ }
+ reset_download(download);
+ }
+ }
+
bool loaded_textures_changed = false;
for(auto it = thumbnails.begin(); it != thumbnails.end();) {
if(it->second->counter != counter) {
{
- for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) {
+ for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) {
Download &download = downloads[i];
if(download.read_program.pid == -1)
continue;
@@ -409,7 +411,7 @@ namespace QuickMedia {
}
int AsyncImageLoader::get_free_load_index() const {
- for(int i = 0; i < NUM_IMAGE_LOAD_PARALLEL; ++i) {
+ for(int i = 0; i < NUM_IMAGE_DOWNLOAD_PARALLEL; ++i) {
if(downloads[i].read_program.pid == -1)
return i;
}