From daa8b9df24b4fd8241b39032e350d2a00aa9930e Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 21 Jan 2025 13:18:22 -0600 Subject: [PATCH] refactor system stop --- cmake/versions.cmake | 12 +- repertory/librepertory/include/app_config.hpp | 40 +-- .../include/comm/curl/curl_comm.hpp | 10 +- .../include/comm/curl/multi_request.hpp | 3 + .../librepertory/include/db/i_file_db.hpp | 5 +- .../librepertory/include/db/i_meta_db.hpp | 2 +- .../include/db/impl/rdb_file_db.hpp | 4 +- .../include/db/impl/rdb_meta_db.hpp | 2 +- .../include/db/impl/sqlite_file_db.hpp | 4 +- .../include/db/impl/sqlite_meta_db.hpp | 2 +- .../include/drives/fuse/fuse_drive.hpp | 242 +++++++++--------- .../include/drives/winfsp/winfsp_drive.hpp | 3 + .../include/file_manager/cache_size_mgr.hpp | 3 + .../include/file_manager/file_manager.hpp | 16 +- .../include/file_manager/open_file.hpp | 16 +- .../include/file_manager/open_file_base.hpp | 14 +- .../include/file_manager/ring_buffer_base.hpp | 23 +- .../librepertory/include/utils/polling.hpp | 2 + .../utils/single_thread_service_base.hpp | 6 +- .../librepertory/include/utils/tasks.hpp | 2 + repertory/librepertory/src/app_config.cpp | 6 + .../librepertory/src/comm/curl/curl_comm.cpp | 6 +- .../src/comm/curl/multi_request.cpp | 9 +- .../librepertory/src/db/impl/rdb_file_db.cpp | 12 +- .../librepertory/src/db/impl/rdb_meta_db.cpp | 5 +- .../src/db/impl/sqlite_file_db.cpp | 8 +- .../src/db/impl/sqlite_meta_db.cpp | 4 +- .../src/drives/fuse/fuse_drive.cpp | 75 +++--- .../src/drives/winfsp/winfsp_drive.cpp | 105 ++++---- .../src/file_manager/cache_size_mgr.cpp | 6 +- .../src/file_manager/file_manager.cpp | 8 +- .../src/file_manager/open_file.cpp | 22 +- .../src/file_manager/open_file_base.cpp | 4 +- .../src/file_manager/ring_buffer_base.cpp | 17 +- .../src/providers/base_provider.cpp | 75 ++++-- .../providers/encrypt/encrypt_provider.cpp | 81 +++--- .../src/providers/s3/s3_provider.cpp | 9 +- .../src/providers/sia/sia_provider.cpp | 3 +- repertory/librepertory/src/utils/polling.cpp | 8 +- .../src/utils/single_thread_service_base.cpp | 7 +- repertory/librepertory/src/utils/tasks.cpp | 14 +- repertory/repertory_test/src/file_db_test.cpp | 14 +- support/include/utils/config.hpp | 1 + support/include/utils/encrypting_reader.hpp | 12 +- support/src/utils/encrypting_reader.cpp | 41 +-- .../test/src/utils/encrypting_reader_test.cpp | 16 +- support/test/src/utils/encryption_test.cpp | 11 +- 47 files changed, 583 insertions(+), 407 deletions(-) diff --git a/cmake/versions.cmake b/cmake/versions.cmake index 2a121d97..4eddf7f5 100644 --- a/cmake/versions.cmake +++ b/cmake/versions.cmake @@ -1,15 +1,15 @@ set(BINUTILS_VERSION 2.43) -set(BOOST2_MAJOR_VERSION 1) -set(BOOST2_MINOR_VERSION 76) -set(BOOST2_PATCH_VERSION 0) set(BOOST_MAJOR_VERSION 1) set(BOOST_MINOR_VERSION 87) set(BOOST_PATCH_VERSION 0) +set(BOOST2_MAJOR_VERSION 1) +set(BOOST2_MINOR_VERSION 76) +set(BOOST2_PATCH_VERSION 0) set(CPP_HTTPLIB_VERSION 0.18.1) -set(CURL2_VERSION 8_11_0) set(CURL_VERSION 8.11.0) -set(EXPAT2_VERSION 2_6_4) +set(CURL2_VERSION 8_11_0) set(EXPAT_VERSION 2.6.4) +set(EXPAT2_VERSION 2_6_4) set(GCC_VERSION 14.2.0) set(GTEST_VERSION 1.15.2) set(ICU_VERSION 76-1) @@ -22,7 +22,7 @@ set(PKG_CONFIG_VERSION 0.29.2) set(PUGIXML_VERSION 1.14) set(ROCKSDB_VERSION 9.7.4) set(SPDLOG_VERSION 1.15.0) -set(SQLITE2_VERSION 3.46.1) set(SQLITE_VERSION 3460100) +set(SQLITE2_VERSION 3.46.1) set(STDUUID_VERSION 1.2.3) set(ZLIB_VERSION 1.3.1) diff --git a/repertory/librepertory/include/app_config.hpp b/repertory/librepertory/include/app_config.hpp index 40391eed..0f03e477 100644 --- a/repertory/librepertory/include/app_config.hpp +++ b/repertory/librepertory/include/app_config.hpp @@ -28,27 +28,35 @@ namespace repertory { class app_config final { +private: + static stop_type stop_requested; + public: - [[nodiscard]] static auto - default_agent_name(const provider_type &prov) -> std::string; + [[nodiscard]] static auto default_agent_name(const provider_type &prov) + -> std::string; - [[nodiscard]] static auto - default_api_port(const provider_type &prov) -> std::uint16_t; + [[nodiscard]] static auto default_api_port(const provider_type &prov) + -> std::uint16_t; - [[nodiscard]] static auto - default_data_directory(const provider_type &prov) -> std::string; + [[nodiscard]] static auto default_data_directory(const provider_type &prov) + -> std::string; - [[nodiscard]] static auto - default_remote_api_port(const provider_type &prov) -> std::uint16_t; + [[nodiscard]] static auto default_remote_api_port(const provider_type &prov) + -> std::uint16_t; - [[nodiscard]] static auto - default_rpc_port(const provider_type &prov) -> std::uint16_t; + [[nodiscard]] static auto default_rpc_port(const provider_type &prov) + -> std::uint16_t; - [[nodiscard]] static auto - get_provider_display_name(const provider_type &prov) -> std::string; + [[nodiscard]] static auto get_provider_display_name(const provider_type &prov) + -> std::string; - [[nodiscard]] static auto - get_provider_name(const provider_type &prov) -> std::string; + [[nodiscard]] static auto get_provider_name(const provider_type &prov) + -> std::string; + +public: + [[nodiscard]] static auto get_stop_requested() -> bool; + + static void set_stop_requested(); public: app_config(const provider_type &prov, std::string_view data_directory = ""); @@ -185,8 +193,8 @@ public: [[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t; - [[nodiscard]] auto - get_value_by_name(const std::string &name) const -> std::string; + [[nodiscard]] auto get_value_by_name(const std::string &name) const + -> std::string; [[nodiscard]] auto get_version() const -> std::uint64_t; diff --git a/repertory/librepertory/include/comm/curl/curl_comm.hpp b/repertory/librepertory/include/comm/curl/curl_comm.hpp index 6275918e..a6d9f23c 100644 --- a/repertory/librepertory/include/comm/curl/curl_comm.hpp +++ b/repertory/librepertory/include/comm/curl/curl_comm.hpp @@ -22,6 +22,7 @@ #ifndef REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_ #define REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_ +#include "app_config.hpp" #include "comm/curl/multi_request.hpp" #include "comm/i_http_comm.hpp" #include "events/event_system.hpp" @@ -42,7 +43,7 @@ private: struct read_write_info final { data_buffer data{}; - stop_type &stop_requested; + stop_type_callback stop_requested_cb; }; static const write_callback write_data; @@ -170,7 +171,12 @@ public: curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_headers); } - read_write_info write_info{{}, stop_requested}; + read_write_info write_info{ + {}, + [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }, + }; if (request.response_handler.has_value()) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_info); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); diff --git a/repertory/librepertory/include/comm/curl/multi_request.hpp b/repertory/librepertory/include/comm/curl/multi_request.hpp index a6d5437b..a294ce8b 100644 --- a/repertory/librepertory/include/comm/curl/multi_request.hpp +++ b/repertory/librepertory/include/comm/curl/multi_request.hpp @@ -36,6 +36,9 @@ private: stop_type &stop_requested_; CURLM *multi_handle_; +private: + [[nodiscard]] auto get_stop_requested() const -> bool; + public: void get_result(CURLcode &curl_code, long &http_code); }; diff --git a/repertory/librepertory/include/db/i_file_db.hpp b/repertory/librepertory/include/db/i_file_db.hpp index f26d6d19..ae05c3a3 100644 --- a/repertory/librepertory/include/db/i_file_db.hpp +++ b/repertory/librepertory/include/db/i_file_db.hpp @@ -58,7 +58,7 @@ public: virtual void enumerate_item_list( std::function &)> callback, - stop_type &stop_requested) const = 0; + stop_type_callback stop_requested_cb) const = 0; [[nodiscard]] virtual auto get_api_path(const std::string &source_path, std::string &api_path) const @@ -84,7 +84,8 @@ public: get_file_source_path(const std::string &api_path, std::string &source_path) const -> api_error = 0; - [[nodiscard]] virtual auto get_item_list(stop_type &stop_requested) const + [[nodiscard]] virtual auto + get_item_list(stop_type_callback stop_requested_cb) const -> std::vector = 0; [[nodiscard]] virtual auto get_source_path(const std::string &api_path, diff --git a/repertory/librepertory/include/db/i_meta_db.hpp b/repertory/librepertory/include/db/i_meta_db.hpp index 7379577d..a1a0d467 100644 --- a/repertory/librepertory/include/db/i_meta_db.hpp +++ b/repertory/librepertory/include/db/i_meta_db.hpp @@ -33,7 +33,7 @@ public: virtual void enumerate_api_path_list( std::function &)> callback, - stop_type &stop_requested) const = 0; + stop_type_callback stop_requested_cb) const = 0; [[nodiscard]] virtual auto get_api_path(const std::string &source_path, std::string &api_path) const diff --git a/repertory/librepertory/include/db/impl/rdb_file_db.hpp b/repertory/librepertory/include/db/impl/rdb_file_db.hpp index 0050099f..902c777d 100644 --- a/repertory/librepertory/include/db/impl/rdb_file_db.hpp +++ b/repertory/librepertory/include/db/impl/rdb_file_db.hpp @@ -80,7 +80,7 @@ public: void enumerate_item_list( std::function &)> callback, - stop_type &stop_requested) const override; + stop_type_callback stop_requested_cb) const override; [[nodiscard]] auto get_api_path(const std::string &source_path, std::string &api_path) const @@ -106,7 +106,7 @@ public: std::string &source_path) const -> api_error override; - [[nodiscard]] auto get_item_list(stop_type &stop_requested) const + [[nodiscard]] auto get_item_list(stop_type_callback stop_requested_cb) const -> std::vector override; [[nodiscard]] auto get_source_path(const std::string &api_path, diff --git a/repertory/librepertory/include/db/impl/rdb_meta_db.hpp b/repertory/librepertory/include/db/impl/rdb_meta_db.hpp index b18696cf..b235f779 100644 --- a/repertory/librepertory/include/db/impl/rdb_meta_db.hpp +++ b/repertory/librepertory/include/db/impl/rdb_meta_db.hpp @@ -82,7 +82,7 @@ public: void enumerate_api_path_list( std::function &)> callback, - stop_type &stop_requested) const override; + stop_type_callback stop_requested_cb) const override; [[nodiscard]] auto get_api_path(const std::string &source_path, std::string &api_path) const diff --git a/repertory/librepertory/include/db/impl/sqlite_file_db.hpp b/repertory/librepertory/include/db/impl/sqlite_file_db.hpp index 44dfb202..4a9a7d82 100644 --- a/repertory/librepertory/include/db/impl/sqlite_file_db.hpp +++ b/repertory/librepertory/include/db/impl/sqlite_file_db.hpp @@ -55,7 +55,7 @@ public: void enumerate_item_list( std::function &)> callback, - stop_type &stop_requested) const override; + stop_type_callback stop_requested_cb) const override; [[nodiscard]] auto get_api_path(const std::string &source_path, std::string &api_path) const @@ -81,7 +81,7 @@ public: std::string &source_path) const -> api_error override; - [[nodiscard]] auto get_item_list(stop_type &stop_requested) const + [[nodiscard]] auto get_item_list(stop_type_callback stop_requested_cb) const -> std::vector override; [[nodiscard]] auto get_source_path(const std::string &api_path, diff --git a/repertory/librepertory/include/db/impl/sqlite_meta_db.hpp b/repertory/librepertory/include/db/impl/sqlite_meta_db.hpp index 4857ce8b..c1f7691d 100644 --- a/repertory/librepertory/include/db/impl/sqlite_meta_db.hpp +++ b/repertory/librepertory/include/db/impl/sqlite_meta_db.hpp @@ -52,7 +52,7 @@ public: void enumerate_api_path_list( std::function &)> callback, - stop_type &stop_requested) const override; + stop_type_callback stop_requested_cb) const override; [[nodiscard]] auto get_api_path(const std::string &source_path, std::string &api_path) const diff --git a/repertory/librepertory/include/drives/fuse/fuse_drive.hpp b/repertory/librepertory/include/drives/fuse/fuse_drive.hpp index 0bd9ef6a..992bd593 100644 --- a/repertory/librepertory/include/drives/fuse/fuse_drive.hpp +++ b/repertory/librepertory/include/drives/fuse/fuse_drive.hpp @@ -63,99 +63,103 @@ private: std::shared_ptr logging_consumer_; std::shared_ptr remote_server_; std::shared_ptr server_; - bool was_mounted_ = false; + std::mutex stop_all_mtx_; + bool was_mounted_{false}; private: void update_accessed_time(const std::string &api_path); protected: #if defined(__APPLE__) - [[nodiscard]] auto chflags_impl(std::string api_path, - uint32_t flags) -> api_error override; + [[nodiscard]] auto chflags_impl(std::string api_path, uint32_t flags) + -> api_error override; #endif // __APPLE__ #if FUSE_USE_VERSION >= 30 - [[nodiscard]] auto - chmod_impl(std::string api_path, mode_t mode, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode, + struct fuse_file_info *file_info) + -> api_error override; #else - [[nodiscard]] auto chmod_impl(std::string api_path, - mode_t mode) -> api_error override; + [[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode) + -> api_error override; #endif #if FUSE_USE_VERSION >= 30 - [[nodiscard]] auto - chown_impl(std::string api_path, uid_t uid, gid_t gid, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid, + struct fuse_file_info *file_info) + -> api_error override; #else - [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, - gid_t gid) -> api_error override; + [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid) + -> api_error override; #endif - [[nodiscard]] auto - create_impl(std::string api_path, mode_t mode, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto create_impl(std::string api_path, mode_t mode, + struct fuse_file_info *file_info) + -> api_error override; void destroy_impl(void *ptr) override; - [[nodiscard]] auto - fallocate_impl(std::string api_path, int mode, off_t offset, off_t length, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto fallocate_impl(std::string api_path, int mode, + off_t offset, off_t length, + struct fuse_file_info *file_info) + -> api_error override; - [[nodiscard]] auto - fgetattr_impl(std::string api_path, struct stat *unix_st, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *unix_st, + struct fuse_file_info *file_info) + -> api_error override; #if defined(__APPLE__) - [[nodiscard]] auto - fsetattr_x_impl(std::string api_path, struct setattr_x *attr, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto fsetattr_x_impl(std::string api_path, + struct setattr_x *attr, + struct fuse_file_info *file_info) + -> api_error override; #endif // __APPLE__ - [[nodiscard]] auto - fsync_impl(std::string api_path, int datasync, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto fsync_impl(std::string api_path, int datasync, + struct fuse_file_info *file_info) + -> api_error override; #if FUSE_USE_VERSION < 30 - [[nodiscard]] auto - ftruncate_impl(std::string api_path, off_t size, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size, + struct fuse_file_info *file_info) + -> api_error override; #endif #if FUSE_USE_VERSION >= 30 - [[nodiscard]] auto - getattr_impl(std::string api_path, struct stat *unix_st, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto getattr_impl(std::string api_path, struct stat *unix_st, + struct fuse_file_info *file_info) + -> api_error override; #else - [[nodiscard]] auto getattr_impl(std::string api_path, - struct stat *unix_st) -> api_error override; + [[nodiscard]] auto getattr_impl(std::string api_path, struct stat *unix_st) + -> api_error override; #endif #if defined(__APPLE__) - [[nodiscard]] auto - getxtimes_impl(std::string api_path, struct timespec *bkuptime, - struct timespec *crtime) -> api_error override; + [[nodiscard]] auto getxtimes_impl(std::string api_path, + struct timespec *bkuptime, + struct timespec *crtime) + -> api_error override; #endif // __APPLE__ #if FUSE_USE_VERSION >= 30 - auto init_impl(struct fuse_conn_info *conn, - struct fuse_config *cfg) -> void * override; + auto init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg) + -> void * override; #else auto init_impl(struct fuse_conn_info *conn) -> void * override; #endif - [[nodiscard]] auto mkdir_impl(std::string api_path, - mode_t mode) -> api_error override; + [[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode) + -> api_error override; void notify_fuse_main_exit(int &ret) override; - [[nodiscard]] auto - open_impl(std::string api_path, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto open_impl(std::string api_path, + struct fuse_file_info *file_info) + -> api_error override; - [[nodiscard]] auto - opendir_impl(std::string api_path, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto opendir_impl(std::string api_path, + struct fuse_file_info *file_info) + -> api_error override; [[nodiscard]] auto read_impl(std::string api_path, char *buffer, size_t read_size, off_t read_offset, @@ -163,29 +167,30 @@ protected: std::size_t &bytes_read) -> api_error override; #if FUSE_USE_VERSION >= 30 - [[nodiscard]] auto - readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir, - off_t offset, struct fuse_file_info *file_info, - fuse_readdir_flags flags) -> api_error override; + [[nodiscard]] auto readdir_impl(std::string api_path, void *buf, + fuse_fill_dir_t fuse_fill_dir, off_t offset, + struct fuse_file_info *file_info, + fuse_readdir_flags flags) + -> api_error override; #else - [[nodiscard]] auto - readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir, - off_t offset, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto readdir_impl(std::string api_path, void *buf, + fuse_fill_dir_t fuse_fill_dir, off_t offset, + struct fuse_file_info *file_info) + -> api_error override; #endif - [[nodiscard]] auto - release_impl(std::string api_path, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto release_impl(std::string api_path, + struct fuse_file_info *file_info) + -> api_error override; - [[nodiscard]] auto - releasedir_impl(std::string api_path, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto releasedir_impl(std::string api_path, + struct fuse_file_info *file_info) + -> api_error override; #if FUSE_USE_VERSION >= 30 [[nodiscard]] auto rename_impl(std::string from_api_path, - std::string to_api_path, - unsigned int flags) -> api_error override; + std::string to_api_path, unsigned int flags) + -> api_error override; #else [[nodiscard]] auto rename_impl(std::string from_api_path, std::string to_api_path) -> api_error override; @@ -196,8 +201,8 @@ protected: #if defined(HAS_SETXATTR) [[nodiscard]] auto getxattr_common(std::string api_path, const char *name, char *value, size_t size, - int &attribute_size, - uint32_t *position) -> api_error; + int &attribute_size, uint32_t *position) + -> api_error; #if defined(__APPLE__) [[nodiscard]] auto getxattr_impl(std::string api_path, const char *name, @@ -213,8 +218,8 @@ protected: size_t size, int &required_size, bool &return_size) -> api_error override; - [[nodiscard]] auto removexattr_impl(std::string api_path, - const char *name) -> api_error override; + [[nodiscard]] auto removexattr_impl(std::string api_path, const char *name) + -> api_error override; #if defined(__APPLE__) [[nodiscard]] auto setxattr_impl(std::string api_path, const char *name, @@ -222,62 +227,64 @@ protected: uint32_t position) -> api_error override; #else // __APPLE__ [[nodiscard]] auto setxattr_impl(std::string api_path, const char *name, - const char *value, size_t size, - int flags) -> api_error override; + const char *value, size_t size, int flags) + -> api_error override; #endif // __APPLE__ #endif // HAS_SETXATTR #if defined(__APPLE__) - [[nodiscard]] auto - setattr_x_impl(std::string api_path, - struct setattr_x *attr) -> api_error override; + [[nodiscard]] auto setattr_x_impl(std::string api_path, + struct setattr_x *attr) + -> api_error override; - [[nodiscard]] auto - setbkuptime_impl(std::string api_path, - const struct timespec *bkuptime) -> api_error override; + [[nodiscard]] auto setbkuptime_impl(std::string api_path, + const struct timespec *bkuptime) + -> api_error override; - [[nodiscard]] auto - setchgtime_impl(std::string api_path, - const struct timespec *chgtime) -> api_error override; + [[nodiscard]] auto setchgtime_impl(std::string api_path, + const struct timespec *chgtime) + -> api_error override; - [[nodiscard]] auto - setcrtime_impl(std::string api_path, - const struct timespec *crtime) -> api_error override; + [[nodiscard]] auto setcrtime_impl(std::string api_path, + const struct timespec *crtime) + -> api_error override; [[nodiscard]] auto setvolname_impl(const char *volname) -> api_error override; - [[nodiscard]] auto statfs_x_impl(std::string api_path, - struct statfs *stbuf) -> api_error override; + [[nodiscard]] auto statfs_x_impl(std::string api_path, struct statfs *stbuf) + -> api_error override; #else // __APPLE__ - [[nodiscard]] auto statfs_impl(std::string api_path, - struct statvfs *stbuf) -> api_error override; + [[nodiscard]] auto statfs_impl(std::string api_path, struct statvfs *stbuf) + -> api_error override; #endif // __APPLE__ #if FUSE_USE_VERSION >= 30 - [[nodiscard]] auto - truncate_impl(std::string api_path, off_t size, - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto truncate_impl(std::string api_path, off_t size, + struct fuse_file_info *file_info) + -> api_error override; #else - [[nodiscard]] auto truncate_impl(std::string api_path, - off_t size) -> api_error override; + [[nodiscard]] auto truncate_impl(std::string api_path, off_t size) + -> api_error override; #endif [[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override; #if FUSE_USE_VERSION >= 30 - [[nodiscard]] auto - utimens_impl(std::string api_path, const struct timespec tv[2], - struct fuse_file_info *file_info) -> api_error override; + [[nodiscard]] auto utimens_impl(std::string api_path, + const struct timespec tv[2], + struct fuse_file_info *file_info) + -> api_error override; #else - [[nodiscard]] auto - utimens_impl(std::string api_path, - const struct timespec tv[2]) -> api_error override; + [[nodiscard]] auto utimens_impl(std::string api_path, + const struct timespec tv[2]) + -> api_error override; #endif - [[nodiscard]] auto - write_impl(std::string api_path, const char *buffer, size_t write_size, - off_t write_offset, struct fuse_file_info *file_info, - std::size_t &bytes_written) -> api_error override; + [[nodiscard]] auto write_impl(std::string api_path, const char *buffer, + size_t write_size, off_t write_offset, + struct fuse_file_info *file_info, + std::size_t &bytes_written) + -> api_error override; public: [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const @@ -286,16 +293,17 @@ public: [[nodiscard]] auto get_directory_items(const std::string &api_path) const -> directory_item_list override; - [[nodiscard]] auto - get_file_size(const std::string &api_path) const -> std::uint64_t override; + [[nodiscard]] auto get_file_size(const std::string &api_path) const + -> std::uint64_t override; - [[nodiscard]] auto - get_item_meta(const std::string &api_path, - api_meta_map &meta) const -> api_error override; + [[nodiscard]] auto get_item_meta(const std::string &api_path, + api_meta_map &meta) const + -> api_error override; - [[nodiscard]] auto - get_item_meta(const std::string &api_path, const std::string &name, - std::string &value) const -> api_error override; + [[nodiscard]] auto get_item_meta(const std::string &api_path, + const std::string &name, + std::string &value) const + -> api_error override; [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; @@ -306,16 +314,16 @@ public: void get_volume_info(UINT64 &total_size, UINT64 &free_size, std::string &volume_label) const override; - [[nodiscard]] auto - is_processing(const std::string &api_path) const -> bool override; + [[nodiscard]] auto is_processing(const std::string &api_path) const + -> bool override; - [[nodiscard]] auto - rename_directory(const std::string &from_api_path, - const std::string &to_api_path) -> int override; + [[nodiscard]] auto rename_directory(const std::string &from_api_path, + const std::string &to_api_path) + -> int override; [[nodiscard]] auto rename_file(const std::string &from_api_path, - const std::string &to_api_path, - bool overwrite) -> int override; + const std::string &to_api_path, bool overwrite) + -> int override; void set_item_meta(const std::string &api_path, const std::string &key, const std::string &value) override; diff --git a/repertory/librepertory/include/drives/winfsp/winfsp_drive.hpp b/repertory/librepertory/include/drives/winfsp/winfsp_drive.hpp index eb044041..4609f40d 100644 --- a/repertory/librepertory/include/drives/winfsp/winfsp_drive.hpp +++ b/repertory/librepertory/include/drives/winfsp/winfsp_drive.hpp @@ -73,6 +73,7 @@ private: std::unique_ptr fm_; std::unique_ptr eviction_; std::unique_ptr remote_server_; + std::mutex stop_all_mtx_; private: [[nodiscard]] auto handle_error(std::string_view function_name, @@ -94,6 +95,8 @@ private: static void set_file_info(remote::file_info &dest, const FSP_FSCTL_FILE_INFO &src); + void stop_all(); + public: auto CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) -> NTSTATUS override; diff --git a/repertory/librepertory/include/file_manager/cache_size_mgr.hpp b/repertory/librepertory/include/file_manager/cache_size_mgr.hpp index 074868b4..1959f1bb 100644 --- a/repertory/librepertory/include/file_manager/cache_size_mgr.hpp +++ b/repertory/librepertory/include/file_manager/cache_size_mgr.hpp @@ -49,6 +49,9 @@ private: std::condition_variable notify_; stop_type stop_requested_{false}; +private: + [[nodiscard]] auto get_stop_requested() const -> bool; + public: [[nodiscard]] auto expand(std::uint64_t size) -> api_error; diff --git a/repertory/librepertory/include/file_manager/file_manager.hpp b/repertory/librepertory/include/file_manager/file_manager.hpp index 04b2ff83..728b0e36 100644 --- a/repertory/librepertory/include/file_manager/file_manager.hpp +++ b/repertory/librepertory/include/file_manager/file_manager.hpp @@ -72,15 +72,19 @@ private: void close_timed_out_files(); - auto get_open_file_by_handle(std::uint64_t handle) const + [[nodiscard]] auto get_open_file_by_handle(std::uint64_t handle) const -> std::shared_ptr; - auto get_open_file_count(const std::string &api_path) const -> std::size_t; + [[nodiscard]] auto get_open_file_count(const std::string &api_path) const + -> std::size_t; - auto open(const std::string &api_path, bool directory, - const open_file_data &ofd, std::uint64_t &handle, - std::shared_ptr &file, - std::shared_ptr closeable_file) -> api_error; + [[nodiscard]] auto get_stop_requested() const -> bool; + + [[nodiscard]] auto open(const std::string &api_path, bool directory, + const open_file_data &ofd, std::uint64_t &handle, + std::shared_ptr &file, + std::shared_ptr closeable_file) + -> api_error; void queue_upload(const std::string &api_path, const std::string &source_path, bool no_lock); diff --git a/repertory/librepertory/include/file_manager/open_file.hpp b/repertory/librepertory/include/file_manager/open_file.hpp index 48bc8268..eaf75c4b 100644 --- a/repertory/librepertory/include/file_manager/open_file.hpp +++ b/repertory/librepertory/include/file_manager/open_file.hpp @@ -78,8 +78,8 @@ private: stop_type stop_requested_{false}; private: - [[nodiscard]] auto adjust_cache_size(std::uint64_t file_size, - bool shrink) -> api_error; + [[nodiscard]] auto adjust_cache_size(std::uint64_t file_size, bool shrink) + -> api_error; [[nodiscard]] auto check_start() -> api_error; @@ -88,6 +88,8 @@ private: void download_range(std::size_t begin_chunk, std::size_t end_chunk, bool should_reset); + [[nodiscard]] auto get_stop_requested() const -> bool; + void set_modified(); void set_read_state(std::size_t chunk); @@ -111,12 +113,12 @@ public: return true; } - [[nodiscard]] auto - native_operation(native_operation_callback callback) -> api_error override; + [[nodiscard]] auto native_operation(native_operation_callback callback) + -> api_error override; - [[nodiscard]] auto - native_operation(std::uint64_t new_file_size, - native_operation_callback callback) -> api_error override; + [[nodiscard]] auto native_operation(std::uint64_t new_file_size, + native_operation_callback callback) + -> api_error override; void remove(std::uint64_t handle) override; diff --git a/repertory/librepertory/include/file_manager/open_file_base.hpp b/repertory/librepertory/include/file_manager/open_file_base.hpp index 0a522114..df5d15be 100644 --- a/repertory/librepertory/include/file_manager/open_file_base.hpp +++ b/repertory/librepertory/include/file_manager/open_file_base.hpp @@ -161,7 +161,7 @@ protected: void set_source_path(std::string source_path); - void wait_for_io(stop_type &stop_requested); + void wait_for_io(stop_type_callback stop_requested_cb); public: void add(std::uint64_t handle, open_file_data ofd) override; @@ -186,17 +186,17 @@ public: [[nodiscard]] auto get_handles() const -> std::vector override; - [[nodiscard]] auto - get_open_data() -> std::map & override; + [[nodiscard]] auto get_open_data() + -> std::map & override; [[nodiscard]] auto get_open_data() const -> const std::map & override; - [[nodiscard]] auto - get_open_data(std::uint64_t handle) -> open_file_data & override; + [[nodiscard]] auto get_open_data(std::uint64_t handle) + -> open_file_data & override; - [[nodiscard]] auto - get_open_data(std::uint64_t handle) const -> const open_file_data & override; + [[nodiscard]] auto get_open_data(std::uint64_t handle) const + -> const open_file_data & override; [[nodiscard]] auto get_open_file_count() const -> std::size_t override; diff --git a/repertory/librepertory/include/file_manager/ring_buffer_base.hpp b/repertory/librepertory/include/file_manager/ring_buffer_base.hpp index edc32533..863f7a53 100644 --- a/repertory/librepertory/include/file_manager/ring_buffer_base.hpp +++ b/repertory/librepertory/include/file_manager/ring_buffer_base.hpp @@ -44,8 +44,8 @@ public: ring_buffer_base(const ring_buffer_base &) noexcept = delete; ring_buffer_base(ring_buffer_base &&) noexcept = delete; auto operator=(ring_buffer_base &&) noexcept -> ring_buffer_base & = delete; - auto - operator=(const ring_buffer_base &) noexcept -> ring_buffer_base & = delete; + auto operator=(const ring_buffer_base &) noexcept + -> ring_buffer_base & = delete; public: static constexpr const auto min_ring_size{5U}; @@ -73,6 +73,8 @@ private: void update_position(std::size_t count, bool is_forward); + [[nodiscard]] auto get_stop_requested() const -> bool; + protected: [[nodiscard]] auto has_reader_thread() const -> bool { return reader_thread_ != nullptr; @@ -84,9 +86,9 @@ protected: [[nodiscard]] virtual auto on_check_start() -> bool = 0; - [[nodiscard]] virtual auto - on_chunk_downloaded(std::size_t chunk, - const data_buffer &buffer) -> api_error = 0; + [[nodiscard]] virtual auto on_chunk_downloaded(std::size_t chunk, + const data_buffer &buffer) + -> api_error = 0; [[nodiscard]] virtual auto on_read_chunk(std::size_t chunk, std::size_t read_size, @@ -94,8 +96,8 @@ protected: std::size_t &bytes_read) -> api_error = 0; [[nodiscard]] virtual auto - use_buffer(std::size_t chunk, - std::function func) -> api_error = 0; + use_buffer(std::size_t chunk, std::function func) + -> api_error = 0; public: auto close() -> bool override; @@ -139,9 +141,10 @@ public: void set_api_path(const std::string &api_path) override; - [[nodiscard]] auto - write(std::uint64_t /* write_offset */, const data_buffer & /* data */, - std::size_t & /* bytes_written */) -> api_error override { + [[nodiscard]] auto write(std::uint64_t /* write_offset */, + const data_buffer & /* data */, + std::size_t & /* bytes_written */) + -> api_error override { return api_error::not_supported; } }; diff --git a/repertory/librepertory/include/utils/polling.hpp b/repertory/librepertory/include/utils/polling.hpp index fcfd3cd8..8cd1d692 100644 --- a/repertory/librepertory/include/utils/polling.hpp +++ b/repertory/librepertory/include/utils/polling.hpp @@ -75,6 +75,8 @@ private: void frequency_thread(std::function get_frequency_seconds, frequency freq); + [[nodiscard]] auto get_stop_requested() const -> bool; + public: void remove_callback(const std::string &name); diff --git a/repertory/librepertory/include/utils/single_thread_service_base.hpp b/repertory/librepertory/include/utils/single_thread_service_base.hpp index e3d98089..ebf8f696 100644 --- a/repertory/librepertory/include/utils/single_thread_service_base.hpp +++ b/repertory/librepertory/include/utils/single_thread_service_base.hpp @@ -36,7 +36,7 @@ private: const std::string service_name_; mutable std::mutex mtx_; mutable std::condition_variable notify_; - stop_type stop_requested_ = false; + stop_type stop_requested_{false}; std::unique_ptr thread_; protected: @@ -46,9 +46,7 @@ protected: return notify_; } - [[nodiscard]] auto get_stop_requested() const -> bool { - return stop_requested_; - } + [[nodiscard]] auto get_stop_requested() const -> bool; void notify_all() const; diff --git a/repertory/librepertory/include/utils/tasks.hpp b/repertory/librepertory/include/utils/tasks.hpp index d39f5778..390084b1 100644 --- a/repertory/librepertory/include/utils/tasks.hpp +++ b/repertory/librepertory/include/utils/tasks.hpp @@ -104,6 +104,8 @@ private: private: void task_thread(); + [[nodiscard]] auto get_stop_requested() const -> bool; + public: auto schedule(task item) -> task_ptr; diff --git a/repertory/librepertory/src/app_config.cpp b/repertory/librepertory/src/app_config.cpp index bf95139b..8af9f113 100644 --- a/repertory/librepertory/src/app_config.cpp +++ b/repertory/librepertory/src/app_config.cpp @@ -57,6 +57,12 @@ auto get_value(const json &data, const std::string &name, dest &dst, } // namespace namespace repertory { +stop_type app_config::stop_requested{false}; + +auto app_config::get_stop_requested() -> bool { return stop_requested.load(); } + +void app_config::set_stop_requested() { stop_requested.store(true); } + app_config::app_config(const provider_type &prov, std::string_view data_directory) : prov_(prov), diff --git a/repertory/librepertory/src/comm/curl/curl_comm.cpp b/repertory/librepertory/src/comm/curl/curl_comm.cpp index 9fbc5b5a..e4113e8f 100644 --- a/repertory/librepertory/src/comm/curl/curl_comm.cpp +++ b/repertory/librepertory/src/comm/curl/curl_comm.cpp @@ -33,7 +33,7 @@ const curl_comm::write_callback curl_comm::write_data = auto &info = *reinterpret_cast(outstream); std::copy(buffer, buffer + (size * nitems), std::back_inserter(info.data)); - return info.stop_requested ? 0 : size * nitems; + return info.stop_requested_cb() ? 0 : size * nitems; }); const curl_comm::write_callback curl_comm::write_headers = @@ -102,8 +102,8 @@ auto curl_comm::reset_curl(CURL *curl_handle) -> CURL * { return curl_handle; } -auto curl_comm::create_host_config(const s3_config &cfg, - bool use_s3_path_style) -> host_config { +auto curl_comm::create_host_config(const s3_config &cfg, bool use_s3_path_style) + -> host_config { host_config host_cfg{}; host_cfg.api_password = cfg.secret_key; host_cfg.api_user = cfg.access_key; diff --git a/repertory/librepertory/src/comm/curl/multi_request.cpp b/repertory/librepertory/src/comm/curl/multi_request.cpp index ac5bb6de..63efa2d1 100644 --- a/repertory/librepertory/src/comm/curl/multi_request.cpp +++ b/repertory/librepertory/src/comm/curl/multi_request.cpp @@ -21,6 +21,7 @@ */ #include "comm/curl/multi_request.hpp" +#include "app_config.hpp" #include "utils/utils.hpp" namespace repertory { @@ -46,7 +47,7 @@ void multi_request::get_result(CURLcode &curl_code, long &http_code) { auto error = false; int running_handles = 0; curl_multi_perform(multi_handle_, &running_handles); - while (not error && (running_handles > 0) && not stop_requested_) { + while (not error && (running_handles > 0) && not get_stop_requested()) { int ignored{}; curl_multi_wait(multi_handle_, nullptr, 0, timeout_ms, &ignored); @@ -54,7 +55,7 @@ void multi_request::get_result(CURLcode &curl_code, long &http_code) { error = (ret != CURLM_CALL_MULTI_PERFORM) && (ret != CURLM_OK); } - if (not stop_requested_) { + if (not get_stop_requested()) { int remaining_messages = 0; auto *multi_result = curl_multi_info_read(multi_handle_, &remaining_messages); @@ -65,4 +66,8 @@ void multi_request::get_result(CURLcode &curl_code, long &http_code) { } } } + +auto multi_request::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} } // namespace repertory diff --git a/repertory/librepertory/src/db/impl/rdb_file_db.cpp b/repertory/librepertory/src/db/impl/rdb_file_db.cpp index d15094e6..4765f781 100644 --- a/repertory/librepertory/src/db/impl/rdb_file_db.cpp +++ b/repertory/librepertory/src/db/impl/rdb_file_db.cpp @@ -151,11 +151,11 @@ auto rdb_file_db::count() const -> std::uint64_t { void rdb_file_db::enumerate_item_list( std::function &)> callback, - stop_type &stop_requested) const { + stop_type_callback stop_requested_cb) const { std::vector list; { auto iter = create_iterator(file_family_); - for (iter->SeekToFirst(); not stop_requested && iter->Valid(); + for (iter->SeekToFirst(); not stop_requested_cb() && iter->Valid(); iter->Next()) { auto json_data = json::parse(iter->value().ToString()); list.emplace_back(i_file_db::file_info{ @@ -175,7 +175,7 @@ void rdb_file_db::enumerate_item_list( { auto iter = create_iterator(directory_family_); - for (iter->SeekToFirst(); not stop_requested && iter->Valid(); + for (iter->SeekToFirst(); not stop_requested_cb() && iter->Valid(); iter->Next()) { list.emplace_back(i_file_db::file_info{ iter->key().ToString(), @@ -311,12 +311,12 @@ auto rdb_file_db::get_file_source_path(const std::string &api_path, return result; } -auto rdb_file_db::get_item_list(stop_type &stop_requested) const +auto rdb_file_db::get_item_list(stop_type_callback stop_requested_cb) const -> std::vector { std::vector ret{}; { auto iter = create_iterator(directory_family_); - for (iter->SeekToFirst(); not stop_requested && iter->Valid(); + for (iter->SeekToFirst(); not stop_requested_cb() && iter->Valid(); iter->Next()) { ret.emplace_back(i_file_db::file_info{ iter->key().ToString(), @@ -328,7 +328,7 @@ auto rdb_file_db::get_item_list(stop_type &stop_requested) const { auto iter = create_iterator(file_family_); - for (iter->SeekToFirst(); not stop_requested && iter->Valid(); + for (iter->SeekToFirst(); not stop_requested_cb() && iter->Valid(); iter->Next()) { auto json_data = json::parse(iter->value().ToString()); ret.emplace_back(i_file_db::file_info{ diff --git a/repertory/librepertory/src/db/impl/rdb_meta_db.cpp b/repertory/librepertory/src/db/impl/rdb_meta_db.cpp index 3e517ba2..4598f361 100644 --- a/repertory/librepertory/src/db/impl/rdb_meta_db.cpp +++ b/repertory/librepertory/src/db/impl/rdb_meta_db.cpp @@ -66,11 +66,12 @@ auto rdb_meta_db::create_iterator(rocksdb::ColumnFamilyHandle *family) const void rdb_meta_db::enumerate_api_path_list( std::function &)> callback, - stop_type &stop_requested) const { + stop_type_callback stop_requested_cb) const { std::vector list{}; auto iter = create_iterator(meta_family_); - for (iter->SeekToFirst(); not stop_requested && iter->Valid(); iter->Next()) { + for (iter->SeekToFirst(); not stop_requested_cb() && iter->Valid(); + iter->Next()) { list.push_back(iter->key().ToString()); if (list.size() < 100U) { diff --git a/repertory/librepertory/src/db/impl/sqlite_file_db.cpp b/repertory/librepertory/src/db/impl/sqlite_file_db.cpp index e5d52554..b4baecac 100644 --- a/repertory/librepertory/src/db/impl/sqlite_file_db.cpp +++ b/repertory/librepertory/src/db/impl/sqlite_file_db.cpp @@ -135,11 +135,11 @@ auto sqlite_file_db::count() const -> std::uint64_t { void sqlite_file_db::enumerate_item_list( std::function &)> callback, - stop_type &stop_requested) const { + stop_type_callback stop_requested_cb) const { std::vector list; auto result = utils::db::sqlite::db_select{*db_, file_table}.go(); - while (not stop_requested && result.has_row()) { + while (not stop_requested_cb() && result.has_row()) { std::optional row; if (result.get_row(row) && row.has_value()) { list.emplace_back(i_file_db::file_info{ @@ -309,12 +309,12 @@ auto sqlite_file_db::get_file_source_path(const std::string &api_path, return api_error::item_not_found; } -auto sqlite_file_db::get_item_list(stop_type &stop_requested) const +auto sqlite_file_db::get_item_list(stop_type_callback stop_requested_cb) const -> std::vector { std::vector ret; auto result = utils::db::sqlite::db_select{*db_, file_table}.go(); - while (not stop_requested && result.has_row()) { + while (not stop_requested_cb() && result.has_row()) { std::optional row; if (result.get_row(row) && row.has_value()) { ret.emplace_back(i_file_db::file_info{ diff --git a/repertory/librepertory/src/db/impl/sqlite_meta_db.cpp b/repertory/librepertory/src/db/impl/sqlite_meta_db.cpp index 6a66312d..d1ef1918 100644 --- a/repertory/librepertory/src/db/impl/sqlite_meta_db.cpp +++ b/repertory/librepertory/src/db/impl/sqlite_meta_db.cpp @@ -77,12 +77,12 @@ void sqlite_meta_db::clear() { void sqlite_meta_db::enumerate_api_path_list( std::function &)> callback, - stop_type &stop_requested) const { + stop_type_callback stop_requested_cb) const { auto result = utils::db::sqlite::db_select{*db_, table_name}.column("api_path").go(); std::vector list{}; - while (not stop_requested && result.has_row()) { + while (not stop_requested_cb() && result.has_row()) { std::optional row; if (result.get_row(row) && row.has_value()) { list.push_back(row->get_column("api_path").get_value()); diff --git a/repertory/librepertory/src/drives/fuse/fuse_drive.cpp b/repertory/librepertory/src/drives/fuse/fuse_drive.cpp index 54b1a1c9..d8905818 100644 --- a/repertory/librepertory/src/drives/fuse/fuse_drive.cpp +++ b/repertory/librepertory/src/drives/fuse/fuse_drive.cpp @@ -246,47 +246,60 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode, return api_error::success; } +void fuse_drive::stop_all() { + mutex_lock lock(stop_all_mtx_); + + auto future = std::async(std::launch::async, [this]() { + remote_server_.reset(); + + if (server_) { + server_->stop(); + } + + polling::instance().stop(); + + if (eviction_) { + eviction_->stop(); + } + + if (fm_) { + fm_->stop(); + } + + provider_.stop(); + + if (directory_cache_) { + directory_cache_->stop(); + } + + directory_cache_.reset(); + eviction_.reset(); + server_.reset(); + + fm_.reset(); + }); + + if (future.wait_for(30s) == std::future_status::timeout) { + app_config::set_stop_requested(); + future.wait(); + } + + if (not lock_data_.set_mount_state(false, "", -1)) { + utils::error::raise_error(function_name, "failed to set mount state"); + } +} + void fuse_drive::destroy_impl(void *ptr) { REPERTORY_USES_FUNCTION_NAME(); event_system::instance().raise(get_mount_location()); - remote_server_.reset(); - - if (server_) { - server_->stop(); - } - - polling::instance().stop(); - - if (eviction_) { - eviction_->stop(); - } - - if (fm_) { - fm_->stop(); - } - - provider_.stop(); - - if (directory_cache_) { - directory_cache_->stop(); - } - - directory_cache_.reset(); - eviction_.reset(); - server_.reset(); - - fm_.reset(); + stop_all(); event_system::instance().raise(get_mount_location()); config_.save(); - if (not lock_data_.set_mount_state(false, "", -1)) { - utils::error::raise_error(function_name, "failed to set mount state"); - } - fuse_base::destroy_impl(ptr); } diff --git a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp index a8d24319..73f726c2 100644 --- a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp +++ b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp @@ -19,6 +19,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #if defined(_WIN32) #include "drives/winfsp/winfsp_drive.hpp" @@ -121,6 +122,7 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/) utils::error::raise_error(function_name, ret, "failed to set mount state"); } + event_system::instance().raise(mount_location, std::to_string(ret)); } @@ -605,28 +607,30 @@ auto winfsp_drive::mount(const std::vector &drive_args) -> int { event_system::instance().raise(std::to_string(ret)); event_system::instance().stop(); cons.reset(); + return static_cast(ret); } auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS { REPERTORY_USES_FUNCTION_NAME(); - auto ret{STATUS_SUCCESS}; - if (not utils::file::change_to_process_directory()) { - return static_cast(utils::get_last_error_code()); - } - - auto *file_system_host{ - reinterpret_cast(host), - }; - fm_ = std::make_unique(config_, provider_); - server_ = std::make_unique(config_, provider_, *fm_); - if (not provider_.is_read_only()) { - eviction_ = std::make_unique(provider_, config_, *fm_); - } - try { + if (not utils::file::change_to_process_directory()) { + return static_cast(utils::get_last_error_code()); + } + + auto *file_system_host{ + reinterpret_cast(host), + }; + + fm_ = std::make_unique(config_, provider_); + server_ = std::make_unique(config_, provider_, *fm_); + if (not provider_.is_read_only()) { + eviction_ = std::make_unique(provider_, config_, *fm_); + } + server_->start(); + if (not provider_.start( [this](bool directory, api_file &file) -> api_error { return provider_meta_handler(provider_, directory, file); @@ -646,30 +650,21 @@ auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS { config_, *this, mount_location); } + polling::instance().start(&config_); + if (not lock_.set_mount_state(true, mount_location, ::GetCurrentProcessId())) { utils::error::raise_error(function_name, "failed to set mount state"); } - polling::instance().start(&config_); - event_system::instance().raise(mount_location); + return STATUS_SUCCESS; } catch (const std::exception &e) { utils::error::raise_error(function_name, e, "exception occurred"); - if (remote_server_) { - remote_server_.reset(); - } - server_->stop(); - polling::instance().stop(); - if (eviction_) { - eviction_->stop(); - } - fm_->stop(); - provider_.stop(); - ret = STATUS_INTERNAL_ERROR; } - return ret; + stop_all(); + return STATUS_INTERNAL_ERROR; } auto winfsp_drive::Open(PWSTR file_name, UINT32 create_options, @@ -1156,29 +1151,51 @@ auto winfsp_drive::SetFileSize(PVOID /*file_node*/, PVOID file_desc, })); } +void winfsp_drive::stop_all() { + mutex_lock lock(stop_all_mtx_); + + auto future = std::async(std::launch::async, [this]() { + remote_server_.reset(); + + if (server_) { + server_->stop(); + } + + polling::instance().stop(); + + if (eviction_) { + eviction_->stop(); + } + + if (fm_) { + fm_->stop(); + } + + provider_.stop(); + + eviction_.reset(); + fm_.reset(); + server_.reset(); + }); + + if (future.wait_for(30s) == std::future_status::timeout) { + app_config::set_stop_requested(); + future.wait(); + } + + if (not lock_.set_mount_state(false, "", -1)) { + utils::error::raise_error(function_name, "failed to set mount state"); + } +} + VOID winfsp_drive::Unmounted(PVOID host) { REPERTORY_USES_FUNCTION_NAME(); auto *file_system_host = reinterpret_cast(host); auto mount_location = parse_mount_location(file_system_host->MountPoint()); event_system::instance().raise(mount_location); - if (remote_server_) { - remote_server_.reset(); - } - server_->stop(); - polling::instance().stop(); - if (eviction_) { - eviction_->stop(); - } - fm_->stop(); - provider_.stop(); - server_.reset(); - fm_.reset(); - eviction_.reset(); - if (not lock_.set_mount_state(false, "", -1)) { - utils::error::raise_error(function_name, "failed to set mount state"); - } + stop_all(); event_system::instance().raise(mount_location); config_.save(); diff --git a/repertory/librepertory/src/file_manager/cache_size_mgr.cpp b/repertory/librepertory/src/file_manager/cache_size_mgr.cpp index 03a9147a..d644c106 100644 --- a/repertory/librepertory/src/file_manager/cache_size_mgr.cpp +++ b/repertory/librepertory/src/file_manager/cache_size_mgr.cpp @@ -58,7 +58,7 @@ auto cache_size_mgr::expand(std::uint64_t size) -> api_error { auto max_cache_size = cfg_->get_max_cache_size_bytes(); auto cache_dir = utils::file::directory{cfg_->get_cache_directory()}; - while (not stop_requested_ && cache_size_ > max_cache_size && + while (not get_stop_requested() && cache_size_ > max_cache_size && cache_dir.count() > 1U) { event_system::instance().raise(cache_size_, max_cache_size); @@ -70,6 +70,10 @@ auto cache_size_mgr::expand(std::uint64_t size) -> api_error { return api_error::success; } +auto cache_size_mgr::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + void cache_size_mgr::initialize(app_config *cfg) { if (cfg == nullptr) { throw startup_exception("app_config must not be null"); diff --git a/repertory/librepertory/src/file_manager/file_manager.cpp b/repertory/librepertory/src/file_manager/file_manager.cpp index f1a29ab3..d9ee0f38 100644 --- a/repertory/librepertory/src/file_manager/file_manager.cpp +++ b/repertory/librepertory/src/file_manager/file_manager.cpp @@ -287,6 +287,10 @@ auto file_manager::get_open_handle_count() const -> std::size_t { }); } +auto file_manager::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + auto file_manager::get_stored_downloads() const -> std::vector { REPERTORY_USES_FUNCTION_NAME(); @@ -1034,10 +1038,10 @@ void file_manager::upload_completed(const file_upload_completed &evt) { void file_manager::upload_handler() { REPERTORY_USES_FUNCTION_NAME(); - while (not stop_requested_) { + while (not get_stop_requested()) { auto should_wait{true}; unique_mutex_lock upload_lock(upload_mtx_); - if (stop_requested_) { + if (get_stop_requested()) { upload_notify_.notify_all(); continue; } diff --git a/repertory/librepertory/src/file_manager/open_file.cpp b/repertory/librepertory/src/file_manager/open_file.cpp index 64c7afbf..0fa5564e 100644 --- a/repertory/librepertory/src/file_manager/open_file.cpp +++ b/repertory/librepertory/src/file_manager/open_file.cpp @@ -118,8 +118,8 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file::~open_file() { close(); } -auto open_file::adjust_cache_size(std::uint64_t file_size, - bool shrink) -> api_error { +auto open_file::adjust_cache_size(std::uint64_t file_size, bool shrink) + -> api_error { REPERTORY_USES_FUNCTION_NAME(); if (file_size == get_file_size()) { @@ -398,11 +398,15 @@ auto open_file::get_read_state(std::size_t chunk) const -> bool { return get_read_state()[chunk]; } +auto open_file::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + auto open_file::is_complete() const -> bool { return get_read_state().all(); } auto open_file::native_operation( i_open_file::native_operation_callback callback) -> api_error { - if (stop_requested_) { + if (get_stop_requested()) { return set_api_error(api_error::download_stopped); } @@ -424,7 +428,7 @@ auto open_file::native_operation( return set_api_error(api_error::invalid_operation); } - if (stop_requested_) { + if (get_stop_requested()) { return set_api_error(api_error::download_stopped); } @@ -535,7 +539,7 @@ auto open_file::read(std::size_t read_size, std::uint64_t read_offset, return set_api_error(api_error::invalid_operation); } - if (stop_requested_) { + if (get_stop_requested()) { return set_api_error(api_error::download_stopped); } @@ -656,7 +660,7 @@ void open_file::update_reader(std::size_t chunk) { recur_mutex_lock rw_lock(rw_mtx_); read_chunk_ = chunk; - if (reader_thread_ || stop_requested_) { + if (reader_thread_ || get_stop_requested()) { return; } @@ -666,13 +670,13 @@ void open_file::update_reader(std::size_t chunk) { auto read_chunk{read_chunk_}; lock.unlock(); - while (not stop_requested_) { + while (not get_stop_requested()) { lock.lock(); auto read_state = get_read_state(); if ((get_file_size() == 0U) || read_state.all()) { lock.unlock(); - wait_for_io(stop_requested_); + wait_for_io([this]() -> bool { return this->get_stop_requested(); }); continue; } @@ -702,7 +706,7 @@ auto open_file::write(std::uint64_t write_offset, const data_buffer &data, return api_error::success; } - if (stop_requested_) { + if (get_stop_requested()) { return set_api_error(api_error::download_stopped); } diff --git a/repertory/librepertory/src/file_manager/open_file_base.cpp b/repertory/librepertory/src/file_manager/open_file_base.cpp index 746b0823..b4b132df 100644 --- a/repertory/librepertory/src/file_manager/open_file_base.cpp +++ b/repertory/librepertory/src/file_manager/open_file_base.cpp @@ -366,9 +366,9 @@ void open_file_base::set_api_path(const std::string &api_path) { fsi_.api_parent = utils::path::get_parent_api_path(api_path); } -void open_file_base::wait_for_io(stop_type &stop_requested) { +void open_file_base::wait_for_io(stop_type_callback stop_requested_cb) { unique_mutex_lock io_lock(io_thread_mtx_); - if (not stop_requested && io_thread_queue_.empty()) { + if (not stop_requested_cb() && io_thread_queue_.empty()) { io_thread_notify_.wait(io_lock); } io_thread_notify_.notify_all(); diff --git a/repertory/librepertory/src/file_manager/ring_buffer_base.cpp b/repertory/librepertory/src/file_manager/ring_buffer_base.cpp index 30ad21d0..2447e326 100644 --- a/repertory/librepertory/src/file_manager/ring_buffer_base.cpp +++ b/repertory/librepertory/src/file_manager/ring_buffer_base.cpp @@ -95,8 +95,8 @@ auto ring_buffer_base::close() -> bool { return res; } -auto ring_buffer_base::download_chunk(std::size_t chunk, - bool skip_active) -> api_error { +auto ring_buffer_base::download_chunk(std::size_t chunk, bool skip_active) + -> api_error { unique_mutex_lock chunk_lock(chunk_mtx_); const auto unlock_and_notify = [this, &chunk_lock]() { chunk_notify_.notify_all(); @@ -183,6 +183,10 @@ auto ring_buffer_base::get_read_state(std::size_t chunk) const -> bool { return read_state_[chunk % read_state_.size()]; } +auto ring_buffer_base::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + auto ring_buffer_base::read(std::size_t read_size, std::uint64_t read_offset, data_buffer &data) -> api_error { if (is_directory()) { @@ -207,7 +211,8 @@ auto ring_buffer_base::read(std::size_t read_size, std::uint64_t read_offset, } for (std::size_t chunk = begin_chunk; - not stop_requested_ && (res == api_error::success) && (read_size > 0U); + not get_stop_requested() && (res == api_error::success) && + (read_size > 0U); ++chunk) { reset_timeout(); @@ -247,7 +252,7 @@ auto ring_buffer_base::read(std::size_t read_size, std::uint64_t read_offset, read_offset = 0U; } - return stop_requested_ ? api_error::download_stopped : res; + return get_stop_requested() ? api_error::download_stopped : res; } void ring_buffer_base::reader_thread() { @@ -256,12 +261,12 @@ void ring_buffer_base::reader_thread() { chunk_notify_.notify_all(); chunk_lock.unlock(); - while (not stop_requested_) { + while (not get_stop_requested()) { chunk_lock.lock(); next_chunk = next_chunk + 1U > ring_end_ ? ring_begin_ : next_chunk + 1U; const auto check_and_wait = [this, &chunk_lock, &next_chunk]() { - if (stop_requested_) { + if (get_stop_requested()) { chunk_notify_.notify_all(); chunk_lock.unlock(); return; diff --git a/repertory/librepertory/src/providers/base_provider.cpp b/repertory/librepertory/src/providers/base_provider.cpp index 3589655b..bbbfdbd2 100644 --- a/repertory/librepertory/src/providers/base_provider.cpp +++ b/repertory/librepertory/src/providers/base_provider.cpp @@ -37,12 +37,16 @@ namespace repertory { void base_provider::add_all_items(stop_type &stop_requested) { + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + REPERTORY_USES_FUNCTION_NAME(); api_file_list list{}; std::string marker; auto res{api_error::more_data}; - while (not stop_requested && res == api_error::more_data) { + while (not get_stop_requested() && res == api_error::more_data) { res = get_file_list(list, marker); if (res != api_error::success && res != api_error::more_data) { utils::error::raise_error(function_name, res, "failed to get file list"); @@ -438,8 +442,12 @@ auto base_provider::is_file_writeable(const std::string &api_path) const void base_provider::process_removed_directories( std::deque removed_list, stop_type &stop_requested) { + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + for (const auto &item : removed_list) { - if (stop_requested) { + if (get_stop_requested()) { return; } @@ -457,10 +465,15 @@ void base_provider::process_removed_files(std::deque removed_list, stop_type &stop_requested) { REPERTORY_USES_FUNCTION_NAME(); - auto orphaned_directory = - utils::path::combine(get_config().get_data_directory(), {"orphaned"}); + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + + auto orphaned_directory{ + utils::path::combine(get_config().get_data_directory(), {"orphaned"}), + }; for (const auto &item : removed_list) { - if (stop_requested) { + if (get_stop_requested()) { return; } @@ -514,11 +527,15 @@ void base_provider::process_removed_files(std::deque removed_list, } void base_provider::process_removed_items(stop_type &stop_requested) { + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + db3_->enumerate_api_path_list( - [this, &stop_requested](auto &&list) { + [this, &get_stop_requested](auto &&list) { [[maybe_unused]] auto res = std::all_of(list.begin(), list.end(), [&](auto &&api_path) -> bool { - if (stop_requested) { + if (get_stop_requested()) { return false; } @@ -566,20 +583,24 @@ void base_provider::process_removed_items(stop_type &stop_requested) { }, }); - return not stop_requested; + return not get_stop_requested(); }); }, - stop_requested); + get_stop_requested); } void base_provider::remove_deleted_items(stop_type &stop_requested) { + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + add_all_items(stop_requested); - if (stop_requested) { + if (get_stop_requested()) { return; } remove_unmatched_source_files(stop_requested); - if (stop_requested) { + if (get_stop_requested()) { return; } @@ -673,12 +694,16 @@ void base_provider::remove_unmatched_source_files(stop_type &stop_requested) { return; } + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + const auto &cfg = get_config(); auto source_list = utils::file::directory{cfg.get_cache_directory()}.get_files(); for (const auto &source_file : source_list) { - if (stop_requested) { + if (get_stop_requested()) { return; } @@ -740,26 +765,34 @@ auto base_provider::start(api_item_added_callback api_item_added, auto online{false}; auto unmount_requested{false}; + const auto get_stop_requested = [&unmount_requested]() -> bool { + return unmount_requested || app_config::get_stop_requested(); + }; + { const auto &cfg = get_config(); repertory::event_consumer consumer( - "unmount_requested", - [&unmount_requested](const event &) { unmount_requested = true; }); - for (std::uint16_t idx = 0U; not online && not unmount_requested && + "unmount_requested", [&unmount_requested](const event & /* evt */) { + unmount_requested = true; + }); + + for (std::uint16_t idx = 0U; not online && not get_stop_requested() && (idx < cfg.get_online_check_retry_secs()); ++idx) { online = is_online(); - if (not online) { - event_system::instance().raise( - cfg.get_host_config().host_name_or_ip, - cfg.get_host_config().api_port); - std::this_thread::sleep_for(1s); + if (online) { + continue; } + + event_system::instance().raise( + cfg.get_host_config().host_name_or_ip, + cfg.get_host_config().api_port); + std::this_thread::sleep_for(1s); } } - if (not online || unmount_requested) { + if (not online || get_stop_requested()) { return false; } diff --git a/repertory/librepertory/src/providers/encrypt/encrypt_provider.cpp b/repertory/librepertory/src/providers/encrypt/encrypt_provider.cpp index c846ce63..cfca5392 100644 --- a/repertory/librepertory/src/providers/encrypt/encrypt_provider.cpp +++ b/repertory/librepertory/src/providers/encrypt/encrypt_provider.cpp @@ -27,21 +27,22 @@ #include "types/repertory.hpp" #include "types/startup_exception.hpp" #include "utils/collection.hpp" +#include "utils/config.hpp" #include "utils/encrypting_reader.hpp" #include "utils/encryption.hpp" #include "utils/error_utils.hpp" #include "utils/file_utils.hpp" #include "utils/path.hpp" #include "utils/polling.hpp" -#include namespace repertory { encrypt_provider::encrypt_provider(app_config &config) : config_(config), encrypt_config_(config.get_encrypt_config()) {} -auto encrypt_provider::create_api_file( - const std::string &api_path, bool directory, - const std::string &source_path) -> api_file { +auto encrypt_provider::create_api_file(const std::string &api_path, + bool directory, + const std::string &source_path) + -> api_file { auto times{utils::file::get_times(source_path)}; if (not times.has_value()) { throw std::runtime_error("failed to get file times"); @@ -67,10 +68,10 @@ auto encrypt_provider::create_api_file( void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory, const api_file &file) { #if defined(_WIN32) - struct _stat64 buf {}; + struct _stat64 buf{}; _stat64(file.source_path.c_str(), &buf); #else // !defined(_WIN32) - struct stat buf {}; + struct stat buf{}; stat(file.source_path.c_str(), &buf); #endif // defined(_WIN32) @@ -150,8 +151,9 @@ auto encrypt_provider::do_fs_operation( return callback(cfg, source_path); } -auto encrypt_provider::get_api_path_from_source( - const std::string &source_path, std::string &api_path) const -> api_error { +auto encrypt_provider::get_api_path_from_source(const std::string &source_path, + std::string &api_path) const + -> api_error { REPERTORY_USES_FUNCTION_NAME(); try { @@ -191,8 +193,9 @@ auto encrypt_provider::get_directory_item_count( return count; } -auto encrypt_provider::get_directory_items( - const std::string &api_path, directory_item_list &list) const -> api_error { +auto encrypt_provider::get_directory_items(const std::string &api_path, + directory_item_list &list) const + -> api_error { REPERTORY_USES_FUNCTION_NAME(); return do_fs_operation( @@ -325,8 +328,9 @@ auto encrypt_provider::get_file(const std::string &api_path, return api_error::error; } -auto encrypt_provider::get_file_list( - api_file_list &list, std::string & /* marker */) const -> api_error { +auto encrypt_provider::get_file_list(api_file_list &list, + std::string & /* marker */) const + -> api_error { REPERTORY_USES_FUNCTION_NAME(); const auto &cfg{get_encrypt_config()}; @@ -349,8 +353,9 @@ auto encrypt_provider::get_file_list( return api_error::error; } -auto encrypt_provider::get_file_size( - const std::string &api_path, std::uint64_t &file_size) const -> api_error { +auto encrypt_provider::get_file_size(const std::string &api_path, + std::uint64_t &file_size) const + -> api_error { REPERTORY_USES_FUNCTION_NAME(); try { @@ -371,9 +376,10 @@ auto encrypt_provider::get_file_size( return api_error::error; } -auto encrypt_provider::get_filesystem_item( - const std::string &api_path, bool directory, - filesystem_item &fsi) const -> api_error { +auto encrypt_provider::get_filesystem_item(const std::string &api_path, + bool directory, + filesystem_item &fsi) const + -> api_error { std::string source_path; if (directory) { auto result{db_->get_directory_source_path(api_path, source_path)}; @@ -424,9 +430,10 @@ auto encrypt_provider::get_filesystem_item_from_source_path( return get_filesystem_item(api_path, false, fsi); } -auto encrypt_provider::get_filesystem_item_and_file( - const std::string &api_path, api_file &file, - filesystem_item &fsi) const -> api_error { +auto encrypt_provider::get_filesystem_item_and_file(const std::string &api_path, + api_file &file, + filesystem_item &fsi) const + -> api_error { REPERTORY_USES_FUNCTION_NAME(); try { @@ -552,8 +559,8 @@ auto encrypt_provider::is_directory(const std::string &api_path, return api_error::error; } -auto encrypt_provider::is_file(const std::string &api_path, - bool &exists) const -> api_error { +auto encrypt_provider::is_file(const std::string &api_path, bool &exists) const + -> api_error { REPERTORY_USES_FUNCTION_NAME(); try { @@ -692,11 +699,11 @@ auto encrypt_provider::process_directory_entry( } if (file_res == api_error::item_not_found) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( utils::path::strip_to_file_name(relative_path), - dir_entry.get_path(), stop_requested, cfg.encryption_token, - utils::path::get_parent_path(relative_path)); + dir_entry.get_path(), + []() -> bool { return app_config::get_stop_requested(); }, + cfg.encryption_token, utils::path::get_parent_path(relative_path)); api_path = utils::path::create_api_path( api_parent + "/" + reader.get_encrypted_file_name()); @@ -757,7 +764,10 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path, auto info{std::make_shared()}; info->reader = std::make_unique( - relative_path, file_data.source_path, stop_requested, + relative_path, file_data.source_path, + [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }, cfg.encryption_token, utils::path::get_parent_path(relative_path)); reader_lookup_[file_data.source_path] = info; file_data.file_size = file_size; @@ -775,8 +785,11 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path, reader_lookup_.end()) { auto info{std::make_shared()}; info->reader = std::make_unique( - api_path, file_data.source_path, stop_requested, cfg.encryption_token, - std::move(file_data.iv_list)); + api_path, file_data.source_path, + [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }, + cfg.encryption_token, std::move(file_data.iv_list)); reader_lookup_[file_data.source_path] = info; } @@ -802,11 +815,15 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path, void encrypt_provider::remove_deleted_files(stop_type &stop_requested) { REPERTORY_USES_FUNCTION_NAME(); + const auto get_stop_requested = [&stop_requested]() -> bool { + return stop_requested || app_config::get_stop_requested(); + }; + db_->enumerate_item_list( - [this, &stop_requested](auto &&list) { + [this, &get_stop_requested](auto &&list) { std::vector removed_list{}; for (const auto &item : list) { - if (stop_requested) { + if (get_stop_requested()) { return; } @@ -818,7 +835,7 @@ void encrypt_provider::remove_deleted_files(stop_type &stop_requested) { } for (const auto &item : removed_list) { - if (stop_requested) { + if (get_stop_requested()) { return; } @@ -841,7 +858,7 @@ void encrypt_provider::remove_deleted_files(stop_type &stop_requested) { item.api_path, item.source_path); } }, - stop_requested); + get_stop_requested); } auto encrypt_provider::start(api_item_added_callback /*api_item_added*/, diff --git a/repertory/librepertory/src/providers/s3/s3_provider.cpp b/repertory/librepertory/src/providers/s3/s3_provider.cpp index de7ddebf..c33e9bb0 100644 --- a/repertory/librepertory/src/providers/s3/s3_provider.cpp +++ b/repertory/librepertory/src/providers/s3/s3_provider.cpp @@ -809,7 +809,8 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size, data_buffer &read_buffer) -> api_error { auto res{api_error::error}; for (std::uint32_t idx = 0U; - not stop_requested && res != api_error::success && + not(stop_requested || app_config::get_stop_requested()) && + res != api_error::success && idx < get_config().get_retry_read_count() + 1U; ++idx) { curl::requests::http_get get{}; @@ -1099,10 +1100,10 @@ auto s3_provider::upload_file_impl(const std::string &api_path, } if (is_encrypted && file_size > 0U) { - static stop_type no_stop{false}; - put_file.reader = std::make_shared( - object_name, source_path, no_stop, cfg.encryption_token, -1); + object_name, source_path, + []() -> bool { return app_config::get_stop_requested(); }, + cfg.encryption_token, -1); } long response_code{}; diff --git a/repertory/librepertory/src/providers/sia/sia_provider.cpp b/repertory/librepertory/src/providers/sia/sia_provider.cpp index 28568753..24dae7d6 100644 --- a/repertory/librepertory/src/providers/sia/sia_provider.cpp +++ b/repertory/librepertory/src/providers/sia/sia_provider.cpp @@ -568,7 +568,8 @@ auto sia_provider::read_file_bytes(const std::string &api_path, auto res{api_error::comm_error}; for (std::uint32_t idx = 0U; - not stop_requested && res != api_error::success && + not(stop_requested || app_config::get_stop_requested()) && + res != api_error::success && idx < get_config().get_retry_read_count() + 1U; ++idx) { long response_code{}; diff --git a/repertory/librepertory/src/utils/polling.cpp b/repertory/librepertory/src/utils/polling.cpp index 4252f832..679fc510 100644 --- a/repertory/librepertory/src/utils/polling.cpp +++ b/repertory/librepertory/src/utils/polling.cpp @@ -31,7 +31,7 @@ polling polling::instance_; void polling::frequency_thread( std::function get_frequency_seconds, frequency freq) { - while (not stop_requested_) { + while (not get_stop_requested()) { unique_mutex_lock lock(mutex_); auto futures = std::accumulate( items_.begin(), items_.end(), std::deque{}, @@ -65,7 +65,7 @@ void polling::frequency_thread( futures.pop_front(); } - if (stop_requested_) { + if (get_stop_requested()) { return; } @@ -74,6 +74,10 @@ void polling::frequency_thread( } } +auto polling::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + void polling::remove_callback(const std::string &name) { mutex_lock lock(mutex_); items_.erase(name); diff --git a/repertory/librepertory/src/utils/single_thread_service_base.cpp b/repertory/librepertory/src/utils/single_thread_service_base.cpp index 501be792..26d824b1 100644 --- a/repertory/librepertory/src/utils/single_thread_service_base.cpp +++ b/repertory/librepertory/src/utils/single_thread_service_base.cpp @@ -21,11 +21,16 @@ */ #include "utils/single_thread_service_base.hpp" +#include "app_config.hpp" #include "events/event_system.hpp" #include "events/events.hpp" #include "types/repertory.hpp" namespace repertory { +auto single_thread_service_base::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + void single_thread_service_base::notify_all() const { mutex_lock lock(get_mutex()); notify_.notify_all(); @@ -38,7 +43,7 @@ void single_thread_service_base::start() { on_start(); thread_ = std::make_unique([this]() { event_system::instance().raise(service_name_); - while (not stop_requested_) { + while (not get_stop_requested()) { service_function(); } }); diff --git a/repertory/librepertory/src/utils/tasks.cpp b/repertory/librepertory/src/utils/tasks.cpp index f7c6b95e..7d6bc166 100644 --- a/repertory/librepertory/src/utils/tasks.cpp +++ b/repertory/librepertory/src/utils/tasks.cpp @@ -27,6 +27,10 @@ namespace repertory { tasks tasks::instance_; +auto tasks::get_stop_requested() const -> bool { + return stop_requested_ || app_config::get_stop_requested(); +} + void tasks::task_wait::set_result(bool result) { unique_mutex_lock lock(mtx); if (complete) { @@ -50,7 +54,7 @@ auto tasks::task_wait::wait() const -> bool { auto tasks::schedule(task item) -> task_ptr { ++count_; - while (not stop_requested_ && (count_ >= task_threads_.size())) { + while (not get_stop_requested() && (count_ >= task_threads_.size())) { std::this_thread::sleep_for( std::chrono::milliseconds(config_->get_task_wait_ms())); } @@ -58,7 +62,7 @@ auto tasks::schedule(task item) -> task_ptr { scheduled_task runnable{item}; unique_mutex_lock lock(mutex_); - if (stop_requested_) { + if (get_stop_requested()) { runnable.wait->set_result(false); notify_.notify_all(); return runnable.wait; @@ -119,14 +123,14 @@ void tasks::task_thread() { release(); - while (not stop_requested_) { + while (not get_stop_requested()) { lock.lock(); - while (not stop_requested_ && tasks_.empty()) { + while (not get_stop_requested() && tasks_.empty()) { notify_.wait(lock); } - if (stop_requested_) { + if (get_stop_requested()) { release(); return; } diff --git a/repertory/repertory_test/src/file_db_test.cpp b/repertory/repertory_test/src/file_db_test.cpp index 8606a3bf..dc941626 100644 --- a/repertory/repertory_test/src/file_db_test.cpp +++ b/repertory/repertory_test/src/file_db_test.cpp @@ -22,6 +22,10 @@ #include "fixtures/file_db_fixture.hpp" +namespace { +const auto get_stop_requested = []() -> bool { return false; }; +} // namespace + namespace repertory { TYPED_TEST_CASE(file_db_test, file_db_types); @@ -30,8 +34,7 @@ TYPED_TEST(file_db_test, can_add_and_remove_directory) { EXPECT_EQ(api_error::success, this->file_db->add_directory("/", "c:\\test")); - stop_type stop_requested{false}; - auto list = this->file_db->get_item_list(stop_requested); + auto list = this->file_db->get_item_list(get_stop_requested); EXPECT_EQ(1U, list.size()); EXPECT_STREQ("/", list.at(0U).api_path.c_str()); EXPECT_TRUE(list.at(0U).directory); @@ -39,7 +42,7 @@ TYPED_TEST(file_db_test, can_add_and_remove_directory) { EXPECT_EQ(api_error::success, this->file_db->remove_item("/")); - list = this->file_db->get_item_list(stop_requested); + list = this->file_db->get_item_list(get_stop_requested); EXPECT_EQ(0U, list.size()); } @@ -53,8 +56,7 @@ TYPED_TEST(file_db_test, can_add_and_remove_file) { "c:\\test\\file.txt", })); - stop_type stop_requested{false}; - auto list = this->file_db->get_item_list(stop_requested); + auto list = this->file_db->get_item_list(get_stop_requested); EXPECT_EQ(1U, list.size()); EXPECT_STREQ("/file", list.at(0U).api_path.c_str()); EXPECT_FALSE(list.at(0U).directory); @@ -62,7 +64,7 @@ TYPED_TEST(file_db_test, can_add_and_remove_file) { EXPECT_EQ(api_error::success, this->file_db->remove_item("/file")); - list = this->file_db->get_item_list(stop_requested); + list = this->file_db->get_item_list(get_stop_requested); EXPECT_EQ(0U, list.size()); } diff --git a/support/include/utils/config.hpp b/support/include/utils/config.hpp index 2f80100c..cedba8cd 100644 --- a/support/include/utils/config.hpp +++ b/support/include/utils/config.hpp @@ -416,6 +416,7 @@ using data_buffer = std::vector; using mutex_lock = std::lock_guard; using recur_mutex_lock = std::lock_guard; using stop_type = std::atomic_bool; +using stop_type_callback = std::function; using unique_mutex_lock = std::unique_lock; using unique_recur_mutex_lock = std::unique_lock; diff --git a/support/include/utils/encrypting_reader.hpp b/support/include/utils/encrypting_reader.hpp index b71df58c..d505e031 100644 --- a/support/include/utils/encrypting_reader.hpp +++ b/support/include/utils/encrypting_reader.hpp @@ -32,17 +32,19 @@ namespace repertory::utils::encryption { class encrypting_reader final { public: encrypting_reader(std::string_view file_name, std::string_view source_path, - stop_type &stop_requested, std::string_view token, + stop_type_callback stop_requested_cb, + std::string_view token, std::optional relative_parent_path, std::size_t error_return = 0U); encrypting_reader(std::string_view encrypted_file_path, - std::string_view source_path, stop_type &stop_requested, + std::string_view source_path, + stop_type_callback stop_requested_cb, std::string_view token, std::size_t error_return = 0U); encrypting_reader( std::string_view encrypted_file_path, std::string_view source_path, - stop_type &stop_requested, std::string_view token, + stop_type_callback stop_requested_cb, std::string_view token, std::vector> iv_list, @@ -62,7 +64,7 @@ public: private: utils::encryption::hash_256_t key_; - stop_type &stop_requested_; + stop_type_callback stop_requested_cb_; size_t error_return_; std::unique_ptr source_file_; @@ -126,7 +128,7 @@ public: } [[nodiscard]] auto get_stop_requested() const -> bool { - return stop_requested_; + return stop_requested_cb_(); } [[nodiscard]] auto get_total_size() const -> std::uint64_t { diff --git a/support/src/utils/encrypting_reader.cpp b/support/src/utils/encrypting_reader.cpp index 30e72297..a9c44eb3 100644 --- a/support/src/utils/encrypting_reader.cpp +++ b/support/src/utils/encrypting_reader.cpp @@ -40,8 +40,8 @@ class encrypting_streambuf final : public encrypting_reader::streambuf { public: encrypting_streambuf(const encrypting_streambuf &) = default; encrypting_streambuf(encrypting_streambuf &&) = delete; - auto - operator=(const encrypting_streambuf &) -> encrypting_streambuf & = delete; + auto operator=(const encrypting_streambuf &) + -> encrypting_streambuf & = delete; auto operator=(encrypting_streambuf &&) -> encrypting_streambuf & = delete; explicit encrypting_streambuf(const encrypting_reader &reader) @@ -93,9 +93,10 @@ protected: return encrypting_reader::streambuf::seekoff(off, dir, which); } - auto seekpos(pos_type pos, std::ios_base::openmode which = - std::ios_base::out | - std::ios_base::in) -> pos_type override { + auto seekpos(pos_type pos, + std::ios_base::openmode which = std::ios_base::out | + std::ios_base::in) + -> pos_type override { return seekoff(pos, std::ios_base::beg, which); } @@ -177,16 +178,16 @@ const std::size_t encrypting_reader::encrypted_chunk_size_ = encrypting_reader::encrypting_reader( std::string_view file_name, std::string_view source_path, - stop_type &stop_requested, std::string_view token, + stop_type_callback stop_requested_cb, std::string_view token, std::optional relative_parent_path, std::size_t error_return) : key_(utils::encryption::generate_key( token)), - stop_requested_(stop_requested), + stop_requested_cb_(std::move(stop_requested_cb)), error_return_(error_return), source_file_(utils::file::file::open_or_create_file(source_path, true)) { REPERTORY_USES_FUNCTION_NAME(); - if (not *source_file_) { + if (not*source_file_) { throw utils::error::create_exception(function_name, { "file open failed", source_path, @@ -237,17 +238,17 @@ encrypting_reader::encrypting_reader( encrypting_reader::encrypting_reader(std::string_view encrypted_file_path, std::string_view source_path, - stop_type &stop_requested, + stop_type_callback stop_requested_cb, std::string_view token, std::size_t error_return) : key_(utils::encryption::generate_key( token)), - stop_requested_(stop_requested), + stop_requested_cb_(std::move(stop_requested_cb)), error_return_(error_return), source_file_(utils::file::file::open_or_create_file(source_path, true)) { REPERTORY_USES_FUNCTION_NAME(); - if (not *source_file_) { + if (not*source_file_) { throw utils::error::create_exception(function_name, { "file open failed", source_path, @@ -283,19 +284,19 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path, encrypting_reader::encrypting_reader( std::string_view encrypted_file_path, std::string_view source_path, - stop_type &stop_requested, std::string_view token, + stop_type_callback stop_requested_cb, std::string_view token, std::vector< std::array> iv_list, std::size_t error_return) : key_(utils::encryption::generate_key( token)), - stop_requested_(stop_requested), + stop_requested_cb_(std::move(stop_requested_cb)), error_return_(error_return), source_file_(utils::file::file::open_or_create_file(source_path, true)) { REPERTORY_USES_FUNCTION_NAME(); - if (not *source_file_) { + if (not*source_file_) { throw utils::error::create_exception(function_name, { "file open failed", source_path, @@ -329,7 +330,7 @@ encrypting_reader::encrypting_reader( encrypting_reader::encrypting_reader(const encrypting_reader &reader) : key_(reader.key_), - stop_requested_(reader.stop_requested_), + stop_requested_cb_(reader.stop_requested_cb_), error_return_(reader.error_return_), source_file_( utils::file::file::open_file(reader.source_file_->get_path(), true)), @@ -343,7 +344,7 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader) total_size_(reader.total_size_) { REPERTORY_USES_FUNCTION_NAME(); - if (not *source_file_) { + if (not*source_file_) { throw utils::error::create_exception( function_name, { "file open failed", @@ -403,7 +404,7 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, try { ret = true; auto remain = read_size; - while (not stop_requested_ && ret && (remain != 0U)) { + while (not get_stop_requested() && ret && (remain != 0U)) { if (chunk_buffers_.find(chunk) == chunk_buffers_.end()) { auto &chunk_buffer = chunk_buffers_[chunk]; data_buffer file_data(chunk == last_data_chunk_ @@ -441,9 +442,9 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, } } - return stop_requested_ ? static_cast(CURL_READFUNC_ABORT) - : ret ? total_read - : error_return_; + return get_stop_requested() ? static_cast(CURL_READFUNC_ABORT) + : ret ? total_read + : error_return_; } } // namespace repertory::utils::encryption diff --git a/support/test/src/utils/encrypting_reader_test.cpp b/support/test/src/utils/encrypting_reader_test.cpp index 1dec673d..3cbaeb42 100644 --- a/support/test/src/utils/encrypting_reader_test.cpp +++ b/support/test/src/utils/encrypting_reader_test.cpp @@ -23,6 +23,10 @@ #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) +namespace { +const auto get_stop_requested = []() -> bool { return false; }; +} // namespace + namespace repertory { TEST(utils_encrypting_reader, read_file_data) { const auto token = std::string("moose"); @@ -30,9 +34,8 @@ TEST(utils_encrypting_reader, read_file_data) { 8U * utils::encryption::encrypting_reader::get_data_chunk_size()); EXPECT_TRUE(source_file); if (source_file) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( - "test.dat", source_file.get_path(), stop_requested, token); + "test.dat", source_file.get_path(), get_stop_requested, token); for (std::uint8_t i = 0U; i < 8U; i++) { data_buffer buffer( @@ -70,9 +73,8 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks) { 8U * utils::encryption::encrypting_reader::get_data_chunk_size()); EXPECT_TRUE(source_file); if (source_file) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( - "test.dat", source_file.get_path(), stop_requested, token); + "test.dat", source_file.get_path(), get_stop_requested, token); for (std::uint8_t i = 0U; i < 8U; i += 2U) { data_buffer buffer( @@ -118,9 +120,8 @@ TEST(utils_encrypting_reader, read_file_data_as_stream) { 8U * utils::encryption::encrypting_reader::get_data_chunk_size()); EXPECT_TRUE(source_file); if (source_file) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( - "test.dat", source_file.get_path(), stop_requested, token); + "test.dat", source_file.get_path(), get_stop_requested, token); auto io_stream = reader.create_iostream(); EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); EXPECT_TRUE(io_stream->good()); @@ -171,9 +172,8 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks_as_stream) { 8u * utils::encryption::encrypting_reader::get_data_chunk_size()); EXPECT_TRUE(source_file); if (source_file) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( - "test.dat", source_file.get_path(), stop_requested, token); + "test.dat", source_file.get_path(), get_stop_requested, token); auto io_stream = reader.create_iostream(); EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); EXPECT_TRUE(io_stream->good()); diff --git a/support/test/src/utils/encryption_test.cpp b/support/test/src/utils/encryption_test.cpp index b863339a..a07b60f4 100644 --- a/support/test/src/utils/encryption_test.cpp +++ b/support/test/src/utils/encryption_test.cpp @@ -23,6 +23,10 @@ #if defined(PROJECT_ENABLE_LIBSODIUM) +namespace { +const auto get_stop_requested = []() -> bool { return false; }; +} // namespace + namespace repertory { static constexpr const std::string_view token{"moose"}; static constexpr const std::wstring_view token_w{L"moose"}; @@ -250,9 +254,8 @@ TEST(utils_encryption, decrypt_file_name) { 8U * utils::encryption::encrypting_reader::get_data_chunk_size()); EXPECT_TRUE(source_file); if (source_file) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( - "test.dat", source_file.get_path(), stop_requested, token, + "test.dat", source_file.get_path(), get_stop_requested, token, std::nullopt); auto file_name = reader.get_encrypted_file_name(); @@ -267,9 +270,9 @@ TEST(utils_encryption, decrypt_file_path) { 8U * utils::encryption::encrypting_reader::get_data_chunk_size()); EXPECT_TRUE(source_file); if (source_file) { - stop_type stop_requested{false}; utils::encryption::encrypting_reader reader( - "test.dat", source_file.get_path(), stop_requested, token, "moose/cow"); + "test.dat", source_file.get_path(), get_stop_requested, token, + "moose/cow"); auto file_path = reader.get_encrypted_file_path();