aboutsummaryrefslogtreecommitdiff
path: root/src/util.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <[email protected]>2018-01-16 10:54:13 +0100
committerWladimir J. van der Laan <[email protected]>2018-01-16 11:11:59 +0100
commit66e3af709dd444b2d85e15c56f4608c700ff82ee (patch)
treea604dd3608644a7cc968253bde02cbedbd30d916 /src/util.cpp
parentMerge #12173: [Qt] Use flexible font size for QRCode image address (diff)
parentAbstract directory locking into util.cpp (diff)
downloaddiscoin-66e3af709dd444b2d85e15c56f4608c700ff82ee.tar.xz
discoin-66e3af709dd444b2d85e15c56f4608c700ff82ee.zip
Merge #11904: Add a lock to the wallet directory
2f3bd47 Abstract directory locking into util.cpp (MeshCollider) 5260a4a Make .walletlock distinct from .lock (MeshCollider) 64226de Generalise walletdir lock error message for correctness (MeshCollider) c9ed4bd Add a test for wallet directory locking (MeshCollider) e60cb99 Add a lock to the wallet directory (MeshCollider) Pull request description: Fixes https://github.com/bitcoin/bitcoin/issues/11888, needs a 0.16 milestone Also adds a test that the lock works. https://github.com/bitcoin/bitcoin/pull/11687 will probably rework this to a per-wallet lock instead of just the walletdir, but this fixes the current issue Tree-SHA512: 98e52d67f820e3b8f919cf361ffbb7d928f1bd67603e0ed26c5076ea02d9b3a90c3535ddf7329f3b88171396fa28dd3c87adab3577a8a217bd1e4247bda99138
Diffstat (limited to 'src/util.cpp')
-rw-r--r--src/util.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/util.cpp b/src/util.cpp
index 150bc503d..80eed24ff 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)
{