Skip to content

Commit 6bce89d

Browse files
[FileSystem] Allow exclusive file lock
Add parameter to file lock API to allow exclusive file lock. Both Unix and Windows support lock the file exclusively for write for one process and LLVM OnDiskCAS uses exclusive file lock to coordinate CAS creation.
1 parent 2b4d1de commit 6bce89d

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

llvm/include/llvm/Support/FileSystem.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,12 +1184,16 @@ openNativeFileForRead(const Twine &Name, OpenFlags Flags = OF_None,
11841184
/// descriptor.
11851185
std::error_code
11861186
tryLockFile(int FD,
1187-
std::chrono::milliseconds Timeout = std::chrono::milliseconds(0));
1187+
std::chrono::milliseconds Timeout = std::chrono::milliseconds(0),
1188+
bool Exclusive = true);
11881189

11891190
/// Lock the file.
11901191
///
11911192
/// This function acts as @ref tryLockFile but it waits infinitely.
1192-
std::error_code lockFile(int FD);
1193+
/// \param FD file descriptor to use for locking.
1194+
/// \param Exclusive if \p true use exclusive/writer lock, otherwise use
1195+
/// shared/reader lock.
1196+
std::error_code lockFile(int FD, bool Exclusive = true);
11931197

11941198
/// Unlock the file.
11951199
///

llvm/lib/Support/Unix/Path.inc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,13 +1223,14 @@ Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf,
12231223
return NumRead;
12241224
}
12251225

1226-
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
1226+
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout,
1227+
bool Exclusive) {
12271228
auto Start = std::chrono::steady_clock::now();
12281229
auto End = Start + Timeout;
12291230
do {
12301231
struct flock Lock;
12311232
memset(&Lock, 0, sizeof(Lock));
1232-
Lock.l_type = F_WRLCK;
1233+
Lock.l_type = Exclusive ? F_WRLCK : F_RDLCK;
12331234
Lock.l_whence = SEEK_SET;
12341235
Lock.l_start = 0;
12351236
Lock.l_len = 0;
@@ -1238,15 +1239,17 @@ std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
12381239
int Error = errno;
12391240
if (Error != EACCES && Error != EAGAIN)
12401241
return std::error_code(Error, std::generic_category());
1242+
if (Timeout.count() == 0)
1243+
break;
12411244
usleep(1000);
12421245
} while (std::chrono::steady_clock::now() < End);
12431246
return make_error_code(errc::no_lock_available);
12441247
}
12451248

1246-
std::error_code lockFile(int FD) {
1249+
std::error_code lockFile(int FD, bool Exclusive) {
12471250
struct flock Lock;
12481251
memset(&Lock, 0, sizeof(Lock));
1249-
Lock.l_type = F_WRLCK;
1252+
Lock.l_type = Exclusive ? F_WRLCK : F_RDLCK;
12501253
Lock.l_whence = SEEK_SET;
12511254
Lock.l_start = 0;
12521255
Lock.l_len = 0;

llvm/lib/Support/Windows/Path.inc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,8 +1327,10 @@ Expected<size_t> readNativeFileSlice(file_t FileHandle,
13271327
return readNativeFileImpl(FileHandle, Buf, &Overlapped);
13281328
}
13291329

1330-
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
1331-
DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
1330+
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout,
1331+
bool Exclusive) {
1332+
DWORD Flags = Exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0;
1333+
Flags |= LOCKFILE_FAIL_IMMEDIATELY;
13321334
OVERLAPPED OV = {};
13331335
file_t File = convertFDToNativeFile(FD);
13341336
auto Start = std::chrono::steady_clock::now();
@@ -1338,6 +1340,8 @@ std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
13381340
return std::error_code();
13391341
DWORD Error = ::GetLastError();
13401342
if (Error == ERROR_LOCK_VIOLATION) {
1343+
if (Timeout.count() == 0)
1344+
break;
13411345
::Sleep(1);
13421346
continue;
13431347
}
@@ -1346,8 +1350,8 @@ std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
13461350
return mapWindowsError(ERROR_LOCK_VIOLATION);
13471351
}
13481352

1349-
std::error_code lockFile(int FD) {
1350-
DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK;
1353+
std::error_code lockFile(int FD, bool Exclusive) {
1354+
DWORD Flags = Exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0;
13511355
OVERLAPPED OV = {};
13521356
file_t File = convertFDToNativeFile(FD);
13531357
if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))

0 commit comments

Comments
 (0)