aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-10-18 06:54:18 +0200
committerdec05eba <dec05eba@protonmail.com>2020-10-18 06:54:18 +0200
commitf5dc7e2c85436877606af46a011c2fba112185a9 (patch)
tree04dfdc46a1faf7b3187e284a45075260d3f25e02
parent7e1a950a0be2871045e0dda6ba2adc892d323464 (diff)
Fix potential crash in thumbnail loader: 2
-rw-r--r--include/AsyncImageLoader.hpp6
-rw-r--r--src/AsyncImageLoader.cpp24
-rw-r--r--src/QuickMedia.cpp1
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);