This commit is contained in:
		| @@ -23,6 +23,7 @@ | ||||
| #define INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_ | ||||
|  | ||||
| #include "utils/single_thread_service_base.hpp" | ||||
| #include <memory> | ||||
|  | ||||
| namespace repertory { | ||||
| class directory_iterator; | ||||
| @@ -33,7 +34,7 @@ public: | ||||
|  | ||||
| private: | ||||
|   struct open_directory { | ||||
|     directory_iterator *iterator{nullptr}; | ||||
|     std::shared_ptr<directory_iterator> 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<directory_iterator>; | ||||
|  | ||||
|   [[nodiscard]] auto remove_directory(const std::string &api_path) | ||||
|       -> directory_iterator *; | ||||
|       -> std::shared_ptr<directory_iterator>; | ||||
|  | ||||
|   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<directory_iterator> iterator); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
|   | ||||
| @@ -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<directory_iterator> { | ||||
|   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<directory_iterator> { | ||||
|   std::shared_ptr<directory_iterator> 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<directory_iterator> iterator) { | ||||
|   recur_mutex_lock directory_lock(directory_mutex_); | ||||
|   directory_lookup_[api_path] = {iterator}; | ||||
|   directory_lookup_[api_path] = {std::move(iterator)}; | ||||
| } | ||||
| } // namespace repertory | ||||
|   | ||||
| @@ -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<std::uint64_t>(iter); | ||||
|   auto iter = std::make_shared<directory_iterator>(std::move(list)); | ||||
|   file_info->fh = reinterpret_cast<std::uint64_t>(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<directory_iterator *>(file_info->fh); | ||||
|   auto iter = directory_cache_->get_directory( | ||||
|       reinterpret_cast<directory_iterator *>(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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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<directory_iterator>(std::move(list)); | ||||
|  | ||||
|     directory_cache_.set_directory(path, iterator); | ||||
|  | ||||
|     handle = reinterpret_cast<remote::file_handle>(iterator); | ||||
|     handle = reinterpret_cast<remote::file_handle>(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<directory_iterator *>(handle); | ||||
|   directory_cache_.remove_directory(iterator); | ||||
|   directory_cache_.remove_directory( | ||||
|       reinterpret_cast<directory_iterator *>(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<directory_iterator>(std::move(list)); | ||||
|     directory_cache_.set_directory(api_path, iterator); | ||||
|  | ||||
|     json_data["handle"] = reinterpret_cast<remote::file_handle>(iterator); | ||||
|     json_data["handle"] = reinterpret_cast<remote::file_handle>(iterator.get()); | ||||
|     json_data["path"] = path; | ||||
|     json_data["page_count"] = utils::divide_with_ceiling( | ||||
|         iterator->get_count(), REPERTORY_DIRECTORY_PAGE_SIZE); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user