diff options
| author | Wladimir J. van der Laan <[email protected]> | 2018-01-16 10:54:13 +0100 |
|---|---|---|
| committer | Wladimir J. van der Laan <[email protected]> | 2018-01-16 11:11:59 +0100 |
| commit | 66e3af709dd444b2d85e15c56f4608c700ff82ee (patch) | |
| tree | a604dd3608644a7cc968253bde02cbedbd30d916 /src/util.cpp | |
| parent | Merge #12173: [Qt] Use flexible font size for QRCode image address (diff) | |
| parent | Abstract directory locking into util.cpp (diff) | |
| download | discoin-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.cpp | 22 |
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) { |