From 45e03ecab7d71bbe42fa1c79773bdfc260537639 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 11 Jul 2020 15:05:34 +0200 Subject: Use atomic rename instead of .finished lock files --- include/Storage.hpp | 1 - src/DownloadUtils.cpp | 14 ++++++++++---- src/ImageViewer.cpp | 3 +-- src/QuickMedia.cpp | 18 ++++++++++-------- src/Storage.cpp | 7 ------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/include/Storage.hpp b/include/Storage.hpp index 362448f..39af8e6 100644 --- a/include/Storage.hpp +++ b/include/Storage.hpp @@ -21,7 +21,6 @@ namespace QuickMedia { FileType get_file_type(const Path &path); int file_get_content(const Path &path, std::string &result); int file_overwrite(const Path &path, const std::string &data); - int create_lock_file(const Path &path); void for_files_in_dir(const Path &path, FileIteratorCallback callback); void for_files_in_dir_sort_last_modified(const Path &path, FileIteratorCallback callback); } \ No newline at end of file diff --git a/src/DownloadUtils.cpp b/src/DownloadUtils.cpp index e02fa6b..cb87890 100644 --- a/src/DownloadUtils.cpp +++ b/src/DownloadUtils.cpp @@ -49,9 +49,10 @@ namespace QuickMedia { DownloadResult download_to_string_cache(const std::string &url, std::string &result, const std::vector &additional_args, bool use_tor, bool use_browser_useragent) { Path media_dir = get_cache_dir().join("media"); Path media_file_path = Path(media_dir).join(cppcodec::base64_rfc4648::encode(url)); - Path media_finished_path(media_file_path.data + ".finished"); - if(get_file_type(media_finished_path) != FileType::FILE_NOT_FOUND && get_file_type(media_file_path) == FileType::REGULAR) { + Path media_file_path_tmp(media_file_path.data + ".tmp"); + if(get_file_type(media_file_path) == FileType::REGULAR) { if(file_get_content(media_file_path, result) == 0) { + fprintf(stderr, "Loaded %s from cache\n", url.c_str()); return DownloadResult::OK; } else { fprintf(stderr, "Failed to get content of cached media file: %s\n", media_file_path.data.c_str()); @@ -60,8 +61,13 @@ namespace QuickMedia { } else { DownloadResult download_result = download_to_string(url, result, additional_args, use_tor, use_browser_useragent); if(download_result == DownloadResult::OK) { - if(create_directory_recursive(media_dir) == 0 && file_overwrite(media_file_path, result) == 0) { - create_lock_file(media_finished_path); + if(create_directory_recursive(media_dir) == 0 && file_overwrite(media_file_path_tmp, result) == 0) { + if(rename(media_file_path_tmp.data.c_str(), media_file_path.data.c_str()) != 0) { + perror("rename"); + download_result = DownloadResult::ERR; + } + } else { + download_result = DownloadResult::ERR; } } return download_result; diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp index 102d73a..574bf94 100644 --- a/src/ImageViewer.cpp +++ b/src/ImageViewer.cpp @@ -87,8 +87,7 @@ namespace QuickMedia { image_path.join(page_str); // TODO: Make image loading asynchronous - Path image_finished_path(image_path.data + ".finished"); - if(get_file_type(image_finished_path) != FileType::FILE_NOT_FOUND && get_file_type(image_path) == FileType::REGULAR) { + if(get_file_type(image_path) == FileType::REGULAR) { fprintf(stderr, "ImageViewer: Load page %d\n", 1 + page); page_image_data = std::make_unique(); page_image_data->visible_on_screen = true; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 6cf6875..8a01dc6 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1135,8 +1135,7 @@ namespace QuickMedia { Path image_path = content_cache_dir; image_path.join(std::to_string(image_index + 1)); - Path image_finished_path(image_path.data + ".finished"); - if(get_file_type(image_finished_path) != FileType::FILE_NOT_FOUND && get_file_type(image_path) == FileType::REGULAR) { + if(get_file_type(image_path) == FileType::REGULAR) { std::string image_data; if(file_get_content(image_path, image_data) == 0) { if(image_texture.loadFromMemory(image_data.data(), image_data.size())) { @@ -1192,8 +1191,7 @@ namespace QuickMedia { Path image_filepath = content_cache_dir_; image_filepath.join(std::to_string(page++)); - Path lockfile_path(image_filepath.data + ".finished"); - if(get_file_type(lockfile_path) != FileType::FILE_NOT_FOUND) + if(get_file_type(image_filepath) != FileType::FILE_NOT_FOUND) return true; std::string image_content; @@ -1223,15 +1221,19 @@ namespace QuickMedia { } } - if(file_overwrite(image_filepath, image_content) != 0) { - show_notification("Storage", "Failed to save image to file: " + image_filepath.data, Urgency::CRITICAL); + Path image_filepath_tmp(image_filepath.data + ".tmp"); + + if(file_overwrite(image_filepath_tmp, image_content) != 0) { + show_notification("Storage", "Failed to save image to file: " + image_filepath_tmp.data, Urgency::CRITICAL); return false; } - if(create_lock_file(lockfile_path) != 0) { - show_notification("Storage", "Failed to save image finished state to file: " + lockfile_path.data, Urgency::CRITICAL); + if(rename(image_filepath_tmp.data.c_str(), image_filepath.data.c_str()) != 0) { + perror("rename"); + show_notification("Storage", "Failed to save image to file: " + image_filepath_tmp.data, Urgency::CRITICAL); return false; } + return true; }); }); diff --git a/src/Storage.cpp b/src/Storage.cpp index 745ecfc..7d2b9ca 100644 --- a/src/Storage.cpp +++ b/src/Storage.cpp @@ -122,13 +122,6 @@ namespace QuickMedia { return fclose(file); } - int create_lock_file(const Path &path) { - int fd = open(path.data.c_str(), O_CREAT | O_EXCL); - if(fd == -1) - return errno; - return close(fd); - } - void for_files_in_dir(const Path &path, FileIteratorCallback callback) { for(auto &p : std::filesystem::directory_iterator(path.data)) { if(!callback(p.path())) -- cgit v1.2.3