diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-10-18 06:54:18 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-10-18 06:54:18 +0200 |
commit | f5dc7e2c85436877606af46a011c2fba112185a9 (patch) | |
tree | 04dfdc46a1faf7b3187e284a45075260d3f25e02 | |
parent | 7e1a950a0be2871045e0dda6ba2adc892d323464 (diff) |
Fix potential crash in thumbnail loader: 2
-rw-r--r-- | include/AsyncImageLoader.hpp | 6 | ||||
-rw-r--r-- | src/AsyncImageLoader.cpp | 24 | ||||
-rw-r--r-- | src/QuickMedia.cpp | 1 |
3 files changed, 10 insertions, 21 deletions
diff --git a/include/AsyncImageLoader.hpp b/include/AsyncImageLoader.hpp index fe8d52a..fa32971 100644 --- a/include/AsyncImageLoader.hpp +++ b/include/AsyncImageLoader.hpp @@ -4,7 +4,7 @@ #include <SFML/System/Vector2.hpp> #include <SFML/Graphics/Texture.hpp> #include <memory> -#include <future> +#include <thread> namespace QuickMedia { enum class LoadingState { @@ -23,15 +23,13 @@ namespace QuickMedia { class AsyncImageLoader { public: - ~AsyncImageLoader(); // Returns false if the image loader is already loading an image. In that case, this function should be called again later. // set |resize_target_size| to {0, 0} to disable resizing. // |thumbnail_data.loading_state| has to be LoadingState::NOT_LOADED when calling this! // Note: this method is not thread-safe bool load_thumbnail(const std::string &url, bool local, sf::Vector2i resize_target_size, bool use_tor, std::shared_ptr<ThumbnailData> thumbnail_data); - void update(); private: bool loading_image = false; - std::future<void> load_image_future; + std::thread load_image_thread; }; }
\ No newline at end of file diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp index fb864c2..8f771e7 100644 --- a/src/AsyncImageLoader.cpp +++ b/src/AsyncImageLoader.cpp @@ -70,16 +70,8 @@ namespace QuickMedia { return ""; } - // TODO: Remove and use std::thread and detach instead of std::async - AsyncImageLoader::~AsyncImageLoader() { - if(load_image_future.valid()) - load_image_future.get(); - } - // TODO: Run in 5 different threads, and add download_to_file(_cache) to reduce memory usage in each (use -O curl option) bool AsyncImageLoader::load_thumbnail(const std::string &url, bool local, sf::Vector2i resize_target_size, bool use_tor, std::shared_ptr<ThumbnailData> thumbnail_data) { - update(); - if(loading_image) return false; @@ -95,7 +87,8 @@ namespace QuickMedia { return true; } - load_image_future = std::async(std::launch::async, [url, local, resize_target_size, thumbnail_data, use_tor]() mutable { + // TODO: Keep the thread running and use conditional variable instead to sleep until a new image should be loaded. Same in ImageViewer. + load_image_thread = std::thread([this, url, local, resize_target_size, thumbnail_data, use_tor]() mutable { // TODO: Use sha256 instead of base64_url encoding Path thumbnail_path = get_cache_dir().join("thumbnails").join(base64_url::encode(url)); @@ -103,17 +96,20 @@ namespace QuickMedia { if(thumbnail_data->image->loadFromFile(thumbnail_path.data)) { fprintf(stderr, "Loaded %s from thumbnail cache\n", url.c_str()); thumbnail_data->loading_state = LoadingState::FINISHED_LOADING; + loading_image = false; return; } else { if(local) { if(!thumbnail_data->image->loadFromFile(url)) { thumbnail_data->loading_state = LoadingState::FINISHED_LOADING; + loading_image = false; return; } } else { std::string texture_data; if(download_to_string_cache(url, texture_data, {}, use_tor, true) != DownloadResult::OK || !thumbnail_data->image->loadFromMemory(texture_data.data(), texture_data.size())) { thumbnail_data->loading_state = LoadingState::FINISHED_LOADING; + loading_image = false; return; } } @@ -127,21 +123,17 @@ namespace QuickMedia { thumbnail_data->image = std::move(destination_image); save_image_as_thumbnail_atomic(*thumbnail_data->image, thumbnail_path, get_ext(url)); thumbnail_data->loading_state = LoadingState::FINISHED_LOADING; + loading_image = false; return; } } thumbnail_data->loading_state = LoadingState::FINISHED_LOADING; + loading_image = false; return; }); + load_image_thread.detach(); return true; } - - void AsyncImageLoader::update() { - if(loading_image && load_image_future.valid() && load_image_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { - load_image_future.get(); - loading_image = false; - } - } }
\ No newline at end of file diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 13f7db9..070b8fe 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3742,7 +3742,6 @@ namespace QuickMedia { ++it; } - async_image_loader.update(); if(current_room_body_data && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED) async_image_loader.load_thumbnail(current_room_body_data->body_item->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data); |