-
Notifications
You must be signed in to change notification settings - Fork 37.7k
utils: drop boost::interprocess::file_lock #13862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Note to reviewers: This pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Seems like a good opportunity to drop |
src/fs.h
Outdated
class FileLock | ||
{ | ||
public: | ||
FileLock(const fs::path& file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: could delete default and copy constructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/fs.cpp
Outdated
lock.l_start = 0; | ||
lock.l_len = 0; | ||
return -1 != fcntl(fd, F_SETLK, &lock); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The relevant boost implementation, for reference:
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
{
struct ::flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
int ret = ::fcntl(hnd, F_SETLK, &lock);
if(ret == -1){
return (errno == EAGAIN || errno == EACCES) ?
acquired = false, true : false;
}
return (acquired = true);
}
https://www.boost.org/doc/libs/1_67_0/boost/interprocess/detail/os_file_functions.hpp
Should we distinguish between hard (e.g. EINVAL) and soft (EAGAIN, EACCES) failures, as they do? We could throw in the former case?
https://www.gnu.org/software/libc/manual/html_node/File-Locks.html
src/fs.cpp
Outdated
} | ||
_OVERLAPPED overlapped = {0}; | ||
return LockFileEx((HANDLE)hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlapped); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The relevant boost implementation, for reference:
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
{
const unsigned long len = ((unsigned long)-1);
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
if(!winapi::lock_file_ex
(hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately,
0, len, len, &overlapped)){
return winapi::get_last_error() == winapi::error_lock_violation ?
acquired = false, true : false;
}
return (acquired = true);
}
https://www.boost.org/doc/libs/1_67_0/boost/interprocess/detail/os_file_functions.hpp
Similar question re. GetLastError
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also is the (HANDLE)
cast necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@Empact In my opinion, we deal catching exception and try_lock fail much the same when we use boost, so no need to handle the extra exception for now. |
@ken2812221 FYI boost does throw on the failures noted above: inline bool file_lock::try_lock()
{
bool result;
if(!ipcdetail::try_acquire_file_lock(m_file_hnd, result)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
return result;
}
namespace boost {
namespace interprocess {
inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
{
#if (defined BOOST_INTERPROCESS_WINDOWS)
return winapi::get_last_error();
#else
return errno; // GCC 3.1 won't accept ::errno
#endif
} https://www.boost.org/doc/libs/1_67_0/boost/interprocess/sync/file_lock.hpp |
@Empact I simply return false in my code at those conditions. |
Yeah so the net effect is the loss of this message: Certainly not a big deal but breadcrumbs can mean the difference between an easy fix and a maddening mystery. |
@Empact Updated to get error messages. |
src/fs.cpp
Outdated
return false; | ||
} | ||
_OVERLAPPED overlapped = {0}; | ||
return LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlapped); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CreateFileW with 0 sharing effectively opens the file as exclusive (locking it). It feels the TryLock() here is redundant because we don't require locking of specific bytes.
Perhaps the TryLock() should be the one doing the CreateFileW.
Apologies if I've misunderstood something here :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/fs.cpp
Outdated
@@ -12,4 +21,82 @@ FILE *freopen(const fs::path& p, const char *mode, FILE *stream) | |||
return ::freopen(p.string().c_str(), mode, stream); | |||
} | |||
|
|||
#ifndef WIN32 | |||
|
|||
std::string GetErrorReason() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: static
src/fs.cpp
Outdated
} | ||
#else | ||
|
||
std::string GetErrorReason() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: static
return error("Error while attempting to lock directory %s: %s", directory.string(), e.what()); | ||
auto lock = MakeUnique<fsbridge::FileLock>(pathLockFile); | ||
if (!lock->TryLock()) { | ||
return error("Error while attempting to lock directory %s: %s", directory.string(), lock->GetReason()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, how these are logged by the callers:
Lines 1183 to 1185 in 2b67354
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))); | |
} |
Lines 136 to 139 in 2b67354
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; | |
} |
boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows. This commit add a new class to handle those specific file for Windows.
1661a47 add unicode compatible file_lock for Windows (Chun Kuan Lee) Pull request description: boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows. This PR is seperated from #13426 for easier review. Tree-SHA512: e240479cda65958bf6e1319840b83928b2b50da81d99f4f002fb3b62621370bcd4bcfacd2b8c0678c443a650d6ba53d9d12618b591e5bfd67ac14388a18fd822
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by #13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
Backports bitcoin#13862 boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows.
Backports bitcoin#13862 boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows.
Since the merge of bitcoin#13862, and the inclusion of the <codecvt> header, it hasn't been possible to compile bitcoind (targeting Windows) using GCC 4.8.x. The libstdc++ packaged with GCC didn't include the <codecvt> header until GCC 5.1. See the GCC 5 release notes: https://gcc.gnu.org/gcc-5/changes.html. Given that we'll be requiring a c++17 capable compiler at some point in the near future, and, assuming no-one else has noticed this, I think we can just adjust the docs to indicate that it's actually GCC 5.1+ that is required (I don't think we need to break it down per target).
Merge bitcoin#19660, bitcoin#19373, bitcoin#19841, bitcoin#13862, bitcoin#13866, bitcoin#17280, bitcoin#17682 and partial bitcoin#19326, bitcoin#14978: Auxiliary Backports
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
63e0be6 [Remove] By-pass logprint-scanner restriction. (furszy) 280ced3 utils: Fix broken Windows filelock (Chun Kuan Lee) be89860 utils: Convert Windows args to utf-8 string (Chun Kuan Lee) e8cfa6e Call unicode API on Windows (Chun Kuan Lee) 1a02a8a tests: Add test case for std::ios_base::ate (Chun Kuan Lee) 2e57cd4 Move boost/std fstream to fsbridge (furszy) 9d8bcd4 utils: Add fsbridge fstream function wrapper (Chun Kuan Lee) d59d48d utils: Convert fs error messages from multibyte to utf-8 (ken2812221) 9ef58cc Logging: use "fmterr" variable name for errors instead of general "e" that can be used by any other function. (furszy) dd94241 utils: Use _wfopen and _wreopen on Windows (Chun Kuan Lee) 3993641 add unicode compatible file_lock for Windows (Chun Kuan Lee) 48349f8 Provide relevant error message if datadir is not writable. (murrayn) Pull request description: As the software is currently using the ANSI encoding on Windows, the user's language settings could affect the proper functioning of the node/wallet, to the point of not be able to open some non-ASCII name files and directories. This solves the Windows encoding issues, completing the entire bitcoin#13869 work path (and some other required backports). Enabling for example users that use non-english characters in directories and file names to be accepted. Backported PRs: * bitcoin#12422. * bitcoin#12630. * bitcoin#13862. * bitcoin#13866. * bitcoin#13877. * bitcoin#13878. * bitcoin#13883. * bitcoin#13884. * bitcoin#13886. * bitcoin#13888. * bitcoin#14192. * bitcoin#13734. * bitcoin#14426. This is built on top of other two PRs that i have open #2423 and #2369. Solves old issues #940 and #2163. TODO: * Backport `assert_start_raises_init_error` and `ErrorMatch` in TestNode` (bitcoin#12718) ACKs for top commit: Fuzzbawls: ACK 63e0be6 random-zebra: ACK 63e0be6 and merging... Tree-SHA512: cb1f7c23abb5b7b3af50bba18652cc2cad93fd7c2fca9c16ffd3fee34c4c152a3b666dfa87fe6b44c430064dcdee4367144dcb4a41203c91b0173b805bdb3d7d
369244f utils: Fix broken Windows filelock (Chun Kuan Lee) Pull request description: Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862. Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows.
This PR is seperated from #13426 for easier review.