[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