add Windows storage directory locking

This commit is contained in:
Syping 2024-02-12 19:15:32 +01:00
parent 2ad1bc3aa5
commit cfede2f3e1
2 changed files with 27 additions and 6 deletions

View file

@ -39,7 +39,7 @@ file::file(const std::filesystem::path &storage_path) : m_storagePath(storage_pa
throw std::runtime_error("Storage directory can not be found"); throw std::runtime_error("Storage directory can not be found");
} }
#ifdef __unix__ #if defined(__unix__)
struct flock lock; struct flock lock;
lock.l_start = 0; lock.l_start = 0;
lock.l_len = 0; lock.l_len = 0;
@ -47,7 +47,7 @@ file::file(const std::filesystem::path &storage_path) : m_storagePath(storage_pa
lock.l_type = F_WRLCK; lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET; lock.l_whence = SEEK_SET;
const std::string lock_file = storage_path / ".lock"; const std::filesystem::path lock_file = storage_path / ".lock";
fd = open(lock_file.c_str(), O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); fd = open(lock_file.c_str(), O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1) { if (fd == -1) {
std::cerr << "[Error] Storage directory " << storage_path << " can not be locked" << std::endl; std::cerr << "[Error] Storage directory " << storage_path << " can not be locked" << std::endl;
@ -58,14 +58,29 @@ file::file(const std::filesystem::path &storage_path) : m_storagePath(storage_pa
std::cerr << "[Error] Storage directory " << storage_path << " can not be locked" << std::endl; std::cerr << "[Error] Storage directory " << storage_path << " can not be locked" << std::endl;
throw std::system_error(errno, std::system_category()); throw std::system_error(errno, std::system_category());
} }
#elif defined(_WIN32)
const std::filesystem::path lock_file = storage_path / ".lock";
fh = CreateFileW(lock_file.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
if (fh == INVALID_HANDLE_VALUE) {
std::cerr << "[Error] Storage directory " << storage_path << " can not be locked" << std::endl;
throw std::system_error(GetLastError(), std::system_category());
}
if (!LockFile(fh, NULL, NULL, NULL, NULL)) {
CloseHandle(fh);
std::cerr << "[Error] Storage directory " << storage_path << " can not be locked" << std::endl;
throw std::system_error(GetLastError(), std::system_category());
}
#endif #endif
} }
file::~file() file::~file()
{ {
const std::lock_guard<std::mutex> guard(m_mutex); const std::lock_guard<std::mutex> guard(m_mutex);
#ifdef __unix__ #if defined(__unix__)
close(fd); close(fd);
#elif defined(_WIN32)
CloseHandle(fh);
#endif #endif
} }
@ -268,7 +283,7 @@ bot::settings::channel file::get_channel(dpp::snowflake guild_id, dpp::snowflake
bot::settings::channel channel; bot::settings::channel channel;
cache_get_channel(channel_id, &channel); cache_get_channel(channel_id, &channel);
return std::move(channel); return channel;
} }
std::vector<dpp::snowflake> file::get_channels(dpp::snowflake guild_id) std::vector<dpp::snowflake> file::get_channels(dpp::snowflake guild_id)

View file

@ -21,6 +21,11 @@
#include <mutex> #include <mutex>
#include <filesystem> #include <filesystem>
#ifdef _WIN32
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include "database_core.h" #include "database_core.h"
namespace bot { namespace bot {
@ -46,13 +51,14 @@ namespace bot {
private: private:
void cache_add_channel(dpp::snowflake guild_id, dpp::snowflake channel_id); void cache_add_channel(dpp::snowflake guild_id, dpp::snowflake channel_id);
void cache_delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id);
void cache_get_channel(dpp::snowflake channel_id, bot::settings::channel *channel); void cache_get_channel(dpp::snowflake channel_id, bot::settings::channel *channel);
void cache_guild(dpp::snowflake guild_id, std::vector<dpp::snowflake> *channels); void cache_guild(dpp::snowflake guild_id, std::vector<dpp::snowflake> *channels);
void list_guilds(std::vector<dpp::snowflake> *guilds); void list_guilds(std::vector<dpp::snowflake> *guilds);
void sync_cache(); void sync_cache();
#ifdef __unix__ #if defined(__unix__)
int fd; int fd;
#elif defined(_WIN32)
HANDLE fh;
#endif #endif
std::vector<bot::database::guild> m_channelCache; std::vector<bot::database::guild> m_channelCache;
std::vector<bot::settings::guild> m_dataCache; std::vector<bot::settings::guild> m_dataCache;