From d89f35775e0c92d8b3085bcf8ec5874f4872c5a1 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 26 Jul 2024 16:54:01 -0500 Subject: [PATCH] fix crash --- .../include/drives/directory_cache.hpp | 11 +++++-- .../src/drives/directory_cache.cpp | 29 +++++++++++++++---- .../src/drives/fuse/fuse_drive.cpp | 13 ++++----- .../drives/fuse/remotefuse/remote_server.cpp | 15 +++++----- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/repertory/librepertory/include/drives/directory_cache.hpp b/repertory/librepertory/include/drives/directory_cache.hpp index 77e2d3a2..fee5409b 100644 --- a/repertory/librepertory/include/drives/directory_cache.hpp +++ b/repertory/librepertory/include/drives/directory_cache.hpp @@ -23,6 +23,7 @@ #define INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_ #include "utils/single_thread_service_base.hpp" +#include namespace repertory { class directory_iterator; @@ -33,7 +34,7 @@ public: private: struct open_directory { - directory_iterator *iterator{nullptr}; + std::shared_ptr iterator{}; std::chrono::system_clock::time_point last_update{ std::chrono::system_clock::now()}; }; @@ -59,12 +60,16 @@ public: void execute_action(const std::string &api_path, const execute_callback &execute); + [[nodiscard]] auto get_directory(directory_iterator *iterator) + -> std::shared_ptr; + [[nodiscard]] auto remove_directory(const std::string &api_path) - -> directory_iterator *; + -> std::shared_ptr; void remove_directory(directory_iterator *iterator); - void set_directory(const std::string &api_path, directory_iterator *iterator); + void set_directory(const std::string &api_path, + std::shared_ptr iterator); }; } // namespace repertory diff --git a/repertory/librepertory/src/drives/directory_cache.cpp b/repertory/librepertory/src/drives/directory_cache.cpp index d7be5135..4e65b164 100644 --- a/repertory/librepertory/src/drives/directory_cache.cpp +++ b/repertory/librepertory/src/drives/directory_cache.cpp @@ -35,9 +35,26 @@ void directory_cache::execute_action(const std::string &api_path, } } +auto directory_cache::get_directory(directory_iterator *iterator) + -> std::shared_ptr { + if (iterator) { + recur_mutex_lock directory_lock(directory_mutex_); + const auto it = + std::find_if(directory_lookup_.begin(), directory_lookup_.end(), + [&iterator](const auto &kv) -> bool { + return kv.second.iterator.get() == iterator; + }); + if (it != directory_lookup_.end()) { + return it->second.iterator; + } + } + + return nullptr; +} + auto directory_cache::remove_directory(const std::string &api_path) - -> directory_iterator * { - directory_iterator *ret = nullptr; + -> std::shared_ptr { + std::shared_ptr ret; recur_mutex_lock directory_lock(directory_mutex_); if (directory_lookup_.find(api_path) != directory_lookup_.end()) { @@ -54,7 +71,7 @@ void directory_cache::remove_directory(directory_iterator *iterator) { const auto it = std::find_if(directory_lookup_.begin(), directory_lookup_.end(), [&iterator](const auto &kv) -> bool { - return kv.second.iterator == iterator; + return kv.second.iterator.get() == iterator; }); if (it != directory_lookup_.end()) { directory_lookup_.erase(it->first); @@ -84,9 +101,9 @@ void directory_cache::service_function() { } } -void directory_cache::set_directory(const std::string &api_path, - directory_iterator *iterator) { +void directory_cache::set_directory( + const std::string &api_path, std::shared_ptr iterator) { recur_mutex_lock directory_lock(directory_mutex_); - directory_lookup_[api_path] = {iterator}; + directory_lookup_[api_path] = {std::move(iterator)}; } } // namespace repertory diff --git a/repertory/librepertory/src/drives/fuse/fuse_drive.cpp b/repertory/librepertory/src/drives/fuse/fuse_drive.cpp index 74291a21..a50907b6 100644 --- a/repertory/librepertory/src/drives/fuse/fuse_drive.cpp +++ b/repertory/librepertory/src/drives/fuse/fuse_drive.cpp @@ -668,8 +668,8 @@ auto fuse_drive::opendir_impl(std::string api_path, return res; } - auto *iter = new directory_iterator(std::move(list)); - file_info->fh = reinterpret_cast(iter); + auto iter = std::make_shared(std::move(list)); + file_info->fh = reinterpret_cast(iter.get()); directory_cache_->set_directory(api_path, iter); return api_error::success; @@ -716,7 +716,8 @@ auto fuse_drive::readdir_impl(std::string api_path, void *buf, return res; } - auto *iter = reinterpret_cast(file_info->fh); + auto iter = directory_cache_->get_directory( + reinterpret_cast(file_info->fh)); if (iter == nullptr) { return api_error::invalid_handle; } @@ -756,8 +757,6 @@ auto fuse_drive::releasedir_impl( } directory_cache_->remove_directory(iter); - delete iter; - return api_error::success; } @@ -820,9 +819,7 @@ auto fuse_drive::rmdir_impl(std::string api_path) -> api_error { return res; } - auto *iter = directory_cache_->remove_directory(api_path); - delete iter; - + auto iter = directory_cache_->remove_directory(api_path); return api_error::success; } diff --git a/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp b/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp index ccd44aac..bbd20aaf 100644 --- a/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp +++ b/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp @@ -619,11 +619,11 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle) if (utils::file::is_directory(file_path)) { auto list = drive_.get_directory_items(utils::path::create_api_path(path)); - auto *iterator = new directory_iterator(std::move(list)); + auto iterator = std::make_shared(std::move(list)); directory_cache_.set_directory(path, iterator); - handle = reinterpret_cast(iterator); + handle = reinterpret_cast(iterator.get()); res = 0; errno = 0; } @@ -720,8 +720,8 @@ auto remote_server::fuse_releasedir( const auto file_path = construct_path(path); - auto *iterator = reinterpret_cast(handle); - directory_cache_.remove_directory(iterator); + directory_cache_.remove_directory( + reinterpret_cast(handle)); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0); return 0; @@ -743,7 +743,7 @@ auto remote_server::fuse_rmdir(const char *path) -> packet::error_type { const auto file_path = construct_path(path); const auto res = rmdir(file_path.c_str()); if (res == 0) { - auto *iterator = + auto iterator = directory_cache_.remove_directory(utils::path::create_api_path(path)); if (iterator == nullptr) { utils::error::raise_error( @@ -1567,11 +1567,10 @@ auto remote_server::json_create_directory_snapshot( if (utils::file::is_directory(file_path)) { auto list = drive_.get_directory_items(api_path); - auto *iterator = new directory_iterator(std::move(list)); - + auto iterator = std::make_shared(std::move(list)); directory_cache_.set_directory(api_path, iterator); - json_data["handle"] = reinterpret_cast(iterator); + json_data["handle"] = reinterpret_cast(iterator.get()); json_data["path"] = path; json_data["page_count"] = utils::divide_with_ceiling( iterator->get_count(), REPERTORY_DIRECTORY_PAGE_SIZE);