summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDana Robinson <43805+derobins@users.noreply.github.com>2021-03-22 16:32:40 (GMT)
committerGitHub <noreply@github.com>2021-03-22 16:32:40 (GMT)
commit60e14b826a22452934f7057196c1ce4d0054d97a (patch)
treecb33f8b4d8840a7d0e2c653bde8e73020837624d /src
parent05bc1905cb37d145c29c036bacb1caac63c7f0c9 (diff)
downloadhdf5-60e14b826a22452934f7057196c1ce4d0054d97a.zip
hdf5-60e14b826a22452934f7057196c1ce4d0054d97a.tar.gz
hdf5-60e14b826a22452934f7057196c1ce4d0054d97a.tar.bz2
File locks now work on Windows (#480)
* File locks now work on Windows Uses LockFileEx() and UnlockFileEx(). Fixes HDFFV-10191 (partial). * Committing clang-format changes * Committing clang-format changes * Fixes commenting in h5repack * Reworks H5Fis_accessible() H5Fis_accessible() created a new file handle and attempted to read through it, which will fail when a file has been opened with an exclusive lock on operating systems that have mandatory locks. This change uses the same scheme we use in H5Fopen() to check if the file is already open and only tries to read the file signature if the file has not already been opened. Also adds a test for this behavior. * Committing clang-format changes * Trivial change to force github to run actions Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/H5Fint.c36
-rw-r--r--src/H5system.c51
2 files changed, 54 insertions, 33 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 920bf51..6da9473 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -1056,9 +1056,10 @@ done:
htri_t
H5F__is_hdf5(const char *name, hid_t fapl_id)
{
- H5FD_t *file = NULL; /* Low-level file struct */
- haddr_t sig_addr = HADDR_UNDEF; /* Addess of hdf5 file signature */
- htri_t ret_value = FAIL; /* Return value */
+ H5FD_t * file = NULL; /* Low-level file struct */
+ H5F_shared_t *shared = NULL; /* Shared part of file */
+ haddr_t sig_addr = HADDR_UNDEF; /* Addess of hdf5 file signature */
+ htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_PACKAGE
@@ -1069,10 +1070,20 @@ H5F__is_hdf5(const char *name, hid_t fapl_id)
if (NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to open file")
- /* The file is an hdf5 file if the hdf5 file signature can be found */
- if (H5FD_locate_signature(file, &sig_addr) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "error while trying to locate file signature")
- ret_value = (HADDR_UNDEF != sig_addr);
+ /* If the file is already open, it's an HDF5 file
+ *
+ * If the file is open with an exclusive lock on an operating system that enforces
+ * mandatory file locks (like Windows), creating a new file handle and attempting
+ * to read through it will fail so we have to try this first.
+ */
+ if ((shared = H5F__sfile_search(file)) != NULL)
+ ret_value = TRUE;
+ else {
+ /* The file is an HDF5 file if the HDF5 file signature can be found */
+ if (H5FD_locate_signature(file, &sig_addr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "error while trying to locate file signature")
+ ret_value = (HADDR_UNDEF != sig_addr);
+ }
done:
/* Close the file */
@@ -1782,7 +1793,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
FUNC_ENTER_NOAPI(NULL)
/*
- * If the driver has a `cmp' method then the driver is capable of
+ * If the driver has a 'cmp' method then the driver is capable of
* determining when two file handles refer to the same file and the
* library can insure that when the application opens a file twice
* that the two handles coordinate their operations appropriately.
@@ -3718,10 +3729,17 @@ H5F__start_swmr_write(H5F_t *f)
setup = TRUE;
/* Place an advisory lock on the file */
- if (H5F_USE_FILE_LOCKING(f))
+ if (H5F_USE_FILE_LOCKING(f)) {
+ /* Have to unlock on Windows as Win32 doesn't support changing the lock
+ * type (exclusive vs shared) with a second call.
+ */
+ if (H5FD_unlock(f->shared->lf) < 0) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTUNLOCKFILE, FAIL, "unable to unlock the file")
+ }
if (H5FD_lock(f->shared->lf, TRUE) < 0) {
HGOTO_ERROR(H5E_FILE, H5E_CANTLOCKFILE, FAIL, "unable to lock the file")
}
+ }
/* Mark superblock as dirty */
if (H5F_super_dirty(f) < 0)
diff --git a/src/H5system.c b/src/H5system.c
index 1d94816..745476d 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -618,40 +618,43 @@ c99_vsnprintf(char *str, size_t size, const char *format, va_list ap)
*-------------------------------------------------------------------------
*/
int
-Wflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation)
+Wflock(int fd, int operation)
{
-/* This is a no-op while we implement a Win32 VFD */
-#if 0
-int
-Wflock(int fd, int operation) {
-
- HANDLE hFile;
- DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
- DWORD dwReserved = 0;
- /* MAXDWORD for entire file */
- DWORD nNumberOfBytesToLockLow = MAXDWORD;
- DWORD nNumberOfBytesToLockHigh = MAXDWORD;
- /* Must initialize OVERLAPPED struct */
- OVERLAPPED overlapped = {0};
+ HANDLE hFile;
+ DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
+ DWORD dwReserved = 0;
+ /* MAXDWORD locks the entire file */
+ DWORD nNumberOfBytesToLockLow = MAXDWORD;
+ DWORD nNumberOfBytesToLockHigh = MAXDWORD;
+ /* Must initialize OVERLAPPED struct */
+ OVERLAPPED overlapped = {0};
/* Get Windows HANDLE */
- hFile = _get_osfhandle(fd);
+ if (INVALID_HANDLE_VALUE == (hFile = (HANDLE)_get_osfhandle(fd)))
+ return -1;
/* Convert to Windows flags */
- if(operation & LOCK_EX)
+ if (operation & LOCK_EX)
dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
/* Lock or unlock */
- if(operation & LOCK_UN)
- if(0 == UnlockFileEx(hFile, dwReserved, nNumberOfBytesToLockLow,
- nNumberOfBytesToLockHigh, &overlapped))
- return -1;
- else
- if(0 == LockFileEx(hFile, dwFlags, dwReserved, nNumberOfBytesToLockLow,
- nNumberOfBytesToLockHigh, &overlapped))
+ if (operation & LOCK_UN) {
+ if (0 ==
+ UnlockFileEx(hFile, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &overlapped)) {
+ /* Attempting to unlock an already unlocked file will fail and this can happen
+ * in H5Fstart_swmr_write(). For now, just ignore the "error" (error code: 0x9e / 158).
+ */
+ if (GetLastError() != 158)
+ return -1;
+ }
+ }
+ else {
+ if (0 == LockFileEx(hFile, dwFlags, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh,
+ &overlapped))
return -1;
-#endif /* 0 */
+ }
+
return 0;
} /* end Wflock() */