[PATCH] D38891: Implement flock for Windows in compiler-rt

Marco Castelluccio via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 16 16:39:04 PDT 2017


marco-c updated this revision to Diff 119229.
marco-c retitled this revision from "Implement part of the flock functionality for Windows in compiler-rt" to "Implement flock for Windows in compiler-rt".
marco-c edited the summary of this revision.
marco-c edited reviewers, added: zturner; removed: slingn.
marco-c added a comment.

Updated patch to handle asynchronous I/O case and to implement all flock functionality as suggested.

It's better to implement it in its entirety and correctly handling all cases, otherwise problems in the future could be hard to debug, especially since we are talking about locking.


https://reviews.llvm.org/D38891

Files:
  lib/profile/WindowsMMap.c


Index: lib/profile/WindowsMMap.c
===================================================================
--- lib/profile/WindowsMMap.c
+++ lib/profile/WindowsMMap.c
@@ -120,11 +120,63 @@
 }
 
 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
 #undef DWORD_LO
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38891.119229.patch
Type: text/x-patch
Size: 1765 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171016/2e3483f5/attachment.bin>


More information about the llvm-commits mailing list