Skip to content

Commit 2f3bd47

Browse files
committed
Abstract directory locking into util.cpp
1 parent 5260a4a commit 2f3bd47

File tree

4 files changed

+27
-36
lines changed

4 files changed

+27
-36
lines changed

src/init.cpp

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,23 +1143,10 @@ bool AppInitParameterInteraction()
11431143

11441144
static bool LockDataDirectory(bool probeOnly)
11451145
{
1146-
std::string strDataDir = GetDataDir().string();
1147-
11481146
// Make sure only a single Bitcoin process is using the data directory.
1149-
fs::path pathLockFile = GetDataDir() / ".lock";
1150-
FILE* file = fsbridge::fopen(pathLockFile, "a"); // empty lock file; created if it doesn't exist.
1151-
if (file) fclose(file);
1152-
1153-
try {
1154-
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
1155-
if (!lock.try_lock()) {
1156-
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME)));
1157-
}
1158-
if (probeOnly) {
1159-
lock.unlock();
1160-
}
1161-
} catch(const boost::interprocess::interprocess_exception& e) {
1162-
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", strDataDir, _(PACKAGE_NAME), e.what()));
1147+
fs::path datadir = GetDataDir();
1148+
if (!LockDirectory(datadir, ".lock", probeOnly)) {
1149+
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME)));
11631150
}
11641151
return true;
11651152
}

src/util.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
7474
#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
75+
#include <boost/interprocess/sync/file_lock.hpp>
7576
#include <boost/program_options/detail/config_file.hpp>
7677
#include <boost/thread.hpp>
7778
#include <openssl/crypto.h>
@@ -375,6 +376,27 @@ int LogPrintStr(const std::string &str)
375376
return ret;
376377
}
377378

379+
bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only)
380+
{
381+
fs::path pathLockFile = directory / lockfile_name;
382+
FILE* file = fsbridge::fopen(pathLockFile, "a"); // empty lock file; created if it doesn't exist.
383+
if (file) fclose(file);
384+
385+
try {
386+
static std::map<std::string, boost::interprocess::file_lock> locks;
387+
boost::interprocess::file_lock& lock = locks.emplace(pathLockFile.string(), pathLockFile.string().c_str()).first->second;
388+
if (!lock.try_lock()) {
389+
return false;
390+
}
391+
if (probe_only) {
392+
lock.unlock();
393+
}
394+
} catch (const boost::interprocess::interprocess_exception& e) {
395+
return error("Error while attempting to lock directory %s: %s", directory.string(), e.what());
396+
}
397+
return true;
398+
}
399+
378400
/** Interpret string as boolean, for argument parsing */
379401
static bool InterpretBool(const std::string& strValue)
380402
{

src/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ bool TruncateFile(FILE *file, unsigned int length);
173173
int RaiseFileDescriptorLimit(int nMinFD);
174174
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
175175
bool RenameOver(fs::path src, fs::path dest);
176+
bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
176177
bool TryCreateDirectories(const fs::path& p);
177178
fs::path GetDefaultDataDir();
178179
const fs::path &GetDataDir(bool fNetSpecific = true);

src/wallet/db.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <sys/stat.h>
1919
#endif
2020

21-
#include <boost/interprocess/sync/file_lock.hpp>
2221
#include <boost/thread.hpp>
2322

2423
namespace {
@@ -53,24 +52,6 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db)
5352
}
5453
}
5554
}
56-
57-
bool LockEnvDirectory(const fs::path& env_path)
58-
{
59-
// Make sure only a single Bitcoin process is using the wallet directory.
60-
fs::path lock_file_path = env_path / ".walletlock";
61-
FILE* file = fsbridge::fopen(lock_file_path, "a"); // empty lock file; created if it doesn't exist.
62-
if (file) fclose(file);
63-
64-
try {
65-
static boost::interprocess::file_lock lock(lock_file_path.string().c_str());
66-
if (!lock.try_lock()) {
67-
return false;
68-
}
69-
} catch (const boost::interprocess::interprocess_exception& e) {
70-
return error("Error obtaining lock on wallet directory %s: %s.", env_path.string(), e.what());
71-
}
72-
return true;
73-
}
7455
} // namespace
7556

7657
//
@@ -122,7 +103,7 @@ bool CDBEnv::Open(const fs::path& pathIn, bool retry)
122103
boost::this_thread::interruption_point();
123104

124105
strPath = pathIn.string();
125-
if (!LockEnvDirectory(pathIn)) {
106+
if (!LockDirectory(pathIn, ".walletlock")) {
126107
LogPrintf("Cannot obtain a lock on wallet directory %s. Another instance of bitcoin may be using it.\n", strPath);
127108
return false;
128109
}

0 commit comments

Comments
 (0)