[compiler-rt] r317705 - Implement flock for Windows in compiler-rt
Marco Castelluccio via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 8 11:11:55 PST 2017
Author: marco
Date: Wed Nov 8 11:11:54 2017
New Revision: 317705
URL: http://llvm.org/viewvc/llvm-project?rev=317705&view=rev
Log:
Implement flock for Windows in compiler-rt
Summary:
This patch implements flock for Windows, needed to make gcda writing work in a multiprocessing scenario.
Fixes https://bugs.llvm.org/show_bug.cgi?id=34923.
Reviewers: zturner
Reviewed By: zturner
Subscribers: rnk, zturner, llvm-commits
Differential Revision: https://reviews.llvm.org/D38891
Modified:
compiler-rt/trunk/lib/profile/WindowsMMap.c
Modified: compiler-rt/trunk/lib/profile/WindowsMMap.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/WindowsMMap.c?rev=317705&r1=317704&r2=317705&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/WindowsMMap.c (original)
+++ compiler-rt/trunk/lib/profile/WindowsMMap.c Wed Nov 8 11:11:54 2017
@@ -120,9 +120,61 @@ int msync(void *addr, size_t length, int
}
COMPILER_RT_VISIBILITY
-int flock(int fd, int operation)
-{
- return -1; /* Not supported. */
+int lock(HANDLE handle, DWORD lockType, BOOL blocking) {
+ DWORD flags = lockType;
+ if (!blocking)
+ flags |= LOCKFILE_FAIL_IMMEDIATELY;
+
+ OVERLAPPED overlapped;
+ ZeroMemory(&overlapped, sizeof(OVERLAPPED));
+ overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);
+ if (!result) {
+ DWORD dw = GetLastError();
+
+ // In non-blocking mode, return an error if the file is locked.
+ if (!blocking && dw == ERROR_LOCK_VIOLATION)
+ return -1; // EWOULDBLOCK
+
+ // If the error is ERROR_IO_PENDING, we need to wait until the operation
+ // finishes. Otherwise, we return an error.
+ if (dw != ERROR_IO_PENDING)
+ return -1;
+
+ DWORD dwNumBytes;
+ if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))
+ return -1;
+ }
+
+ return 0;
+}
+
+COMPILER_RT_VISIBILITY
+int flock(int fd, int operation) {
+ HANDLE handle = (HANDLE)_get_osfhandle(fd);
+ if (handle == INVALID_HANDLE_VALUE)
+ return -1;
+
+ BOOL blocking = (operation & LOCK_NB) == 0;
+ int op = operation & ~LOCK_NB;
+
+ switch (op) {
+ case LOCK_EX:
+ return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);
+
+ case LOCK_SH:
+ return lock(handle, 0, blocking);
+
+ case LOCK_UN:
+ if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))
+ return -1;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
}
#undef DWORD_HI
More information about the llvm-commits
mailing list