Skip to content

Commit

Permalink
Abstract LockDirectory into system.cpp
Browse files Browse the repository at this point in the history
Adaptation of btc@2f3bd47d44634cfc0a4261e64af178407ce2869c
  • Loading branch information
furszy committed Jul 21, 2021
1 parent 6a0380a commit 434ed75
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 40 deletions.
23 changes: 3 additions & 20 deletions src/init.cpp
Expand Up @@ -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;
}
Expand Down
23 changes: 23 additions & 0 deletions src/util/system.cpp
Expand Up @@ -77,6 +77,8 @@
#include <CoreFoundation/CoreFoundation.h>
#endif

#include <boost/interprocess/sync/file_lock.hpp>

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";
Expand All @@ -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<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 a string argument as a boolean.
*
Expand Down
1 change: 1 addition & 0 deletions src/util/system.h
Expand Up @@ -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.
Expand Down
21 changes: 1 addition & 20 deletions src/wallet/db.cpp
Expand Up @@ -20,7 +20,6 @@
#include <sys/stat.h>
#endif

#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/thread.hpp>


Expand Down Expand Up @@ -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

//
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 434ed75

Please sign in to comment.