summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2015-12-11 08:19:10 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2015-12-11 08:19:10 (GMT)
commitf53c939bd05b44d0cfc520f4de870d139ab1e61f (patch)
tree32d87e8436e40b3f1bc8dc49a1e364cbe3f5e4bb /src
parent1b62a22e0ca679cadb666e6951a65fc74dec4b69 (diff)
downloadhdf5-f53c939bd05b44d0cfc520f4de870d139ab1e61f.zip
hdf5-f53c939bd05b44d0cfc520f4de870d139ab1e61f.tar.gz
hdf5-f53c939bd05b44d0cfc520f4de870d139ab1e61f.tar.bz2
[svn-r28581] Brought flock changes over from revise_chunks as well as a few
minor tweaks from H5private.h. Tested on: 64-bit Ubuntu 15.10 (Linux 4.2.0 x86_64) gcc 5.2.1 serial only, autotools and CMake (3.3.2)
Diffstat (limited to 'src')
-rw-r--r--src/H5private.h74
-rw-r--r--src/H5system.c112
-rw-r--r--src/H5win32defs.h2
3 files changed, 186 insertions, 2 deletions
diff --git a/src/H5private.h b/src/H5private.h
index daf6998..c536566 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -119,6 +119,13 @@
#endif
/*
+ * flock() in sys/file.h is used for the implemention of file locking.
+ */
+#if defined(H5_HAVE_FLOCK) && defined(H5_HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif
+
+/*
* Resource usage is not Posix.1 but HDF5 uses it anyway for some performance
* and debugging code if available.
*/
@@ -291,6 +298,10 @@
*
* Note that Solaris Studio supports attribute, but does not support the
* attributes we use.
+ *
+ * H5_ATTR_CONST is redefined in tools/h5repack/dynlib_rpk.c to quiet
+ * gcc warnings (it has to use the public API and can't include this
+ * file). Be sure to update that file if the #ifdefs change here.
*/
#ifdef __cplusplus
# define H5_ATTR_FORMAT(X,Y,Z) /*void*/
@@ -542,6 +553,18 @@
#define H5_TB (1024.0F * 1024.0F * 1024.0F * 1024.0F)
#define H5_EB (1024.0F * 1024.0F * 1024.0F * 1024.0F * 1024.0F)
+#ifndef H5_HAVE_FLOCK
+/* flock() operations. Used in the source so we have to define them when
+ * the call is not available (e.g.: Windows). These should NOT be used
+ * with system-provided flock() calls since the values will come from the
+ * header file.
+ */
+#define LOCK_SH 0x01
+#define LOCK_EX 0x02
+#define LOCK_NB 0x04
+#define LOCK_UN 0x08
+#endif /* H5_HAVE_FLOCK */
+
/*
* Data types and functions for timing certain parts of the library.
*/
@@ -746,7 +769,11 @@ typedef struct {
#ifndef HDfclose
#define HDfclose(F) fclose(F)
#endif /* HDfclose */
-/* fcntl() variable arguments */
+#ifdef H5_HAVE_FCNTL
+ #ifndef HDfcntl
+ #define HDfcntl(F,C,...) fcntl(F,C,__VA_ARGS__)
+ #endif /* HDfcntl */
+#endif /* H5_HAVE_FCNTL */
#ifndef HDfdopen
#define HDfdopen(N,S) fdopen(N,S)
#endif /* HDfdopen */
@@ -771,6 +798,27 @@ typedef struct {
#ifndef HDfileno
#define HDfileno(F) fileno(F)
#endif /* HDfileno */
+/* Since flock is so prevalent, always build these functions
+ * when possible to avoid them becoming dead code.
+ */
+#ifdef H5_HAVE_FCNTL
+H5_DLL int Pflock(int fd, int operation);
+#endif /* H5_HAVE_FCNTL */
+H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation);
+#ifndef HDflock
+ /* NOTE: flock(2) is not present on all POSIX systems.
+ * If it is not present, we try a flock() equivalent based on
+ * fcntl(2), then fall back to a function that always fails if
+ * it is not present at all.
+ */
+ #if defined(H5_HAVE_FLOCK)
+ #define HDflock(F,L) flock(F,L)
+ #elif defined(H5_HAVE_FCNTL)
+ #define HDflock(F,L) Pflock(F,L)
+ #else
+ #define HDflock(F,L) Nflock(F,L)
+ #endif /* H5_HAVE_FLOCK */
+#endif /* HDflock */
#ifndef HDfloor
#define HDfloor(X) floor(X)
#endif /* HDfloor */
@@ -1163,6 +1211,9 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#define HDrmdir(S) rmdir(S)
#endif /* HDrmdir */
/* scanf() variable arguments */
+#ifndef HDselect
+ #define HDselect(N,RD,WR,ER,T) select(N,RD,WR,ER,T)
+#endif /* HDsetbuf */
#ifndef HDsetbuf
#define HDsetbuf(F,S) setbuf(F,S)
#endif /* HDsetbuf */
@@ -2374,6 +2425,16 @@ func \
H5_GLUE(FUNC_ERR_VAR_, use_err)(ret_typ, err) \
H5_GLUE(FUNC_ENT_, scope)(H5_MY_PKG, H5_MY_PKG_INIT)
+/* Use this macro when entering functions that have no return value */
+#define BEGIN_FUNC_VOID(scope, use_err, func) \
+H5_GLUE(FUNC_PREFIX_, scope) \
+void \
+func \
+/* Open function */ \
+{ \
+ H5_GLUE(FUNC_ERR_VAR_, use_err)(void, -, -) \
+ H5_GLUE(FUNC_ENT_, scope)
+
/* Macros for label when a function initialization can fail */
#define H5_PRIV_YES_FUNC_INIT_FAILED func_init_failed:
#define H5_PRIV_NO_FUNC_INIT_FAILED
@@ -2449,6 +2510,17 @@ func_init_failed: \
/* Close Function */ \
}
+/* Use this macro when leaving void functions */
+#define END_FUNC_VOID(scope) \
+ /* Scope-specific function conclusion */ \
+ H5_GLUE(FUNC_LEAVE_, scope) \
+ \
+ /* Leave routine */ \
+ return; \
+ \
+ /* Close Function */ \
+}
+
/* Macro to begin/end tagging (when FUNC_ENTER_*TAG macros are insufficient).
* Make sure to use HGOTO_ERROR_TAG and HGOTO_DONE_TAG between these macros! */
#define H5_BEGIN_TAG(dxpl, tag, err) { \
diff --git a/src/H5system.c b/src/H5system.c
index f91fb27..4baebc5 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -587,6 +587,68 @@ void HDsrand(unsigned int seed)
#endif /* H5_HAVE_RAND_R */
+
+/*-------------------------------------------------------------------------
+ * Function: Pflock
+ *
+ * Purpose: Wrapper function for POSIX systems where flock(2) is not
+ * available.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+/* NOTE: Compile this all the time on POSIX systems, even when flock(2) is
+ * present so that it's less likely to become dead code.
+ */
+#ifdef H5_HAVE_FCNTL
+int
+Pflock(int fd, int operation) {
+
+ struct flock flk;
+
+ /* Set the lock type */
+ if(operation & LOCK_UN)
+ flk.l_type = F_UNLCK;
+ else if(operation & LOCK_SH)
+ flk.l_type = F_RDLCK;
+ else
+ flk.l_type = F_WRLCK;
+
+ /* Set the other flock struct values */
+ flk.l_whence = SEEK_SET;
+ flk.l_start = 0;
+ flk.l_len = 0; /* to EOF */
+ flk.l_pid = 0; /* not used with set */
+
+ /* Lock or unlock */
+ if(HDfcntl(fd, F_SETLK, flk) < 0)
+ return -1;
+
+ return 0;
+
+} /* end Pflock() */
+#endif /* H5_HAVE_FCNTL */
+
+
+/*-------------------------------------------------------------------------
+ * Function: Nflock
+ *
+ * Purpose: Wrapper function for systems where no file locking is
+ * available.
+ *
+ * Return: Failure: -1 (always fails)
+ *
+ *-------------------------------------------------------------------------
+ */
+int H5_ATTR_CONST
+Nflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation) {
+ /* just fail */
+ return -1;
+} /* end Nflock() */
+
+
/*-------------------------------------------------------------------------
* Function: H5_make_time
*
@@ -767,7 +829,55 @@ int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
return count;
}
-#endif
+
+/*-------------------------------------------------------------------------
+ * Function: Wflock
+ *
+ * Purpose: Wrapper function for flock on Windows systems
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+Wflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED 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};
+
+ /* Get Windows HANDLE */
+ hFile = _get_osfhandle(fd);
+
+ /* Convert to Windows flags */
+ 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))
+ return -1;
+#endif /* 0 */
+ return 0;
+} /* end Wflock() */
+
+#endif /* H5_HAVE_VISUAL_STUDIO */
/*-------------------------------------------------------------------------
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index 73d8417..e84def9 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -74,6 +74,7 @@ struct timezone {
extern "C" {
#endif /* __cplusplus */
H5_DLL int Wgettimeofday(struct timeval *tv, struct timezone *tz);
+ H5_DLL int Wflock(int fd, int operation);
H5_DLL char* Wgetlogin(void);
H5_DLL int c99_snprintf(char* str, size_t size, const char* format, ...);
H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap);
@@ -81,6 +82,7 @@ struct timezone {
}
#endif /* __cplusplus */
#define HDgettimeofday(V,Z) Wgettimeofday(V,Z)
+#define HDflock(F,L) Wflock(F,L)
#define HDgetlogin() Wgetlogin()
#define HDsnprintf c99_snprintf /*varargs*/
#define HDvsnprintf c99_vsnprintf