diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Fint.c | 36 | ||||
-rw-r--r-- | src/H5system.c | 51 |
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() */ |