From 434ed7598cef245718fdf8a198e632a9452f40bf Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 15 Jun 2021 10:23:23 -0300 Subject: [PATCH] Abstract LockDirectory into system.cpp Adaptation of btc@2f3bd47d44634cfc0a4261e64af178407ce2869c --- src/init.cpp | 23 +++-------------------- src/util/system.cpp | 23 +++++++++++++++++++++++ src/util/system.h | 1 + src/wallet/db.cpp | 21 +-------------------- 4 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 236e668cb47d9..93730bdb7624d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1199,27 +1199,10 @@ bool AppInitParameterInteraction() static bool LockDataDirectory(bool probeOnly) { - std::string strDataDir = GetDataDir().string(); - // Make sure only a single PIVX process is using the data directory. - fs::path pathLockFile = GetDataDir() / ".lock"; - FILE* file = fsbridge::fopen(pathLockFile, "a"); // empty lock file; created if it doesn't exist. - if (file) fclose(file); - - try { - static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); - // Wait maximum 10 seconds if an old wallet is still running. Avoids lockup during restart - if (!lock.timed_lock(boost::get_system_time() + boost::posix_time::seconds(10))) { - return UIError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), - strDataDir, _(PACKAGE_NAME))); - } - if (probeOnly) { - lock.unlock(); - } - } catch (const boost::interprocess::interprocess_exception& e) { - return UIError( - strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", - strDataDir, _(PACKAGE_NAME), e.what())); + fs::path datadir = GetDataDir(); + if (!LockDirectory(datadir, ".lock", probeOnly)) { + return UIError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME))); } return true; } diff --git a/src/util/system.cpp b/src/util/system.cpp index d3792e57d6a46..193ef2e676e89 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -77,6 +77,8 @@ #include #endif +#include + const char * const PIVX_CONF_FILENAME = "pivx.conf"; const char * const PIVX_PID_FILENAME = "pivx.pid"; const char * const PIVX_MASTERNODE_CONF_FILENAME = "masternode.conf"; @@ -103,6 +105,27 @@ bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes) return free_bytes_available >= min_disk_space + additional_bytes; } +bool LockDirectory(const fs::path& directory, const std::string& lockfile_name, bool probe_only) +{ + fs::path pathLockFile = directory / lockfile_name; + FILE* file = fsbridge::fopen(pathLockFile, "a"); // empty lock file; created if it doesn't exist. + if (file) fclose(file); + + try { + static std::map locks; + boost::interprocess::file_lock& lock = locks.emplace(pathLockFile.string(), pathLockFile.string().c_str()).first->second; + if (!lock.try_lock()) { + return false; + } + if (probe_only) { + lock.unlock(); + } + } catch (const boost::interprocess::interprocess_exception& e) { + return error("Error while attempting to lock directory %s: %s", directory.string(), e.what()); + } + return true; +} + /** * Interpret a string argument as a boolean. * diff --git a/src/util/system.h b/src/util/system.h index 8837ee8784bf5..3a8f5cf0404bc 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -88,6 +88,7 @@ int RaiseFileDescriptorLimit(int nMinFD); void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length); bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0); bool RenameOver(fs::path src, fs::path dest); +bool LockDirectory(const fs::path& directory, const std::string& lockfile_name, bool probe_only=false); bool TryCreateDirectories(const fs::path& p); fs::path GetDefaultDataDir(); // The blocks directory is always net specific. diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index a0ed2c4592aa9..b00671b6652b9 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -20,7 +20,6 @@ #include #endif -#include #include @@ -56,24 +55,6 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db) } } } - -bool LockEnvDirectory(const fs::path& env_path) -{ - // Make sure only a single PIVX process is using the wallet directory. - fs::path lock_file_path = env_path / ".walletlock"; - FILE* file = fsbridge::fopen(lock_file_path, "a"); // empty lock file; created if it doesn't exist. - if (file) fclose(file); - - try { - static boost::interprocess::file_lock lock(lock_file_path.string().c_str()); - if (!lock.try_lock()) { - return false; - } - } catch (const boost::interprocess::interprocess_exception& e) { - return error("Error obtaining lock on wallet directory %s: %s.", env_path.string(), e.what()); - } - return true; -} } // namespace // @@ -125,7 +106,7 @@ bool CDBEnv::Open(const fs::path& pathIn, bool retry) boost::this_thread::interruption_point(); strPath = pathIn.string(); - if (!LockEnvDirectory(pathIn)) { + if (!LockDirectory(pathIn, ".walletlock")) { LogPrintf("Cannot obtain a lock on wallet directory %s. Another instance of PIVX may be using it.\n", strPath); return false; }