forked from mirrors/gecko-dev
92 lines
2.5 KiB
Diff
92 lines
2.5 KiB
Diff
From 07e2a968c83c489c5b46efe4973114e78e1804c1 Mon Sep 17 00:00:00 2001
|
|
From: Marco Castelluccio <mcastelluccio@mozilla.com>
|
|
Date: Wed, 8 Nov 2017 19:11:54 +0000
|
|
Subject: [PATCH] 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
|
|
|
|
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317705 91177308-0d34-0410-b5e6-96231b3b80d8
|
|
---
|
|
lib/profile/WindowsMMap.c | 58 ++++++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 55 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/compiler-rt/lib/profile/WindowsMMap.c b/lib/profile/WindowsMMap.c
|
|
index f81d7da53..0c534710b 100644
|
|
--- a/compiler-rt/lib/profile/WindowsMMap.c
|
|
+++ b/compiler-rt/lib/profile/WindowsMMap.c
|
|
@@ -120,9 +120,61 @@ int msync(void *addr, size_t length, int flags)
|
|
}
|
|
|
|
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
|