Skip to content

Commit 6c7d348

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 3166cc0 commit 6c7d348

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
@@ -1185,12 +1185,16 @@ openNativeFileForRead(const Twine &Name, OpenFlags Flags = OF_None,
11851185
/// descriptor.
11861186
std::error_code
11871187
tryLockFile(int FD,
1188-
std::chrono::milliseconds Timeout = std::chrono::milliseconds(0));
1188+
std::chrono::milliseconds Timeout = std::chrono::milliseconds(0),
1189+
bool Exclusive = true);
11891190

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

11951199
/// Unlock the file.
11961200
///

llvm/lib/Support/Unix/Path.inc

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

1217-
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
1217+
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout,
1218+
bool Exclusive) {
12181219
auto Start = std::chrono::steady_clock::now();
12191220
auto End = Start + Timeout;
12201221
do {
12211222
struct flock Lock;
12221223
memset(&Lock, 0, sizeof(Lock));
1223-
Lock.l_type = F_WRLCK;
1224+
Lock.l_type = Exclusive ? F_WRLCK : F_RDLCK;
12241225
Lock.l_whence = SEEK_SET;
12251226
Lock.l_start = 0;
12261227
Lock.l_len = 0;
@@ -1229,15 +1230,17 @@ std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
12291230
int Error = errno;
12301231
if (Error != EACCES && Error != EAGAIN)
12311232
return std::error_code(Error, std::generic_category());
1233+
if (Timeout.count() == 0)
1234+
break;
12321235
usleep(1000);
12331236
} while (std::chrono::steady_clock::now() < End);
12341237
return make_error_code(errc::no_lock_available);
12351238
}
12361239

1237-
std::error_code lockFile(int FD) {
1240+
std::error_code lockFile(int FD, bool Exclusive) {
12381241
struct flock Lock;
12391242
memset(&Lock, 0, sizeof(Lock));
1240-
Lock.l_type = F_WRLCK;
1243+
Lock.l_type = Exclusive ? F_WRLCK : F_RDLCK;
12411244
Lock.l_whence = SEEK_SET;
12421245
Lock.l_start = 0;
12431246
Lock.l_len = 0;

llvm/lib/Support/Windows/Path.inc

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

1298-
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
1299-
DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
1298+
std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout,
1299+
bool Exclusive) {
1300+
DWORD Flags = Exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0;
1301+
Flags |= LOCKFILE_FAIL_IMMEDIATELY;
13001302
OVERLAPPED OV = {};
13011303
file_t File = convertFDToNativeFile(FD);
13021304
auto Start = std::chrono::steady_clock::now();
@@ -1306,6 +1308,8 @@ std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
13061308
return std::error_code();
13071309
DWORD Error = ::GetLastError();
13081310
if (Error == ERROR_LOCK_VIOLATION) {
1311+
if (Timeout.count() == 0)
1312+
break;
13091313
::Sleep(1);
13101314
continue;
13111315
}
@@ -1314,8 +1318,8 @@ std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
13141318
return mapWindowsError(ERROR_LOCK_VIOLATION);
13151319
}
13161320

1317-
std::error_code lockFile(int FD) {
1318-
DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK;
1321+
std::error_code lockFile(int FD, bool Exclusive) {
1322+
DWORD Flags = Exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0;
13191323
OVERLAPPED OV = {};
13201324
file_t File = convertFDToNativeFile(FD);
13211325
if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))

0 commit comments

Comments
 (0)