aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp19
-rw-r--r--src/util.cpp22
-rw-r--r--src/util.h1
-rw-r--r--src/wallet/db.cpp21
4 files changed, 27 insertions, 36 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 7215e87359..b48802637b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1143,23 +1143,10 @@ bool AppInitParameterInteraction()
static bool LockDataDirectory(bool probeOnly)
{
- std::string strDataDir = GetDataDir().string();
-
// Make sure only a single Bitcoin 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());
- if (!lock.try_lock()) {
- return InitError(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 InitError(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 InitError(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.cpp b/src/util.cpp
index 150bc503df..80eed24ffd 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -72,6 +72,7 @@
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
+#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/thread.hpp>
#include <openssl/crypto.h>
@@ -375,6 +376,27 @@ int LogPrintStr(const std::string &str)
return ret;
}
+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<std::string, boost::interprocess::file_lock> 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 string as boolean, for argument parsing */
static bool InterpretBool(const std::string& strValue)
{
diff --git a/src/util.h b/src/util.h
index 6a0d6a31e7..277b4c66af 100644
--- a/src/util.h
+++ b/src/util.h
@@ -173,6 +173,7 @@ bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
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();
const fs::path &GetDataDir(bool fNetSpecific = true);
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index e3366e1060..23c6279128 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -18,7 +18,6 @@
#include <sys/stat.h>
#endif
-#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/thread.hpp>
namespace {
@@ -53,24 +52,6 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db)
}
}
}
-
-bool LockEnvDirectory(const fs::path& env_path)
-{
- // Make sure only a single Bitcoin 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
//
@@ -122,7 +103,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 bitcoin may be using it.\n", strPath);
return false;
}