Compare commits
35 Commits
b5ae3e4ed1
...
6464c01d8b
Author | SHA1 | Date | |
---|---|---|---|
6464c01d8b | |||
58db36d628 | |||
f39c6550f2 | |||
400c97cebd | |||
a2ad258b7c | |||
c4b4fe83fb | |||
262fccf9a6 | |||
50898488f0 | |||
1acb3311b1 | |||
3fd3f85cc9 | |||
cbbd586347 | |||
57a591c51e | |||
29fb395758 | |||
b3f87e2828 | |||
7e06f810ea | |||
02e568b77a | |||
8b2bafc9f3 | |||
97e5f17049 | |||
124dc62250 | |||
5da4d4e940 | |||
b507643d23 | |||
1e25fb57f1 | |||
4d8e59f97f | |||
881778e485 | |||
3efb2b817f | |||
21d02534e5 | |||
1b11e500f3 | |||
f57bbdbb50 | |||
1c65f51ef4 | |||
f44bb6bcfc | |||
57d9884510 | |||
5da036e979 | |||
daa8b9df24 | |||
fe2a1b96b2 | |||
be678e8f9c |
@ -11,7 +11,7 @@
|
||||
* \#28 \[bug\] Address slow directory responses in S3 mounts for deeply nested directories
|
||||
* \#29 \[bug\] S3 error responses are not being logged
|
||||
* \#30 \[bug\] Sia provider error responses are not logged
|
||||
* ~~\#31 \[bug\] S3 provider should limit max key size to 1024~~
|
||||
* \#31 \[bug\] S3 provider should limit max key size to 1024
|
||||
|
||||
### Changes from v2.0.2-rc
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
* Fixed http headers not being added for requests
|
||||
* Fixed incorrect `stat` values for remote mounts
|
||||
* Fixed invalid directory nullptr error on remote mounts
|
||||
* Fixed memory leak in event system
|
||||
* Refactored application shutdown
|
||||
* Updated build system to Alpine 3.21.0
|
||||
* Updated build system to MinGW-w64 12.0.0
|
||||
* Updated copyright to 2018-2025
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
@ -115,7 +116,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response_code != 200) {
|
||||
if (response_code != http_error_codes::ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
|
||||
virtual void enumerate_item_list(
|
||||
std::function<void(const std::vector<i_file_db::file_info> &)> 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<file_info> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_source_path(const std::string &api_path,
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
|
||||
virtual void enumerate_api_path_list(
|
||||
std::function<void(const std::vector<std::string> &)> 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
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
|
||||
void enumerate_item_list(
|
||||
std::function<void(const std::vector<i_file_db::file_info> &)> 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<i_file_db::file_info> override;
|
||||
|
||||
[[nodiscard]] auto get_source_path(const std::string &api_path,
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
|
||||
void enumerate_api_path_list(
|
||||
std::function<void(const std::vector<std::string> &)> 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
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
void enumerate_item_list(
|
||||
std::function<void(const std::vector<i_file_db::file_info> &)> 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<i_file_db::file_info> override;
|
||||
|
||||
[[nodiscard]] auto get_source_path(const std::string &api_path,
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
|
||||
void enumerate_api_path_list(
|
||||
std::function<void(const std::vector<std::string> &)> 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
|
||||
|
@ -22,12 +22,10 @@
|
||||
#ifndef REPERTORY_INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_
|
||||
#define REPERTORY_INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_
|
||||
|
||||
#include "utils/single_thread_service_base.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class directory_iterator;
|
||||
|
||||
class directory_cache final : public single_thread_service_base {
|
||||
class directory_cache final {
|
||||
public:
|
||||
using execute_callback = std::function<void(directory_iterator &)>;
|
||||
|
||||
@ -35,13 +33,11 @@ private:
|
||||
struct open_directory final {
|
||||
std::shared_ptr<directory_iterator> iterator;
|
||||
std::vector<std::uint64_t> handles;
|
||||
std::chrono::system_clock::time_point last_update{
|
||||
std::chrono::system_clock::now()};
|
||||
};
|
||||
|
||||
public:
|
||||
directory_cache() : single_thread_service_base("directory_cache") {}
|
||||
~directory_cache() override = default;
|
||||
directory_cache() = default;
|
||||
~directory_cache() = default;
|
||||
|
||||
directory_cache(const directory_cache &) = delete;
|
||||
directory_cache(directory_cache &&) = delete;
|
||||
@ -51,17 +47,13 @@ public:
|
||||
private:
|
||||
std::unordered_map<std::string, open_directory> directory_lookup_;
|
||||
std::recursive_mutex directory_mutex_;
|
||||
std::unique_ptr<std::thread> refresh_thread_;
|
||||
|
||||
protected:
|
||||
void service_function() override;
|
||||
|
||||
public:
|
||||
void execute_action(const std::string &api_path,
|
||||
const execute_callback &execute);
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_directory(std::uint64_t handle) -> std::shared_ptr<directory_iterator>;
|
||||
[[nodiscard]] auto get_directory(std::uint64_t handle)
|
||||
-> std::shared_ptr<directory_iterator>;
|
||||
|
||||
auto remove_directory(const std::string &api_path)
|
||||
-> std::shared_ptr<directory_iterator>;
|
||||
|
@ -26,13 +26,13 @@
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE3(fuse_event, debug, true,
|
||||
E_SIMPLE3(fuse_event, debug,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
int, result, res, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE1(fuse_args_parsed, info, true,
|
||||
E_SIMPLE1(fuse_args_parsed, info,
|
||||
std::string, arguments, args, E_FROM_STRING
|
||||
);
|
||||
// clang-format on
|
||||
|
@ -63,99 +63,103 @@ private:
|
||||
std::shared_ptr<logging_consumer> logging_consumer_;
|
||||
std::shared_ptr<remote_fuse::remote_server> remote_server_;
|
||||
std::shared_ptr<full_server> 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;
|
||||
|
@ -73,6 +73,7 @@ private:
|
||||
std::unique_ptr<file_manager> fm_;
|
||||
std::unique_ptr<eviction> eviction_;
|
||||
std::unique_ptr<remote_winfsp::remote_server> 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;
|
||||
|
@ -22,29 +22,15 @@
|
||||
#ifndef REPERTORY_INCLUDE_EVENTS_EVENT_HPP_
|
||||
#define REPERTORY_INCLUDE_EVENTS_EVENT_HPP_
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
enum class event_level {
|
||||
critical,
|
||||
error,
|
||||
warn,
|
||||
info,
|
||||
debug,
|
||||
trace,
|
||||
};
|
||||
|
||||
[[nodiscard]] auto
|
||||
event_level_from_string(std::string level,
|
||||
event_level default_level = event_level::info)
|
||||
-> event_level;
|
||||
|
||||
[[nodiscard]] auto event_level_to_string(event_level level) -> std::string;
|
||||
|
||||
class event {
|
||||
protected:
|
||||
explicit event(bool allow_async) : allow_async_(allow_async) {}
|
||||
event() = default;
|
||||
|
||||
event(const std::stringstream &ss, json j, bool allow_async)
|
||||
: allow_async_(allow_async), ss_(ss.str()), j_(std::move(j)) {}
|
||||
event(const std::stringstream &ss, json j)
|
||||
: ss_(ss.str()), j_(std::move(j)) {}
|
||||
|
||||
public:
|
||||
event(const event &) = delete;
|
||||
@ -53,18 +39,13 @@ public:
|
||||
auto operator=(event &&) -> event & = delete;
|
||||
virtual ~event() = default;
|
||||
|
||||
private:
|
||||
bool allow_async_;
|
||||
|
||||
protected:
|
||||
std::stringstream ss_;
|
||||
json j_;
|
||||
json j_{};
|
||||
|
||||
public:
|
||||
[[nodiscard]] virtual auto clone() const -> std::shared_ptr<event> = 0;
|
||||
|
||||
[[nodiscard]] auto get_allow_async() const -> bool { return allow_async_; }
|
||||
|
||||
[[nodiscard]] virtual auto get_event_level() const -> event_level = 0;
|
||||
|
||||
[[nodiscard]] auto get_json() const -> json { return j_; }
|
||||
@ -75,18 +56,4 @@ public:
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
template <> struct adl_serializer<std::atomic<repertory::event_level>> {
|
||||
static void to_json(json &data,
|
||||
const std::atomic<repertory::event_level> &value) {
|
||||
data = repertory::event_level_to_string(value.load());
|
||||
}
|
||||
|
||||
static void from_json(const json &data,
|
||||
std::atomic<repertory::event_level> &value) {
|
||||
value.store(repertory::event_level_from_string(data.get<std::string>()));
|
||||
}
|
||||
};
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
#endif // REPERTORY_INCLUDE_EVENTS_EVENT_HPP_
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "events/event.hpp"
|
||||
#include "events/t_event_system.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
using event_system = t_event_system<event>;
|
||||
@ -60,8 +61,7 @@ public: \
|
||||
#define E_BEGIN(name, el) \
|
||||
class name final : public virtual event { \
|
||||
private: \
|
||||
name(const std::stringstream &ss, const json &j, bool allow_async) \
|
||||
: event(ss, j, allow_async) {} \
|
||||
name(const std::stringstream &ss, const json &j) : event(ss, j) {} \
|
||||
\
|
||||
public: \
|
||||
~name() override = default; \
|
||||
@ -84,28 +84,26 @@ public: \
|
||||
} \
|
||||
\
|
||||
[[nodiscard]] auto clone() const -> std::shared_ptr<event> override { \
|
||||
return std::shared_ptr<name>(new name(ss_, j_, get_allow_async())); \
|
||||
return std::shared_ptr<name>(new name(ss_, j_)); \
|
||||
}
|
||||
#define E_END() }
|
||||
|
||||
#define E_SIMPLE(event_name, el, allow_async) \
|
||||
#define E_SIMPLE(event_name, el) \
|
||||
E_BEGIN(event_name, el) \
|
||||
public: \
|
||||
event_name() : event(allow_async) {} \
|
||||
event_name() {} \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE1(event_name, el, allow_async, type, name, short_name, tc) \
|
||||
#define E_SIMPLE1(event_name, el, type, name, short_name, tc) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv) : event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
} \
|
||||
explicit event_name(const type &tv) { init_##short_name(tv); } \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE2(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2) \
|
||||
#define E_SIMPLE2(event_name, el, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2) : event(allow_async) { \
|
||||
explicit event_name(const type &tv, const type2 &tv2) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
} \
|
||||
@ -113,12 +111,10 @@ public: \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE3(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3) \
|
||||
#define E_SIMPLE3(event_name, el, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3) \
|
||||
: event(allow_async) { \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
@ -128,13 +124,12 @@ public: \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE4(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4) \
|
||||
#define E_SIMPLE4(event_name, el, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, \
|
||||
name4, short_name4, tc4) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4) \
|
||||
: event(allow_async) { \
|
||||
const type4 &tv4) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
@ -146,14 +141,12 @@ public: \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE5(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4, type5, name5, \
|
||||
short_name5, tc5) \
|
||||
#define E_SIMPLE5(event_name, el, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, \
|
||||
name4, short_name4, tc4, type5, name5, short_name5, tc5) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4, const type5 &tv5) \
|
||||
: event(allow_async) { \
|
||||
const type4 &tv4, const type5 &tv5) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
@ -167,14 +160,13 @@ public: \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE6(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4, type5, name5, \
|
||||
short_name5, tc5, type6, name6, short_name6, tc6) \
|
||||
#define E_SIMPLE6(event_name, el, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, \
|
||||
name4, short_name4, tc4, type5, name5, short_name5, tc5, \
|
||||
type6, name6, short_name6, tc6) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4, const type5 &tv5, const type6 &tv6) \
|
||||
: event(allow_async) { \
|
||||
const type4 &tv4, const type5 &tv5, const type6 &tv6) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
@ -190,16 +182,15 @@ public: \
|
||||
E_PROP(type6, name6, short_name6, tc6) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE7(event_name, el, allow_async, type, name, short_name, tc, \
|
||||
type2, name2, short_name2, tc2, type3, name3, short_name3, \
|
||||
tc3, type4, name4, short_name4, tc4, type5, name5, \
|
||||
short_name5, tc5, type6, name6, short_name6, tc6, type7, \
|
||||
name7, short_name7, tc7) \
|
||||
#define E_SIMPLE7(event_name, el, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, \
|
||||
name4, short_name4, tc4, type5, name5, short_name5, tc5, \
|
||||
type6, name6, short_name6, tc6, type7, name7, short_name7, \
|
||||
tc7) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, \
|
||||
const type4 &tv4, const type5 &tv5, const type6 &tv6, \
|
||||
const type7 &tv7) \
|
||||
: event(allow_async) { \
|
||||
const type7 &tv7) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
|
@ -28,126 +28,126 @@
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(curl_error, error, true,
|
||||
E_SIMPLE2(curl_error, error,
|
||||
std::string, url, url, E_FROM_STRING,
|
||||
CURLcode, res, res, E_FROM_CURL_CODE
|
||||
);
|
||||
|
||||
E_SIMPLE3(debug_log, debug, true,
|
||||
E_SIMPLE3(debug_log, debug,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, data, data, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(directory_removed, debug, true,
|
||||
E_SIMPLE1(directory_removed, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(directory_removed_externally, warn, true,
|
||||
E_SIMPLE2(directory_removed_externally, warn,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(directory_remove_failed, error, true,
|
||||
E_SIMPLE2(directory_remove_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(drive_mount_failed, error, true,
|
||||
E_SIMPLE2(drive_mount_failed, error,
|
||||
std::string, location, loc, E_FROM_STRING,
|
||||
std::string, result, res, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_mounted, info, true,
|
||||
E_SIMPLE1(drive_mounted, info,
|
||||
std::string, location, loc, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_mount_result, info, true,
|
||||
E_SIMPLE1(drive_mount_result, info,
|
||||
std::string, result, res, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_unmount_pending, info, true,
|
||||
E_SIMPLE1(drive_unmount_pending, info,
|
||||
std::string, location, loc, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_unmounted, info, true,
|
||||
E_SIMPLE1(drive_unmounted, info,
|
||||
std::string, location, loc, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(event_level_changed, info, true,
|
||||
E_SIMPLE1(event_level_changed, info,
|
||||
std::string, new_event_level, level, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_queued, error, true,
|
||||
E_SIMPLE1(failed_upload_queued, error,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_removed, warn, true,
|
||||
E_SIMPLE1(failed_upload_removed, warn,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_retry, info, true,
|
||||
E_SIMPLE1(failed_upload_retry, info,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_get_failed, error, true,
|
||||
E_SIMPLE2(file_get_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_get_api_list_failed, error, true,
|
||||
E_SIMPLE1(file_get_api_list_failed, error,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_pinned, info, true,
|
||||
E_SIMPLE1(file_pinned, info,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_read_bytes_failed, error, true,
|
||||
E_SIMPLE3(file_read_bytes_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING,
|
||||
std::size_t, retry, retry, E_FROM_SIZE_T
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_removed, debug, true,
|
||||
E_SIMPLE1(file_removed, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_removed_externally, warn, true,
|
||||
E_SIMPLE2(file_removed_externally, warn,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_remove_failed, error, true,
|
||||
E_SIMPLE2(file_remove_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_rename_failed, error, true,
|
||||
E_SIMPLE3(file_rename_failed, error,
|
||||
std::string, from_api_path, FROM, E_FROM_STRING,
|
||||
std::string, to_api_path, TO, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_get_size_failed, error, true,
|
||||
E_SIMPLE2(file_get_size_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(filesystem_item_added, debug, true,
|
||||
E_SIMPLE3(filesystem_item_added, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, parent, parent, E_FROM_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE4(filesystem_item_closed, trace, true,
|
||||
E_SIMPLE4(filesystem_item_closed, trace,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL,
|
||||
bool, changed, changed, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE5(filesystem_item_handle_closed, trace, true,
|
||||
E_SIMPLE5(filesystem_item_handle_closed, trace,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::uint64_t, handle, handle, E_FROM_UINT64,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
@ -155,136 +155,136 @@ E_SIMPLE5(filesystem_item_handle_closed, trace, true,
|
||||
bool, changed, changed, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE4(filesystem_item_handle_opened, trace, true,
|
||||
E_SIMPLE4(filesystem_item_handle_opened, trace,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::uint64_t, handle, handle, E_FROM_UINT64,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE2(filesystem_item_evicted, info, true,
|
||||
E_SIMPLE2(filesystem_item_evicted, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(filesystem_item_opened, trace, true,
|
||||
E_SIMPLE3(filesystem_item_opened, trace,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_unpinned, info, true,
|
||||
E_SIMPLE1(file_unpinned, info,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(file_upload_completed, info, true,
|
||||
E_SIMPLE4(file_upload_completed, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR,
|
||||
bool, cancelled, cancel, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_failed, error, true,
|
||||
E_SIMPLE3(file_upload_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_not_found, warn, true,
|
||||
E_SIMPLE2(file_upload_not_found, warn,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_queued, info, true,
|
||||
E_SIMPLE2(file_upload_queued, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_upload_removed, debug, true,
|
||||
E_SIMPLE1(file_upload_removed, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_retry, info, true,
|
||||
E_SIMPLE3(file_upload_retry, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_started, info, true,
|
||||
E_SIMPLE2(file_upload_started, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(orphaned_file_deleted, warn, true,
|
||||
E_SIMPLE1(orphaned_file_deleted, warn,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(orphaned_file_detected, warn, true,
|
||||
E_SIMPLE1(orphaned_file_detected, warn,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(orphaned_file_processing_failed, error, true,
|
||||
E_SIMPLE3(orphaned_file_processing_failed, error,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
std::string, dest, dest, E_FROM_STRING,
|
||||
std::string, result, res, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(orphaned_source_file_detected, info, true,
|
||||
E_SIMPLE1(orphaned_source_file_detected, info,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(orphaned_source_file_removed, info, true,
|
||||
E_SIMPLE1(orphaned_source_file_removed, info,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(polling_item_begin, debug, true,
|
||||
E_SIMPLE1(polling_item_begin, debug,
|
||||
std::string, item_name, item, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(polling_item_end, debug, true,
|
||||
E_SIMPLE1(polling_item_end, debug,
|
||||
std::string, item_name, item, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(provider_offline, error, true,
|
||||
E_SIMPLE2(provider_offline, error,
|
||||
std::string, host_name_or_ip, host, E_FROM_STRING,
|
||||
std::uint16_t, port, port, E_FROM_UINT16
|
||||
);
|
||||
|
||||
E_SIMPLE2(provider_upload_begin, info, true,
|
||||
E_SIMPLE2(provider_upload_begin, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(provider_upload_end, info, true,
|
||||
E_SIMPLE3(provider_upload_end, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(repertory_exception, error, true,
|
||||
E_SIMPLE2(repertory_exception, error,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, message, msg, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(rpc_server_exception, error, true,
|
||||
E_SIMPLE1(rpc_server_exception, error,
|
||||
std::string, exception, exception, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_shutdown_begin, debug, true,
|
||||
E_SIMPLE1(service_shutdown_begin, debug,
|
||||
std::string, service, svc, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_shutdown_end, debug, true,
|
||||
E_SIMPLE1(service_shutdown_end, debug,
|
||||
std::string, service, svc, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_started, debug, true,
|
||||
E_SIMPLE1(service_started, debug,
|
||||
std::string, service, svc, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE(unmount_requested, info, true);
|
||||
E_SIMPLE(unmount_requested, info);
|
||||
#if !defined(_WIN32)
|
||||
E_SIMPLE2(unmount_result, info, true,
|
||||
E_SIMPLE2(unmount_result, info,
|
||||
std::string, location, loc, E_FROM_STRING,
|
||||
std::string, result, res, E_FROM_STRING
|
||||
);
|
||||
|
@ -22,12 +22,26 @@
|
||||
#ifndef REPERTORY_INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
||||
#define REPERTORY_INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
||||
|
||||
#include "app_config.hpp"
|
||||
#include "events/event.hpp"
|
||||
#include "utils/collection.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
template <typename event_type> class t_event_system final {
|
||||
private:
|
||||
static constexpr const std::uint8_t max_queue_retry{
|
||||
30U,
|
||||
};
|
||||
|
||||
const std::uint32_t max_queue_size{
|
||||
std::thread::hardware_concurrency() * 4UL,
|
||||
};
|
||||
|
||||
static constexpr const std::chrono::seconds queue_wait_secs{
|
||||
5s,
|
||||
};
|
||||
|
||||
public:
|
||||
t_event_system(const t_event_system &) = delete;
|
||||
t_event_system(t_event_system &&) = delete;
|
||||
@ -83,38 +97,48 @@ private:
|
||||
std::mutex event_mutex_;
|
||||
std::unique_ptr<std::thread> event_thread_;
|
||||
std::mutex run_mutex_;
|
||||
stop_type stop_requested_ = false;
|
||||
stop_type stop_requested_{false};
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto get_stop_requested() const -> bool {
|
||||
return stop_requested_ || app_config::get_stop_requested();
|
||||
}
|
||||
|
||||
void process_events() {
|
||||
std::vector<std::shared_ptr<event_type>> events;
|
||||
{
|
||||
|
||||
unique_mutex_lock lock(event_mutex_);
|
||||
if (not stop_requested_ && event_list_.empty()) {
|
||||
event_notify_.wait_for(lock, 1s);
|
||||
const auto lock_and_notify = [this, &lock]() {
|
||||
lock.lock();
|
||||
event_notify_.notify_all();
|
||||
lock.unlock();
|
||||
};
|
||||
|
||||
if (not get_stop_requested() && event_list_.empty()) {
|
||||
event_notify_.wait_for(lock, queue_wait_secs);
|
||||
}
|
||||
|
||||
if (not event_list_.empty()) {
|
||||
events.insert(events.end(), event_list_.begin(), event_list_.end());
|
||||
event_list_.clear();
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if (events.empty()) {
|
||||
lock_and_notify();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto notify_events = [this](const std::string &name,
|
||||
const event_type &event) {
|
||||
std::deque<std::future<void>> futures;
|
||||
recur_mutex_lock lock(consumer_mutex_);
|
||||
if (event_consumers_.find(name) != event_consumers_.end()) {
|
||||
recur_mutex_lock consumer_lock(consumer_mutex_);
|
||||
for (auto *consumer : event_consumers_[name]) {
|
||||
if (event.get_allow_async()) {
|
||||
futures.emplace_back(
|
||||
std::async(std::launch::async, [consumer, &event]() {
|
||||
consumer->notify_event(event);
|
||||
}));
|
||||
} else {
|
||||
consumer->notify_event(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (not futures.empty()) {
|
||||
@ -127,12 +151,31 @@ private:
|
||||
notify_events("", *evt.get());
|
||||
notify_events(evt->get_name(), *evt.get());
|
||||
}
|
||||
|
||||
lock_and_notify();
|
||||
}
|
||||
|
||||
void queue_event(std::shared_ptr<event_type> evt) {
|
||||
mutex_lock lock(event_mutex_);
|
||||
unique_mutex_lock lock(event_mutex_);
|
||||
event_list_.push_back(std::move(evt));
|
||||
auto size = event_list_.size();
|
||||
event_notify_.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
for (std::uint8_t retry{0U};
|
||||
size > max_queue_size && retry < max_queue_retry &&
|
||||
not get_stop_requested();
|
||||
++retry) {
|
||||
lock.lock();
|
||||
size = event_list_.size();
|
||||
if (size > max_queue_size) {
|
||||
event_notify_.wait_for(lock, queue_wait_secs);
|
||||
size = event_list_.size();
|
||||
}
|
||||
|
||||
event_notify_.notify_all();
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@ -165,28 +208,41 @@ public:
|
||||
|
||||
void start() {
|
||||
mutex_lock lock(run_mutex_);
|
||||
if (not event_thread_) {
|
||||
if (event_thread_) {
|
||||
event_notify_.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
stop_requested_ = false;
|
||||
|
||||
event_thread_ = std::make_unique<std::thread>([this]() {
|
||||
while (not stop_requested_) {
|
||||
while (not get_stop_requested()) {
|
||||
process_events();
|
||||
}
|
||||
});
|
||||
}
|
||||
event_notify_.notify_all();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
mutex_lock lock(run_mutex_);
|
||||
if (event_thread_) {
|
||||
stop_requested_ = true;
|
||||
unique_mutex_lock lock(run_mutex_);
|
||||
if (not event_thread_) {
|
||||
event_notify_.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
event_thread_->join();
|
||||
event_thread_.reset();
|
||||
stop_requested_ = true;
|
||||
|
||||
std::unique_ptr<std::thread> thread{nullptr};
|
||||
std::swap(thread, event_thread_);
|
||||
|
||||
event_notify_.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
thread->join();
|
||||
thread.reset();
|
||||
|
||||
process_events();
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
|
@ -28,6 +28,11 @@ namespace repertory {
|
||||
class app_config;
|
||||
|
||||
class cache_size_mgr final {
|
||||
private:
|
||||
static constexpr const std::chrono::seconds cache_wait_secs{
|
||||
5s,
|
||||
};
|
||||
|
||||
public:
|
||||
cache_size_mgr(const cache_size_mgr &) = delete;
|
||||
cache_size_mgr(cache_size_mgr &&) = delete;
|
||||
@ -49,6 +54,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;
|
||||
|
||||
|
@ -27,55 +27,55 @@
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(download_begin, info, true,
|
||||
E_SIMPLE2(download_begin, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_end, info, true,
|
||||
E_SIMPLE3(download_end, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
api_error, result, result, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_progress, info, true,
|
||||
E_SIMPLE3(download_progress, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
double, progress, prog, E_FROM_DOUBLE_PRECISE
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_restored, info, true,
|
||||
E_SIMPLE2(download_restored, info,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_restore_failed, error, true,
|
||||
E_SIMPLE3(download_restore_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_resume_add_failed, error, true,
|
||||
E_SIMPLE3(download_resume_add_failed, error,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_resume_added, debug, true,
|
||||
E_SIMPLE2(download_resume_added, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_resume_removed, debug, true,
|
||||
E_SIMPLE2(download_resume_removed, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(item_timeout, trace, true,
|
||||
E_SIMPLE1(item_timeout, trace,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_type_selected, debug, true,
|
||||
E_SIMPLE3(download_type_selected, debug,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
download_type, download_type, type, E_FROM_DOWNLOAD_TYPE
|
||||
|
@ -39,6 +39,11 @@ class i_provider;
|
||||
class file_manager final : public i_file_manager, public i_upload_manager {
|
||||
E_CONSUMER();
|
||||
|
||||
private:
|
||||
static constexpr const std::chrono::seconds queue_wait_secs{
|
||||
5s,
|
||||
};
|
||||
|
||||
public:
|
||||
file_manager(app_config &config, i_provider &provider);
|
||||
|
||||
@ -72,15 +77,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<i_closeable_open_file>;
|
||||
|
||||
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,
|
||||
[[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<i_open_file> &file,
|
||||
std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error;
|
||||
std::shared_ptr<i_closeable_open_file> closeable_file)
|
||||
-> api_error;
|
||||
|
||||
void queue_upload(const std::string &api_path, const std::string &source_path,
|
||||
bool no_lock);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<std::uint64_t> override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_open_data() -> std::map<std::uint64_t, open_file_data> & override;
|
||||
[[nodiscard]] auto get_open_data()
|
||||
-> std::map<std::uint64_t, open_file_data> & override;
|
||||
|
||||
[[nodiscard]] auto get_open_data() const
|
||||
-> const std::map<std::uint64_t, 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)
|
||||
-> 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;
|
||||
|
||||
|
@ -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<api_error(data_buffer &)> func) -> api_error = 0;
|
||||
use_buffer(std::size_t chunk, std::function<api_error(data_buffer &)> 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;
|
||||
}
|
||||
};
|
||||
|
@ -47,8 +47,8 @@ private:
|
||||
private:
|
||||
bool cancelled_{false};
|
||||
api_error error_{api_error::success};
|
||||
std::unique_ptr<std::thread> thread_;
|
||||
stop_type stop_requested_{false};
|
||||
std::unique_ptr<std::thread> thread_;
|
||||
|
||||
private:
|
||||
void upload_thread();
|
||||
|
@ -38,7 +38,6 @@ private:
|
||||
std::unique_ptr<httplib::Server> server_;
|
||||
std::unique_ptr<std::thread> server_thread_;
|
||||
std::mutex start_stop_mutex_;
|
||||
std::atomic<bool> started_ = false;
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto check_authorization(const httplib::Request &req) -> bool;
|
||||
|
@ -246,6 +246,22 @@ download_type_from_string(std::string type,
|
||||
[[nodiscard]] auto download_type_to_string(const download_type &type)
|
||||
-> std::string;
|
||||
|
||||
enum class event_level {
|
||||
critical,
|
||||
error,
|
||||
warn,
|
||||
info,
|
||||
debug,
|
||||
trace,
|
||||
};
|
||||
|
||||
[[nodiscard]] auto
|
||||
event_level_from_string(std::string level,
|
||||
event_level default_level = event_level::info)
|
||||
-> event_level;
|
||||
|
||||
[[nodiscard]] auto event_level_to_string(event_level level) -> std::string;
|
||||
|
||||
enum class exit_code : std::int32_t {
|
||||
success = 0,
|
||||
communication_error = -1,
|
||||
@ -654,6 +670,18 @@ template <> struct adl_serializer<repertory::download_type> {
|
||||
value = repertory::download_type_from_string(data.get<std::string>());
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<std::atomic<repertory::event_level>> {
|
||||
static void to_json(json &data,
|
||||
const std::atomic<repertory::event_level> &value) {
|
||||
data = repertory::event_level_to_string(value.load());
|
||||
}
|
||||
|
||||
static void from_json(const json &data,
|
||||
std::atomic<repertory::event_level> &value) {
|
||||
value.store(repertory::event_level_from_string(data.get<std::string>()));
|
||||
}
|
||||
};
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
#endif // REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_
|
||||
|
@ -75,6 +75,8 @@ private:
|
||||
void frequency_thread(std::function<std::uint32_t()> get_frequency_seconds,
|
||||
frequency freq);
|
||||
|
||||
[[nodiscard]] auto get_stop_requested() const -> bool;
|
||||
|
||||
public:
|
||||
void remove_callback(const std::string &name);
|
||||
|
||||
|
@ -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<std::thread> 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;
|
||||
|
||||
|
@ -104,6 +104,8 @@ private:
|
||||
private:
|
||||
void task_thread();
|
||||
|
||||
[[nodiscard]] auto get_stop_requested() const -> bool;
|
||||
|
||||
public:
|
||||
auto schedule(task item) -> task_ptr;
|
||||
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
~timeout() { disable(); }
|
||||
|
||||
private:
|
||||
bool timeout_killed_;
|
||||
std::atomic<bool> timeout_killed_;
|
||||
std::unique_ptr<std::thread> timeout_thread_;
|
||||
std::mutex timeout_mutex_;
|
||||
std::condition_variable timeout_notify_;
|
||||
|
@ -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),
|
||||
|
@ -33,7 +33,7 @@ const curl_comm::write_callback curl_comm::write_data =
|
||||
auto &info = *reinterpret_cast<read_write_info *>(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;
|
||||
|
@ -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
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(packet_client_timeout, error, true,
|
||||
E_SIMPLE2(packet_client_timeout, error,
|
||||
std::string, event_name, en, E_FROM_STRING,
|
||||
std::string, message, msg, E_FROM_STRING
|
||||
);
|
||||
@ -112,8 +112,8 @@ void packet_client::put_client(std::shared_ptr<client> &cli) {
|
||||
}
|
||||
}
|
||||
|
||||
auto packet_client::read_packet(client &cli,
|
||||
packet &response) const -> packet::error_type {
|
||||
auto packet_client::read_packet(client &cli, packet &response) const
|
||||
-> packet::error_type {
|
||||
data_buffer buffer(sizeof(std::uint32_t));
|
||||
const auto read_buffer = [&]() {
|
||||
std::uint32_t offset{};
|
||||
@ -154,8 +154,8 @@ void packet_client::resolve() {
|
||||
.resolve(cfg_.host_name_or_ip, std::to_string(cfg_.api_port));
|
||||
}
|
||||
|
||||
auto packet_client::send(std::string_view method,
|
||||
std::uint32_t &service_flags) -> packet::error_type {
|
||||
auto packet_client::send(std::string_view method, std::uint32_t &service_flags)
|
||||
-> packet::error_type {
|
||||
packet request;
|
||||
return send(method, request, service_flags);
|
||||
}
|
||||
@ -167,8 +167,8 @@ auto packet_client::send(std::string_view method, packet &request,
|
||||
}
|
||||
|
||||
auto packet_client::send(std::string_view method, packet &request,
|
||||
packet &response,
|
||||
std::uint32_t &service_flags) -> packet::error_type {
|
||||
packet &response, std::uint32_t &service_flags)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
auto success = false;
|
||||
|
@ -151,11 +151,11 @@ auto rdb_file_db::count() const -> std::uint64_t {
|
||||
|
||||
void rdb_file_db::enumerate_item_list(
|
||||
std::function<void(const std::vector<i_file_db::file_info> &)> callback,
|
||||
stop_type &stop_requested) const {
|
||||
stop_type_callback stop_requested_cb) const {
|
||||
std::vector<i_file_db::file_info> 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<i_file_db::file_info> {
|
||||
std::vector<i_file_db::file_info> 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{
|
||||
|
@ -66,11 +66,12 @@ auto rdb_meta_db::create_iterator(rocksdb::ColumnFamilyHandle *family) const
|
||||
|
||||
void rdb_meta_db::enumerate_api_path_list(
|
||||
std::function<void(const std::vector<std::string> &)> callback,
|
||||
stop_type &stop_requested) const {
|
||||
stop_type_callback stop_requested_cb) const {
|
||||
std::vector<std::string> 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) {
|
||||
|
@ -135,11 +135,11 @@ auto sqlite_file_db::count() const -> std::uint64_t {
|
||||
|
||||
void sqlite_file_db::enumerate_item_list(
|
||||
std::function<void(const std::vector<i_file_db::file_info> &)> callback,
|
||||
stop_type &stop_requested) const {
|
||||
stop_type_callback stop_requested_cb) const {
|
||||
std::vector<i_file_db::file_info> 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<utils::db::sqlite::db_result::row> 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<i_file_db::file_info> {
|
||||
std::vector<i_file_db::file_info> 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<utils::db::sqlite::db_result::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
ret.emplace_back(i_file_db::file_info{
|
||||
|
@ -77,12 +77,12 @@ void sqlite_meta_db::clear() {
|
||||
|
||||
void sqlite_meta_db::enumerate_api_path_list(
|
||||
std::function<void(const std::vector<std::string> &)> 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<std::string> list{};
|
||||
while (not stop_requested && result.has_row()) {
|
||||
while (not stop_requested_cb() && result.has_row()) {
|
||||
std::optional<utils::db::sqlite::db_result::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
list.push_back(row->get_column("api_path").get_value<std::string>());
|
||||
@ -343,7 +343,7 @@ auto sqlite_meta_db::set_item_meta(const std::string &api_path,
|
||||
// TODO handle error
|
||||
}
|
||||
|
||||
for (auto &&item : meta) {
|
||||
for (const auto &item : meta) {
|
||||
existing_meta[item.first] = item.second;
|
||||
}
|
||||
|
||||
|
@ -38,14 +38,15 @@ void directory_cache::execute_action(const std::string &api_path,
|
||||
auto directory_cache::get_directory(std::uint64_t handle)
|
||||
-> std::shared_ptr<directory_iterator> {
|
||||
recur_mutex_lock directory_lock(directory_mutex_);
|
||||
auto it = std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
||||
[handle](auto &&kv) -> bool {
|
||||
auto &&handles = kv.second.handles;
|
||||
return std::find(handles.begin(), handles.end(),
|
||||
handle) != kv.second.handles.end();
|
||||
auto iter =
|
||||
std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
||||
[handle](auto &&item) -> bool {
|
||||
auto &&handles = item.second.handles;
|
||||
return std::find(handles.begin(), handles.end(), handle) !=
|
||||
item.second.handles.end();
|
||||
});
|
||||
if (it != directory_lookup_.end()) {
|
||||
return it->second.iterator;
|
||||
if (iter != directory_lookup_.end()) {
|
||||
return iter->second.iterator;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -66,39 +67,20 @@ auto directory_cache::remove_directory(const std::string &api_path)
|
||||
|
||||
void directory_cache::remove_directory(std::uint64_t handle) {
|
||||
recur_mutex_lock directory_lock(directory_mutex_);
|
||||
auto it = std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
||||
[handle](auto &&kv) -> bool {
|
||||
auto &&handles = kv.second.handles;
|
||||
return std::find(handles.begin(), handles.end(),
|
||||
handle) != kv.second.handles.end();
|
||||
auto iter =
|
||||
std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
||||
[handle](auto &&item) -> bool {
|
||||
auto &&handles = item.second.handles;
|
||||
return std::find(handles.begin(), handles.end(), handle) !=
|
||||
item.second.handles.end();
|
||||
});
|
||||
if (it != directory_lookup_.end()) {
|
||||
utils::collection::remove_element(it->second.handles, handle);
|
||||
if (it->second.handles.empty()) {
|
||||
directory_lookup_.erase(it);
|
||||
}
|
||||
}
|
||||
if (iter == directory_lookup_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
void directory_cache::service_function() {
|
||||
unique_recur_mutex_lock directory_lock(directory_mutex_);
|
||||
auto lookup = directory_lookup_;
|
||||
directory_lock.unlock();
|
||||
|
||||
for (auto &&kv : lookup) {
|
||||
if (std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now() - kv.second.last_update) >= 120s) {
|
||||
directory_lock.lock();
|
||||
directory_lookup_.erase(kv.first);
|
||||
directory_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (not get_stop_requested()) {
|
||||
unique_mutex_lock shutdown_lock(get_mutex());
|
||||
if (not get_stop_requested()) {
|
||||
get_notify().wait_for(shutdown_lock, 15s);
|
||||
}
|
||||
utils::collection::remove_element(iter->second.handles, handle);
|
||||
if (iter->second.handles.empty()) {
|
||||
directory_lookup_.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,11 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
|
||||
-> int {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
if (offset < items_.size()) {
|
||||
if (offset >= items_.size()) {
|
||||
errno = 120;
|
||||
return -1;
|
||||
}
|
||||
|
||||
try {
|
||||
std::string item_name;
|
||||
struct stat st{};
|
||||
@ -58,11 +62,12 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
if (filler_function(buffer, item_name.data(), pst,
|
||||
static_cast<off_t>(offset + 1),
|
||||
FUSE_FILL_DIR_PLUS) != 0) {
|
||||
#else
|
||||
FUSE_FILL_DIR_PLUS) != 0)
|
||||
#else // FUSE_USE_VERSION < 30
|
||||
if (filler_function(buffer, item_name.data(), pst,
|
||||
static_cast<off_t>(offset + 1)) != 0) {
|
||||
#endif
|
||||
static_cast<off_t>(offset + 1)) != 0)
|
||||
#endif // FUSE_USE_VERSION >= 30
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
@ -73,30 +78,26 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
auto directory_iterator::get(std::size_t offset, std::string &item) -> int {
|
||||
if (offset >= items_.size()) {
|
||||
errno = 120;
|
||||
return -1;
|
||||
}
|
||||
#endif // !_WIN32
|
||||
|
||||
auto directory_iterator::get(std::size_t offset, std::string &item) -> int {
|
||||
if (offset < items_.size()) {
|
||||
item = items_[offset].api_path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = 120;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto directory_iterator::get_directory_item(std::size_t offset,
|
||||
directory_item &di) -> api_error {
|
||||
if (offset < items_.size()) {
|
||||
di = items_[offset];
|
||||
return api_error::success;
|
||||
if (offset >= items_.size()) {
|
||||
return api_error::directory_end_of_files;
|
||||
}
|
||||
|
||||
return api_error::directory_end_of_files;
|
||||
di = items_[offset];
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto directory_iterator::get_directory_item(const std::string &api_path,
|
||||
@ -105,24 +106,24 @@ auto directory_iterator::get_directory_item(const std::string &api_path,
|
||||
std::find_if(items_.begin(), items_.end(), [&](const auto &item) -> bool {
|
||||
return api_path == item.api_path;
|
||||
});
|
||||
if (iter != items_.end()) {
|
||||
if (iter == items_.end()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
di = *iter;
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto directory_iterator::get_json(std::size_t offset, json &item) -> int {
|
||||
if (offset < items_.size()) {
|
||||
item = json(items_.at(offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset >= items_.size()) {
|
||||
errno = 120;
|
||||
return -1;
|
||||
}
|
||||
|
||||
item = json(items_.at(offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto directory_iterator::get_next_directory_offset(
|
||||
const std::string &api_path) const -> std::size_t {
|
||||
const auto iter = std::find_if(items_.begin(), items_.end(),
|
||||
|
@ -632,7 +632,7 @@ auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
|
||||
}
|
||||
|
||||
const auto option_parts = utils::string::split(options, ',', true);
|
||||
for (auto &&option : option_parts) {
|
||||
for (const auto &option : option_parts) {
|
||||
if (option.find("gid") == 0) {
|
||||
const auto parts = utils::string::split(option, '=', true);
|
||||
if (parts.size() == 2u) {
|
||||
|
@ -246,11 +246,12 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
void fuse_drive::destroy_impl(void *ptr) {
|
||||
void fuse_drive::stop_all() {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
event_system::instance().raise<drive_unmount_pending>(get_mount_location());
|
||||
mutex_lock lock(stop_all_mtx_);
|
||||
|
||||
auto future = std::async(std::launch::async, [this]() {
|
||||
remote_server_.reset();
|
||||
|
||||
if (server_) {
|
||||
@ -269,25 +270,35 @@ void fuse_drive::destroy_impl(void *ptr) {
|
||||
|
||||
provider_.stop();
|
||||
|
||||
if (directory_cache_) {
|
||||
directory_cache_->stop();
|
||||
}
|
||||
|
||||
directory_cache_.reset();
|
||||
eviction_.reset();
|
||||
server_.reset();
|
||||
|
||||
fm_.reset();
|
||||
});
|
||||
|
||||
event_system::instance().raise<drive_unmounted>(get_mount_location());
|
||||
|
||||
config_.save();
|
||||
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<drive_unmount_pending>(get_mount_location());
|
||||
|
||||
stop_all();
|
||||
|
||||
config_.save();
|
||||
|
||||
fuse_base::destroy_impl(ptr);
|
||||
|
||||
event_system::instance().raise<drive_unmounted>(get_mount_location());
|
||||
}
|
||||
|
||||
auto fuse_drive::fallocate_impl(std::string /*api_path*/, int mode,
|
||||
@ -486,17 +497,6 @@ auto fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st)
|
||||
return res;
|
||||
}
|
||||
|
||||
auto found = false;
|
||||
directory_cache_->execute_action(parent, [&](directory_iterator &iter) {
|
||||
directory_item dir_item{};
|
||||
found = (iter.get_directory_item(api_path, dir_item) == api_error::success);
|
||||
if (found) {
|
||||
fuse_drive_base::populate_stat(api_path, dir_item.size, dir_item.meta,
|
||||
dir_item.directory, provider_, unix_st);
|
||||
}
|
||||
});
|
||||
|
||||
if (not found) {
|
||||
api_meta_map meta{};
|
||||
res = provider_.get_item_meta(api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
@ -506,7 +506,6 @@ auto fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st)
|
||||
fuse_drive_base::populate_stat(
|
||||
api_path, utils::string::to_uint64(meta[META_SIZE]), meta,
|
||||
utils::string::to_bool(meta[META_DIRECTORY]), provider_, unix_st);
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
}
|
||||
@ -568,6 +567,7 @@ void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||
auto *ret = fuse_drive_base::init_impl(conn);
|
||||
#endif
|
||||
|
||||
try {
|
||||
if (console_enabled_) {
|
||||
console_consumer_ =
|
||||
std::make_unique<console_consumer>(config_.get_event_level());
|
||||
@ -583,10 +583,8 @@ void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||
if (not provider_.is_read_only()) {
|
||||
eviction_ = std::make_unique<eviction>(provider_, config_, *fm_);
|
||||
}
|
||||
directory_cache_ = std::make_unique<directory_cache>();
|
||||
|
||||
try {
|
||||
directory_cache_->start();
|
||||
directory_cache_ = std::make_unique<directory_cache>();
|
||||
server_->start();
|
||||
|
||||
if (not provider_.start(
|
||||
@ -607,12 +605,12 @@ void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||
config_, *this, get_mount_location());
|
||||
}
|
||||
|
||||
polling::instance().start(&config_);
|
||||
|
||||
if (not lock_data_.set_mount_state(true, get_mount_location(), getpid())) {
|
||||
utils::error::raise_error(function_name, "failed to set mount state");
|
||||
}
|
||||
|
||||
polling::instance().start(&config_);
|
||||
|
||||
event_system::instance().raise<drive_mounted>(get_mount_location());
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_error(function_name, e, "exception during fuse init");
|
||||
@ -892,19 +890,7 @@ auto fuse_drive::getxattr_common(std::string api_path, const char *name,
|
||||
}
|
||||
|
||||
api_meta_map meta;
|
||||
auto found{false};
|
||||
directory_cache_->execute_action(
|
||||
utils::path::get_parent_api_path(api_path),
|
||||
[&](directory_iterator &iterator) {
|
||||
directory_item dir_item{};
|
||||
found = (iterator.get_directory_item(api_path, dir_item) ==
|
||||
api_error::success);
|
||||
if (found) {
|
||||
meta = dir_item.meta;
|
||||
}
|
||||
});
|
||||
|
||||
res = found ? api_error::success : provider_.get_item_meta(api_path, meta);
|
||||
res = provider_.get_item_meta(api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
@ -958,7 +944,7 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
||||
api_meta_map meta;
|
||||
res = provider_.get_item_meta(api_path, meta);
|
||||
if (res == api_error::success) {
|
||||
for (auto &&meta_item : meta) {
|
||||
for (const auto &meta_item : meta) {
|
||||
if (utils::collection::excludes(META_USED_NAMES, meta_item.first)) {
|
||||
auto attribute_name = meta_item.first;
|
||||
#if defined(__APPLE__)
|
||||
|
@ -41,13 +41,13 @@ namespace repertory::remote_fuse {
|
||||
#define RAISE_REMOTE_FUSE_SERVER_EVENT(func, file, ret) \
|
||||
if (config_.get_enable_drive_events() && \
|
||||
(((config_.get_event_level() >= remote_fuse_server_event::level) && \
|
||||
(ret < 0)) || \
|
||||
((ret) < 0)) || \
|
||||
(config_.get_event_level() >= event_level::trace))) \
|
||||
event_system::instance().raise<remote_fuse_server_event>(std::string{func}, \
|
||||
file, ret)
|
||||
|
||||
// clang-format off
|
||||
E_SIMPLE3(remote_fuse_server_event, debug, true,
|
||||
E_SIMPLE3(remote_fuse_server_event, debug,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
packet::error_type, result, res, E_FROM_INT32
|
||||
@ -208,8 +208,8 @@ auto remote_server::fuse_access(const char *path, const std::int32_t &mask)
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_chflags(const char *path,
|
||||
std::uint32_t flags) -> packet::error_type {
|
||||
auto remote_server::fuse_chflags(const char *path, std::uint32_t flags)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -321,9 +321,10 @@ length); ret = ((res < 0) ? -errno : 0); #endif
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
auto remote_server::fuse_fgetattr(
|
||||
const char *path, remote::stat &r_stat, bool &directory,
|
||||
const remote::file_handle &handle) -> packet::error_type {
|
||||
auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat,
|
||||
bool &directory,
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
r_stat = {};
|
||||
@ -345,9 +346,10 @@ auto remote_server::fuse_fgetattr(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_fsetattr_x(
|
||||
const char *path, const remote::setattr_x &attr,
|
||||
const remote::file_handle &handle) -> packet::error_type {
|
||||
auto remote_server::fuse_fsetattr_x(const char *path,
|
||||
const remote::setattr_x &attr,
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -463,9 +465,10 @@ auto remote_server::fuse_fsync(const char *path, const std::int32_t &datasync,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_ftruncate(
|
||||
const char *path, const remote::file_offset &size,
|
||||
const remote::file_handle &handle) -> packet::error_type {
|
||||
auto remote_server::fuse_ftruncate(const char *path,
|
||||
const remote::file_offset &size,
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
@ -558,9 +561,10 @@ STATUS_NOT_IMPLEMENTED; #endif RAISE_REMOTE_FUSE_SERVER_EVENT(function_name,
|
||||
file_path, ret); return ret;
|
||||
}*/
|
||||
|
||||
auto remote_server::fuse_getxtimes(
|
||||
const char *path, remote::file_time &bkuptime,
|
||||
remote::file_time &crtime) -> packet::error_type {
|
||||
auto remote_server::fuse_getxtimes(const char *path,
|
||||
remote::file_time &bkuptime,
|
||||
remote::file_time &crtime)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -665,10 +669,11 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_read(
|
||||
const char *path, char *buffer, const remote::file_size &read_size,
|
||||
auto remote_server::fuse_read(const char *path, char *buffer,
|
||||
const remote::file_size &read_size,
|
||||
const remote::file_offset &read_offset,
|
||||
const remote::file_handle &handle) -> packet::error_type {
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
@ -689,8 +694,8 @@ auto remote_server::fuse_read(
|
||||
return static_cast<packet::error_type>(ret);
|
||||
}
|
||||
|
||||
auto remote_server::fuse_rename(const char *from,
|
||||
const char *to) -> packet::error_type {
|
||||
auto remote_server::fuse_rename(const char *from, const char *to)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto from_path = utils::path::combine(mount_location_, {from});
|
||||
@ -728,8 +733,9 @@ auto remote_server::fuse_readdir(const char *path,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_release(
|
||||
const char *path, const remote::file_handle &handle) -> packet::error_type {
|
||||
auto remote_server::fuse_release(const char *path,
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
packet::error_type ret = 0;
|
||||
@ -746,8 +752,9 @@ auto remote_server::fuse_release(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_releasedir(
|
||||
const char *path, const remote::file_handle &handle) -> packet::error_type {
|
||||
auto remote_server::fuse_releasedir(const char *path,
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
@ -792,8 +799,9 @@ auto remote_server::fuse_setattr_x(const char *path, remote::setattr_x &attr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_setbkuptime(
|
||||
const char *path, const remote::file_time &bkuptime) -> packet::error_type {
|
||||
auto remote_server::fuse_setbkuptime(const char *path,
|
||||
const remote::file_time &bkuptime)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -812,8 +820,9 @@ auto remote_server::fuse_setbkuptime(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_setchgtime(
|
||||
const char *path, const remote::file_time &chgtime) -> packet::error_type {
|
||||
auto remote_server::fuse_setchgtime(const char *path,
|
||||
const remote::file_time &chgtime)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -832,8 +841,9 @@ auto remote_server::fuse_setchgtime(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_setcrtime(
|
||||
const char *path, const remote::file_time &crtime) -> packet::error_type {
|
||||
auto remote_server::fuse_setcrtime(const char *path,
|
||||
const remote::file_time &crtime)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -924,8 +934,9 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_truncate(
|
||||
const char *path, const remote::file_offset &size) -> packet::error_type {
|
||||
auto remote_server::fuse_truncate(const char *path,
|
||||
const remote::file_offset &size)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
@ -946,8 +957,8 @@ auto remote_server::fuse_unlink(const char *path) -> packet::error_type {
|
||||
}
|
||||
|
||||
auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
std::uint64_t op0,
|
||||
std::uint64_t op1) -> packet::error_type {
|
||||
std::uint64_t op0, std::uint64_t op1)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
@ -974,10 +985,11 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::fuse_write(
|
||||
const char *path, const char *buffer, const remote::file_size &write_size,
|
||||
auto remote_server::fuse_write(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) -> packet::error_type {
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
@ -1007,8 +1019,8 @@ auto remote_server::fuse_write_base64(
|
||||
}
|
||||
|
||||
// WinFSP Layer
|
||||
auto remote_server::winfsp_can_delete(PVOID file_desc,
|
||||
PWSTR file_name) -> packet::error_type {
|
||||
auto remote_server::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto relative_path = utils::string::to_utf8(file_name);
|
||||
@ -1033,8 +1045,8 @@ auto remote_server::winfsp_can_delete(PVOID file_desc,
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_cleanup(PVOID /*file_desc*/, PWSTR file_name,
|
||||
UINT32 flags,
|
||||
BOOLEAN &was_deleted) -> packet::error_type {
|
||||
UINT32 flags, BOOLEAN &was_deleted)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto relative_path = utils::string::to_utf8(file_name);
|
||||
@ -1111,8 +1123,8 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
|
||||
UINT32 granted_access, UINT32 attributes,
|
||||
UINT64 /*allocation_size*/, PVOID *file_desc,
|
||||
remote::file_info *file_info,
|
||||
std::string &normalized_name,
|
||||
BOOLEAN &exists) -> packet::error_type {
|
||||
std::string &normalized_name, BOOLEAN &exists)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto relative_path = utils::string::to_utf8(file_name);
|
||||
@ -1184,8 +1196,9 @@ auto remote_server::winfsp_flush(PVOID file_desc, remote::file_info *file_info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_get_file_info(
|
||||
PVOID file_desc, remote::file_info *file_info) -> packet::error_type {
|
||||
auto remote_server::winfsp_get_file_info(PVOID file_desc,
|
||||
remote::file_info *file_info)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||
@ -1228,9 +1241,10 @@ auto remote_server::winfsp_get_security_by_name(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_get_volume_info(
|
||||
UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) -> packet::error_type {
|
||||
auto remote_server::winfsp_get_volume_info(UINT64 &total_size,
|
||||
UINT64 &free_size,
|
||||
std::string &volume_label)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
drive_.get_volume_info(total_size, free_size, volume_label);
|
||||
@ -1247,10 +1261,11 @@ auto remote_server::winfsp_mounted(const std::wstring &location)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_open(
|
||||
PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
PVOID *file_desc, remote::file_info *file_info,
|
||||
std::string &normalized_name) -> packet::error_type {
|
||||
auto remote_server::winfsp_open(PWSTR file_name, UINT32 create_options,
|
||||
UINT32 granted_access, PVOID *file_desc,
|
||||
remote::file_info *file_info,
|
||||
std::string &normalized_name)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto relative_path = utils::string::to_utf8(file_name);
|
||||
@ -1291,10 +1306,11 @@ auto remote_server::winfsp_open(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_overwrite(
|
||||
PVOID file_desc, UINT32 attributes, BOOLEAN replace_attributes,
|
||||
auto remote_server::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
|
||||
BOOLEAN replace_attributes,
|
||||
UINT64 /*allocation_size*/,
|
||||
remote::file_info *file_info) -> packet::error_type {
|
||||
remote::file_info *file_info)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||
@ -1410,9 +1426,10 @@ auto remote_server::winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_rename(
|
||||
PVOID /*file_desc*/, PWSTR file_name, PWSTR new_file_name,
|
||||
BOOLEAN replace_if_exists) -> packet::error_type {
|
||||
auto remote_server::winfsp_rename(PVOID /*file_desc*/, PWSTR file_name,
|
||||
PWSTR new_file_name,
|
||||
BOOLEAN replace_if_exists)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto relative_path = utils::string::to_utf8(file_name);
|
||||
@ -1506,9 +1523,10 @@ auto remote_server::winfsp_set_basic_info(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_set_file_size(
|
||||
PVOID file_desc, UINT64 new_size, BOOLEAN set_allocation_size,
|
||||
remote::file_info *file_info) -> packet::error_type {
|
||||
auto remote_server::winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
|
||||
BOOLEAN set_allocation_size,
|
||||
remote::file_info *file_info)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||
@ -1544,10 +1562,12 @@ auto remote_server::winfsp_unmounted(const std::wstring &location)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
auto remote_server::winfsp_write(
|
||||
PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
BOOLEAN write_to_end, BOOLEAN constrained_io, PUINT32 bytes_transferred,
|
||||
remote::file_info *file_info) -> packet::error_type {
|
||||
auto remote_server::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
|
||||
UINT32 length, BOOLEAN write_to_end,
|
||||
BOOLEAN constrained_io,
|
||||
PUINT32 bytes_transferred,
|
||||
remote::file_info *file_info)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
*bytes_transferred = 0;
|
||||
@ -1595,8 +1615,9 @@ auto remote_server::winfsp_write(
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_server::json_create_directory_snapshot(
|
||||
const std::string &path, json &json_data) -> packet::error_type {
|
||||
auto remote_server::json_create_directory_snapshot(const std::string &path,
|
||||
json &json_data)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto api_path = utils::path::create_api_path(path);
|
||||
@ -1655,8 +1676,8 @@ auto remote_server::json_read_directory_snapshot(
|
||||
}
|
||||
|
||||
auto remote_server::json_release_directory_snapshot(
|
||||
const std::string &path,
|
||||
const remote::file_handle &handle) -> packet::error_type {
|
||||
const std::string &path, const remote::file_handle &handle)
|
||||
-> packet::error_type {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
const auto file_path = construct_path(path);
|
||||
|
@ -65,7 +65,7 @@ void remote_open_file_table::close_all(const std::string &client_id) {
|
||||
});
|
||||
lock.unlock();
|
||||
|
||||
for (auto &&handle : compat_handles) {
|
||||
for (const auto &handle : compat_handles) {
|
||||
#if defined(_WIN32)
|
||||
_close(static_cast<int>(handle));
|
||||
#else
|
||||
@ -74,7 +74,7 @@ void remote_open_file_table::close_all(const std::string &client_id) {
|
||||
remove_compat_open_info(handle);
|
||||
}
|
||||
|
||||
for (auto &&handle : handles) {
|
||||
for (const auto &handle : handles) {
|
||||
#if defined(_WIN32)
|
||||
::CloseHandle(handle);
|
||||
#else // !defined(_WIN32)
|
||||
@ -85,14 +85,14 @@ void remote_open_file_table::close_all(const std::string &client_id) {
|
||||
|
||||
std::vector<std::uint64_t> dirs;
|
||||
lock.lock();
|
||||
for (auto &&kv : directory_lookup_) {
|
||||
for (const auto &kv : directory_lookup_) {
|
||||
if (kv.first == client_id) {
|
||||
dirs.insert(dirs.end(), kv.second.begin(), kv.second.end());
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
|
||||
for (auto &&dir : dirs) {
|
||||
for (const auto &dir : dirs) {
|
||||
remove_directory(client_id, dir);
|
||||
}
|
||||
}
|
||||
@ -185,11 +185,11 @@ void remote_open_file_table::remove_all(const std::string &file_path) {
|
||||
});
|
||||
lock.unlock();
|
||||
|
||||
for (auto &&handle : compat_open_list) {
|
||||
for (const auto &handle : compat_open_list) {
|
||||
remove_compat_open_info(handle);
|
||||
}
|
||||
|
||||
for (auto &&handle : open_list) {
|
||||
for (const auto &handle : open_list) {
|
||||
remove_open_info(handle);
|
||||
}
|
||||
}
|
||||
@ -262,7 +262,7 @@ void remote_open_file_table::remove_and_close_all(const native_handle &handle) {
|
||||
auto op_info = *file_lookup_.at(handle_lookup_.at(handle));
|
||||
lock.unlock();
|
||||
|
||||
for (auto &&open_handle : op_info.handles) {
|
||||
for (const auto &open_handle : op_info.handles) {
|
||||
#if defined(_WIN32)
|
||||
::CloseHandle(open_handle);
|
||||
#else // !defined(_WIN32)
|
||||
|
@ -33,13 +33,13 @@ namespace repertory::remote_winfsp {
|
||||
#define RAISE_REMOTE_WINFSP_CLIENT_EVENT(func, file, ret) \
|
||||
if (config_.get_enable_drive_events() && \
|
||||
(((config_.get_event_level() >= remote_winfsp_client_event::level) && \
|
||||
(ret != STATUS_SUCCESS)) || \
|
||||
((ret) != STATUS_SUCCESS)) || \
|
||||
(config_.get_event_level() >= event_level::trace))) \
|
||||
event_system::instance().raise<remote_winfsp_client_event>( \
|
||||
std::string{func}, file, ret)
|
||||
|
||||
// clang-format off
|
||||
E_SIMPLE3(remote_winfsp_client_event, debug, true,
|
||||
E_SIMPLE3(remote_winfsp_client_event, debug,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
packet::error_type, result, res, E_FROM_INT32
|
||||
|
@ -47,13 +47,13 @@ namespace repertory::remote_winfsp {
|
||||
#define RAISE_REMOTE_WINFSP_SERVER_EVENT(func, file, ret) \
|
||||
if (config_.get_enable_drive_events() && \
|
||||
(((config_.get_event_level() >= remote_winfsp_server_event::level) && \
|
||||
(ret != STATUS_SUCCESS)) || \
|
||||
((ret) != STATUS_SUCCESS)) || \
|
||||
(config_.get_event_level() >= event_level::trace))) \
|
||||
event_system::instance().raise<remote_winfsp_server_event>( \
|
||||
std::string{func}, file, ret)
|
||||
|
||||
// clang-format off
|
||||
E_SIMPLE3(remote_winfsp_server_event, debug, true,
|
||||
E_SIMPLE3(remote_winfsp_server_event, debug,
|
||||
std::string, function, FUNC, E_FROM_STRING,
|
||||
std::string, api_path, AP, E_FROM_STRING,
|
||||
packet::error_type, result, RES, E_FROM_INT32
|
||||
|
@ -238,7 +238,7 @@ auto remote_winfsp_drive::mount(const std::vector<std::string> &drive_args)
|
||||
auto force_no_console = utils::collection::includes(drive_args, "-nc");
|
||||
|
||||
auto enable_console = false;
|
||||
for (auto &&arg : drive_args) {
|
||||
for (const auto &arg : drive_args) {
|
||||
if (arg == "-f") {
|
||||
if (not force_no_console) {
|
||||
enable_console = true;
|
||||
@ -352,7 +352,7 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
||||
directory_buffer, static_cast<BOOLEAN>(nullptr == marker),
|
||||
&ret)) {
|
||||
auto item_found = false;
|
||||
for (auto &&item : item_list) {
|
||||
for (const auto &item : item_list) {
|
||||
auto item_path = item["path"].get<std::string>();
|
||||
auto display_name = utils::string::from_utf8(
|
||||
utils::path::strip_to_file_name(item_path));
|
||||
|
@ -39,15 +39,20 @@
|
||||
#include "utils/polling.hpp"
|
||||
#include "utils/string.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/timeout.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE3(winfsp_event, debug, true,
|
||||
E_SIMPLE3(winfsp_event, debug,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
NTSTATUS, result, res, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE(drive_stop_begin, info);
|
||||
E_SIMPLE(drive_stop_end, info);
|
||||
E_SIMPLE(drive_stop_timed_out, info);
|
||||
// clang-format on
|
||||
|
||||
#define RAISE_WINFSP_EVENT(func, file, ret) \
|
||||
@ -100,7 +105,9 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/)
|
||||
((mount_location.size() == 3U) && (mount_location[2U] == '\\'))) &&
|
||||
(mount_location[1U] == ':');
|
||||
|
||||
auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED;
|
||||
auto ret{
|
||||
drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED,
|
||||
};
|
||||
if ((drive_letter && not utils::file::directory(mount_location).exists())) {
|
||||
auto unicode_mount_location = utils::string::from_utf8(mount_location);
|
||||
host_.SetFileSystemName(unicode_mount_location.data());
|
||||
@ -116,14 +123,16 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/)
|
||||
<< mount_location << std::endl;
|
||||
}
|
||||
|
||||
if (ret != STATUS_SUCCESS) {
|
||||
if (not lock_.set_mount_state(false, "", -1)) {
|
||||
utils::error::raise_error(function_name, ret,
|
||||
"failed to set mount state");
|
||||
if (ret == STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (not lock_.set_mount_state(false, "", -1)) {
|
||||
utils::error::raise_error(function_name, ret, "failed to set mount state");
|
||||
}
|
||||
|
||||
event_system::instance().raise<drive_mount_failed>(mount_location,
|
||||
std::to_string(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -131,8 +140,20 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/)
|
||||
auto winfsp_drive::winfsp_service::OnStop() -> NTSTATUS {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
event_system::instance().raise<drive_stop_begin>();
|
||||
|
||||
timeout stop_timeout(
|
||||
[]() {
|
||||
event_system::instance().raise<drive_stop_timed_out>();
|
||||
app_config::set_stop_requested();
|
||||
},
|
||||
30s);
|
||||
host_.Unmount();
|
||||
|
||||
stop_timeout.disable();
|
||||
|
||||
event_system::instance().raise<drive_stop_end>();
|
||||
|
||||
if (not lock_.set_mount_state(false, "", -1)) {
|
||||
utils::error::raise_error(function_name, "failed to set mount state");
|
||||
}
|
||||
@ -583,7 +604,7 @@ auto winfsp_drive::mount(const std::vector<std::string> &drive_args) -> int {
|
||||
auto force_no_console = utils::collection::includes(drive_args, "-nc");
|
||||
|
||||
auto enable_console = false;
|
||||
for (auto &&arg : drive_args) {
|
||||
for (const auto &arg : drive_args) {
|
||||
if (arg == "-f") {
|
||||
if (not force_no_console) {
|
||||
enable_console = true;
|
||||
@ -605,13 +626,14 @@ auto winfsp_drive::mount(const std::vector<std::string> &drive_args) -> int {
|
||||
event_system::instance().raise<drive_mount_result>(std::to_string(ret));
|
||||
event_system::instance().stop();
|
||||
cons.reset();
|
||||
|
||||
return static_cast<int>(ret);
|
||||
}
|
||||
|
||||
auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
auto ret{STATUS_SUCCESS};
|
||||
try {
|
||||
if (not utils::file::change_to_process_directory()) {
|
||||
return static_cast<NTSTATUS>(utils::get_last_error_code());
|
||||
}
|
||||
@ -619,14 +641,15 @@ auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
|
||||
auto *file_system_host{
|
||||
reinterpret_cast<FileSystemHost *>(host),
|
||||
};
|
||||
|
||||
fm_ = std::make_unique<file_manager>(config_, provider_);
|
||||
server_ = std::make_unique<full_server>(config_, provider_, *fm_);
|
||||
if (not provider_.is_read_only()) {
|
||||
eviction_ = std::make_unique<eviction>(provider_, config_, *fm_);
|
||||
}
|
||||
|
||||
try {
|
||||
server_->start();
|
||||
|
||||
if (not provider_.start(
|
||||
[this](bool directory, api_file &file) -> api_error {
|
||||
return provider_meta_handler(provider_, directory, file);
|
||||
@ -646,30 +669,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<drive_mounted>(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 +1170,53 @@ auto winfsp_drive::SetFileSize(PVOID /*file_node*/, PVOID file_desc,
|
||||
}));
|
||||
}
|
||||
|
||||
void winfsp_drive::stop_all() {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
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<FileSystemHost *>(host);
|
||||
auto mount_location = parse_mount_location(file_system_host->MountPoint());
|
||||
event_system::instance().raise<drive_unmount_pending>(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<drive_unmounted>(mount_location);
|
||||
config_.save();
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "events/event.hpp"
|
||||
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace repertory {
|
||||
auto event_level_from_string(std::string level,
|
||||
event_level default_level) -> event_level {
|
||||
level = utils::string::to_lower(level);
|
||||
if (level == "critical" || level == "event_level::critical") {
|
||||
return event_level::critical;
|
||||
}
|
||||
|
||||
if (level == "debug" || level == "event_level::debug") {
|
||||
return event_level::debug;
|
||||
}
|
||||
|
||||
if (level == "warn" || level == "event_level::warn") {
|
||||
return event_level::warn;
|
||||
}
|
||||
|
||||
if (level == "info" || level == "event_level::info") {
|
||||
return event_level::info;
|
||||
}
|
||||
|
||||
if (level == "error" || level == "event_level::error") {
|
||||
return event_level::error;
|
||||
}
|
||||
|
||||
if (level == "trace" || level == "event_level::trace") {
|
||||
return event_level::trace;
|
||||
}
|
||||
|
||||
return default_level;
|
||||
}
|
||||
|
||||
auto event_level_to_string(event_level level) -> std::string {
|
||||
switch (level) {
|
||||
case event_level::critical:
|
||||
return "critical";
|
||||
case event_level::debug:
|
||||
return "debug";
|
||||
case event_level::error:
|
||||
return "error";
|
||||
case event_level::info:
|
||||
return "info";
|
||||
case event_level::warn:
|
||||
return "warn";
|
||||
case event_level::trace:
|
||||
return "trace";
|
||||
default:
|
||||
return "info";
|
||||
}
|
||||
}
|
||||
} // namespace repertory
|
@ -29,12 +29,12 @@
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(invalid_cache_size, warn, true,
|
||||
E_SIMPLE2(invalid_cache_size, warn,
|
||||
std::uint64_t, cache_size, sz, E_FROM_UINT64,
|
||||
std::uint64_t, by, by, E_FROM_UINT64
|
||||
);
|
||||
|
||||
E_SIMPLE2(max_cache_size_reached, warn, true,
|
||||
E_SIMPLE2(max_cache_size_reached, warn,
|
||||
std::uint64_t, cache_size, sz, E_FROM_UINT64,
|
||||
std::uint64_t, max_cache_size, max, E_FROM_UINT64
|
||||
);
|
||||
@ -42,32 +42,44 @@ E_SIMPLE2(max_cache_size_reached, warn, true,
|
||||
|
||||
cache_size_mgr cache_size_mgr::instance_{};
|
||||
|
||||
// TODO add timeout
|
||||
auto cache_size_mgr::expand(std::uint64_t size) -> api_error {
|
||||
if (size == 0U) {
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
unique_mutex_lock lock(mtx_);
|
||||
|
||||
if (cfg_ == nullptr) {
|
||||
notify_.notify_all();
|
||||
return api_error::cache_not_initialized;
|
||||
}
|
||||
|
||||
if (size == 0U) {
|
||||
notify_.notify_all();
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto last_cache_size{cache_size_};
|
||||
cache_size_ += size;
|
||||
|
||||
auto max_cache_size = cfg_->get_max_cache_size_bytes();
|
||||
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 &&
|
||||
auto cache_dir{
|
||||
utils::file::directory{cfg_->get_cache_directory()},
|
||||
};
|
||||
while (not get_stop_requested() && cache_size_ > max_cache_size &&
|
||||
cache_dir.count() > 1U) {
|
||||
if (last_cache_size != cache_size_) {
|
||||
event_system::instance().raise<max_cache_size_reached>(cache_size_,
|
||||
max_cache_size);
|
||||
notify_.wait(lock);
|
||||
last_cache_size = cache_size_;
|
||||
}
|
||||
notify_.wait_for(lock, cache_wait_secs);
|
||||
}
|
||||
|
||||
notify_.notify_all();
|
||||
|
||||
return api_error::success;
|
||||
return get_stop_requested() ? api_error::error : 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) {
|
||||
@ -80,7 +92,9 @@ void cache_size_mgr::initialize(app_config *cfg) {
|
||||
|
||||
stop_requested_ = false;
|
||||
|
||||
auto cache_dir = utils::file::directory{cfg_->get_cache_directory()};
|
||||
auto cache_dir{
|
||||
utils::file::directory{cfg_->get_cache_directory()},
|
||||
};
|
||||
if (not cache_dir.create_directory()) {
|
||||
throw startup_exception(fmt::format("failed to create cache directory|{}",
|
||||
cache_dir.get_path()));
|
||||
|
@ -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<i_file_mgr_db::resume_entry> {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
@ -1023,7 +1027,7 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
|
||||
evt.get_api_path(), evt.get_source(), err);
|
||||
|
||||
queue_upload(evt.get_api_path(), evt.get_source(), true);
|
||||
upload_notify_.wait_for(upload_lock, 5s);
|
||||
upload_notify_.wait_for(upload_lock, queue_wait_secs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -1087,7 +1091,7 @@ void file_manager::upload_handler() {
|
||||
}
|
||||
|
||||
if (should_wait) {
|
||||
upload_notify_.wait_for(upload_lock, 5s);
|
||||
upload_notify_.wait_for(upload_lock, queue_wait_secs);
|
||||
}
|
||||
|
||||
upload_notify_.notify_all();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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_item> 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_item> 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_item> 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) {
|
||||
if (online) {
|
||||
continue;
|
||||
}
|
||||
|
||||
event_system::instance().raise<provider_offline>(
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 <utils/config.hpp>
|
||||
|
||||
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");
|
||||
@ -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<reader_info>()};
|
||||
info->reader = std::make_unique<utils::encryption::encrypting_reader>(
|
||||
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<reader_info>()};
|
||||
info->reader = std::make_unique<utils::encryption::encrypting_reader>(
|
||||
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<i_file_db::file_info> 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*/,
|
||||
|
@ -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<utils::encryption::encrypting_reader>(
|
||||
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{};
|
||||
|
@ -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{};
|
||||
|
@ -137,7 +137,10 @@ void server::start() {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
mutex_lock lock(start_stop_mutex_);
|
||||
if (not started_) {
|
||||
if (server_thread_) {
|
||||
return;
|
||||
}
|
||||
|
||||
event_system::instance().raise<service_started>("server");
|
||||
server_ = std::make_unique<httplib::Server>();
|
||||
|
||||
@ -176,24 +179,29 @@ void server::start() {
|
||||
|
||||
server_thread_ = std::make_unique<std::thread>(
|
||||
[this]() { server_->listen("127.0.0.1", config_.get_api_port()); });
|
||||
|
||||
started_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void server::stop() {
|
||||
if (started_) {
|
||||
mutex_lock l(start_stop_mutex_);
|
||||
if (started_) {
|
||||
unique_mutex_lock lock(start_stop_mutex_);
|
||||
if (not server_thread_) {
|
||||
return;
|
||||
}
|
||||
|
||||
event_system::instance().raise<service_shutdown_begin>("server");
|
||||
|
||||
server_->stop();
|
||||
server_thread_->join();
|
||||
server_thread_.reset();
|
||||
|
||||
started_ = false;
|
||||
std::unique_ptr<std::thread> thread{nullptr};
|
||||
std::swap(thread, server_thread_);
|
||||
lock.unlock();
|
||||
|
||||
thread->join();
|
||||
thread.reset();
|
||||
|
||||
lock.lock();
|
||||
server_.reset();
|
||||
lock.unlock();
|
||||
|
||||
event_system::instance().raise<service_shutdown_end>("server");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@ -81,6 +81,54 @@ auto download_type_to_string(const download_type &type) -> std::string {
|
||||
}
|
||||
}
|
||||
|
||||
auto event_level_from_string(std::string level, event_level default_level)
|
||||
-> event_level {
|
||||
level = utils::string::to_lower(level);
|
||||
if (level == "critical" || level == "event_level::critical") {
|
||||
return event_level::critical;
|
||||
}
|
||||
|
||||
if (level == "debug" || level == "event_level::debug") {
|
||||
return event_level::debug;
|
||||
}
|
||||
|
||||
if (level == "warn" || level == "event_level::warn") {
|
||||
return event_level::warn;
|
||||
}
|
||||
|
||||
if (level == "info" || level == "event_level::info") {
|
||||
return event_level::info;
|
||||
}
|
||||
|
||||
if (level == "error" || level == "event_level::error") {
|
||||
return event_level::error;
|
||||
}
|
||||
|
||||
if (level == "trace" || level == "event_level::trace") {
|
||||
return event_level::trace;
|
||||
}
|
||||
|
||||
return default_level;
|
||||
}
|
||||
|
||||
auto event_level_to_string(event_level level) -> std::string {
|
||||
switch (level) {
|
||||
case event_level::critical:
|
||||
return "critical";
|
||||
case event_level::debug:
|
||||
return "debug";
|
||||
case event_level::error:
|
||||
return "error";
|
||||
case event_level::info:
|
||||
return "info";
|
||||
case event_level::warn:
|
||||
return "warn";
|
||||
case event_level::trace:
|
||||
return "trace";
|
||||
default:
|
||||
return "info";
|
||||
}
|
||||
}
|
||||
static const std::unordered_map<api_error, std::string> LOOKUP = {
|
||||
{api_error::success, "success"},
|
||||
{api_error::access_denied, "access_denied"},
|
||||
|
@ -31,7 +31,7 @@ polling polling::instance_;
|
||||
|
||||
void polling::frequency_thread(
|
||||
std::function<std::uint32_t()> 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<tasks::task_ptr>{},
|
||||
@ -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);
|
||||
@ -138,15 +142,20 @@ void polling::stop() {
|
||||
}
|
||||
|
||||
event_system::instance().raise<service_shutdown_begin>("polling");
|
||||
|
||||
stop_requested_ = true;
|
||||
|
||||
tasks::instance().stop();
|
||||
|
||||
unique_mutex_lock thread_lock(mutex_);
|
||||
std::array<std::unique_ptr<std::thread>,
|
||||
static_cast<std::size_t>(frequency::size)>
|
||||
threads;
|
||||
std::swap(threads, frequency_threads_);
|
||||
notify_.notify_all();
|
||||
thread_lock.unlock();
|
||||
|
||||
for (auto &&thread : frequency_threads_) {
|
||||
for (auto &thread : threads) {
|
||||
thread->join();
|
||||
thread.reset();
|
||||
}
|
||||
|
@ -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();
|
||||
@ -33,33 +38,41 @@ void single_thread_service_base::notify_all() const {
|
||||
|
||||
void single_thread_service_base::start() {
|
||||
mutex_lock lock(mtx_);
|
||||
if (not thread_) {
|
||||
if (thread_) {
|
||||
return;
|
||||
}
|
||||
|
||||
stop_requested_ = false;
|
||||
on_start();
|
||||
thread_ = std::make_unique<std::thread>([this]() {
|
||||
event_system::instance().raise<service_started>(service_name_);
|
||||
while (not stop_requested_) {
|
||||
while (not get_stop_requested()) {
|
||||
service_function();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void single_thread_service_base::stop() {
|
||||
if (thread_) {
|
||||
event_system::instance().raise<service_shutdown_begin>(service_name_);
|
||||
unique_mutex_lock lock(mtx_);
|
||||
if (thread_) {
|
||||
if (not thread_) {
|
||||
return;
|
||||
}
|
||||
|
||||
event_system::instance().raise<service_shutdown_begin>(service_name_);
|
||||
|
||||
stop_requested_ = true;
|
||||
|
||||
std::unique_ptr<std::thread> thread{nullptr};
|
||||
std::swap(thread, thread_);
|
||||
|
||||
notify_.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
thread_->join();
|
||||
thread_.reset();
|
||||
thread->join();
|
||||
thread.reset();
|
||||
|
||||
on_stop();
|
||||
}
|
||||
|
||||
event_system::instance().raise<service_shutdown_end>(service_name_);
|
||||
}
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@ -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;
|
||||
@ -96,15 +100,17 @@ void tasks::stop() {
|
||||
stop_requested_ = true;
|
||||
|
||||
unique_mutex_lock lock(mutex_);
|
||||
std::vector<std::unique_ptr<std::jthread>> threads;
|
||||
std::swap(threads, task_threads_);
|
||||
|
||||
std::deque<scheduled_task> task_list;
|
||||
std::swap(task_list, tasks_);
|
||||
|
||||
notify_.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
task_threads_.clear();
|
||||
|
||||
lock.lock();
|
||||
tasks_.clear();
|
||||
notify_.notify_all();
|
||||
lock.unlock();
|
||||
threads.clear();
|
||||
task_list.clear();
|
||||
}
|
||||
|
||||
void tasks::task_thread() {
|
||||
@ -119,14 +125,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;
|
||||
}
|
||||
|
@ -27,7 +27,10 @@ namespace repertory {
|
||||
timeout::timeout(std::function<void()> timeout_callback,
|
||||
const std::chrono::system_clock::duration &duration)
|
||||
: timeout_killed_(duration == 0s) {
|
||||
if (not timeout_killed_) {
|
||||
if (timeout_killed_) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeout_thread_ =
|
||||
std::make_unique<std::thread>([this, duration, timeout_callback]() {
|
||||
unique_mutex_lock lock(timeout_mutex_);
|
||||
@ -39,16 +42,18 @@ timeout::timeout(std::function<void()> timeout_callback,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void timeout::disable() {
|
||||
if (not timeout_killed_) {
|
||||
if (timeout_killed_) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeout_killed_ = true;
|
||||
unique_mutex_lock lock(timeout_mutex_);
|
||||
timeout_notify_.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
timeout_thread_->join();
|
||||
timeout_thread_.reset();
|
||||
}
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@ -19,6 +19,8 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "rocksdb/table.h"
|
||||
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
#include "app_config.hpp"
|
||||
@ -38,12 +40,9 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_size > allocation_size) {
|
||||
allocation_size = file_size;
|
||||
}
|
||||
|
||||
allocation_size =
|
||||
utils::divide_with_ceiling(allocation_size, WINFSP_ALLOCATION_UNIT) *
|
||||
utils::divide_with_ceiling(std::max(file_size, allocation_size),
|
||||
WINFSP_ALLOCATION_UNIT) *
|
||||
WINFSP_ALLOCATION_UNIT;
|
||||
allocation_meta_size = std::to_string(allocation_size);
|
||||
}
|
||||
@ -51,8 +50,8 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
|
||||
auto create_rocksdb(
|
||||
const app_config &cfg, const std::string &name,
|
||||
const std::vector<rocksdb::ColumnFamilyDescriptor> &families,
|
||||
std::vector<rocksdb::ColumnFamilyHandle *> &handles,
|
||||
bool clear) -> std::unique_ptr<rocksdb::TransactionDB> {
|
||||
std::vector<rocksdb::ColumnFamilyHandle *> &handles, bool clear)
|
||||
-> std::unique_ptr<rocksdb::TransactionDB> {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
auto db_dir = utils::path::combine(cfg.get_data_directory(), {"db"});
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "fixtures/file_mgr_db_fixture.hpp"
|
||||
#include <utils/time.hpp>
|
||||
#include "utils/time.hpp"
|
||||
|
||||
namespace repertory {
|
||||
TYPED_TEST_CASE(file_mgr_db_test, file_mgr_db_types);
|
||||
|
@ -103,7 +103,7 @@ TYPED_TEST(fuse_test, access_directory_permutations_test) {
|
||||
std::string dir_name{"access_test"};
|
||||
auto dir_path = this->create_directory_and_test(dir_name);
|
||||
|
||||
for (auto &&permutation : access_permutations) {
|
||||
for (const auto &permutation : access_permutations) {
|
||||
perform_access_test(permutation, dir_path);
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ TYPED_TEST(fuse_test, access_file_permutations_test) {
|
||||
std::string file_name{"access_test"};
|
||||
auto file_path = this->create_file_and_test(file_name);
|
||||
|
||||
for (auto &&permutation : access_permutations) {
|
||||
for (const auto &permutation : access_permutations) {
|
||||
perform_access_test(permutation, file_path);
|
||||
}
|
||||
|
||||
|
@ -376,7 +376,7 @@ TYPED_TEST(fuse_test, create_fails_with_excl_if_path_is_directory) {
|
||||
std::string dir_name{"create_test"};
|
||||
auto dir_path = this->create_directory_and_test(dir_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(dir_path.c_str(), flags, ACCESSPERMS);
|
||||
EXPECT_EQ(-1, handle);
|
||||
|
||||
@ -396,7 +396,7 @@ TYPED_TEST(fuse_test, create_fails_with_excl_if_file_exists) {
|
||||
std::string file_name{"create_test"};
|
||||
auto file_path = this->create_file_and_test(file_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(file_path.c_str(), flags, ACCESSPERMS);
|
||||
EXPECT_EQ(-1, handle);
|
||||
|
||||
@ -420,7 +420,7 @@ TYPED_TEST(fuse_test, create_fails_if_path_is_directory) {
|
||||
std::string dir_name{"create_test"};
|
||||
auto dir_path = this->create_directory_and_test(dir_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(dir_path.c_str(), flags, ACCESSPERMS);
|
||||
EXPECT_EQ(-1, handle);
|
||||
|
||||
@ -447,7 +447,7 @@ TYPED_TEST(fuse_test, create_fails_if_parent_path_does_not_exist) {
|
||||
std::string file_name{"no_dir/create_test"};
|
||||
auto file_path = this->create_file_path(file_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(file_path.c_str(), flags, ACCESSPERMS);
|
||||
EXPECT_EQ(-1, handle);
|
||||
|
||||
@ -463,7 +463,7 @@ TYPED_TEST(fuse_test, create_fails_if_invalid) {
|
||||
std::string file_name{"create_test"};
|
||||
auto file_path = this->create_file_path(file_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(file_path.c_str(), flags, ACCESSPERMS);
|
||||
EXPECT_EQ(-1, handle);
|
||||
|
||||
@ -481,7 +481,7 @@ TYPED_TEST(fuse_test, create_open_fails_if_path_is_directory) {
|
||||
std::string dir_name{"create_test"};
|
||||
auto dir_path = this->create_directory_and_test(dir_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(dir_path.c_str(), flags);
|
||||
EXPECT_EQ(-1, handle);
|
||||
if (handle != -1) {
|
||||
@ -510,7 +510,7 @@ TYPED_TEST(fuse_test, create_open_fails_if_path_does_not_exist) {
|
||||
std::string file_name{"create_test"};
|
||||
auto file_path = this->create_file_path(file_name);
|
||||
|
||||
for (auto &&flags : ops) {
|
||||
for (const auto &flags : ops) {
|
||||
auto handle = open(file_path.c_str(), flags);
|
||||
EXPECT_EQ(-1, handle);
|
||||
EXPECT_EQ(ENOENT, errno);
|
||||
|
@ -97,7 +97,7 @@ TYPED_TEST(winfsp_test, cr8_file_can_delete_file_after_close) {
|
||||
|
||||
TYPED_TEST(winfsp_test,
|
||||
cr8_file_cannot_create_files_with_invalid_characters_in_path) {
|
||||
for (auto &&invalid_char : std::array<std::string, 7U>{
|
||||
for (const auto &invalid_char : std::array<std::string, 7U>{
|
||||
{"*", ":", "<", ">", "?", "|", "\""},
|
||||
}) {
|
||||
auto handle = ::CreateFileA(
|
||||
|
@ -416,6 +416,7 @@ using data_buffer = std::vector<unsigned char>;
|
||||
using mutex_lock = std::lock_guard<std::mutex>;
|
||||
using recur_mutex_lock = std::lock_guard<std::recursive_mutex>;
|
||||
using stop_type = std::atomic_bool;
|
||||
using stop_type_callback = std::function<std::atomic_bool()>;
|
||||
using unique_mutex_lock = std::unique_lock<std::mutex>;
|
||||
using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
|
||||
|
||||
|
@ -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<std::string> 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<std::array<unsigned char,
|
||||
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||
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<utils::file::i_file> 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 {
|
||||
|
@ -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,11 +178,11 @@ 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<std::string> relative_parent_path, std::size_t error_return)
|
||||
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
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();
|
||||
@ -237,12 +238,12 @@ 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<utils::encryption::hash_256_t>(
|
||||
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();
|
||||
@ -283,14 +284,14 @@ 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<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||
iv_list,
|
||||
std::size_t error_return)
|
||||
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
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();
|
||||
@ -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)),
|
||||
@ -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,7 +442,7 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
|
||||
}
|
||||
}
|
||||
|
||||
return stop_requested_ ? static_cast<std::size_t>(CURL_READFUNC_ABORT)
|
||||
return get_stop_requested() ? static_cast<std::size_t>(CURL_READFUNC_ABORT)
|
||||
: ret ? total_read
|
||||
: error_return_;
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
||||
|
Reference in New Issue
Block a user