summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2020-07-10 20:09:29 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2020-07-10 20:09:29 (GMT)
commit2e66b5cf86c1a184e01eea6b67b52ac82648573a (patch)
tree6cf56f85fdc4f2b433a127d1c8d4d66dc59a8e65 /src
parent5493f4faacd7984bf8e442786a33e49598118788 (diff)
downloadhdf5-2e66b5cf86c1a184e01eea6b67b52ac82648573a.zip
hdf5-2e66b5cf86c1a184e01eea6b67b52ac82648573a.tar.gz
hdf5-2e66b5cf86c1a184e01eea6b67b52ac82648573a.tar.bz2
Add all extant virtual files to a list. Add an "exclusive owner" (`exc_owner`)
member to all virtual files. Add a routine, H5FD_has_conflict(), that returns true if a new virtual file is identical to an existing virtual file that has an exclusive owner. Establish an exclusive owner for a VFD SWMR virtual file's lower virtual file. Rename bsdqueue.h to H5queue.h and install it, since it's used by H5FDpublic.h. This is part of a changeset that helps us avoid creating multiple H5F_shared_t for one file when virtual datasets are used with VFD SWMR. The old code for deduplicating VFD SWMR H5F_shared_t instances did not work correctly with VFD SWMR, so we'd end up with multiple H5F_shared_t all active on the same file.
Diffstat (limited to 'src')
-rw-r--r--src/H5FD.c32
-rw-r--r--src/H5FDprivate.h1
-rw-r--r--src/H5FDpublic.h6
-rw-r--r--src/H5FDvfd_swmr.c2
-rw-r--r--src/H5FDvfd_swmr_private.h2
-rw-r--r--src/H5Fint.c19
-rw-r--r--src/H5Fpkg.h2
-rw-r--r--src/H5MF.c2
-rw-r--r--src/H5queue.h (renamed from src/bsdqueue.h)0
-rw-r--r--src/Makefile.am4
-rw-r--r--src/hlog.h2
11 files changed, 60 insertions, 12 deletions
diff --git a/src/H5FD.c b/src/H5FD.c
index bd26bd9..e136e12 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -92,6 +92,8 @@ hbool_t H5_PKG_INIT_VAR = FALSE;
*/
static unsigned long H5FD_file_serial_no_g;
+static TAILQ_HEAD(_all_vfds, H5FD_t) all_vfds = TAILQ_HEAD_INITIALIZER(all_vfds);
+
/* File driver ID class */
static const H5I_class_t H5I_VFL_CLS[1] = {{
H5I_VFL, /* ID class value */
@@ -677,6 +679,24 @@ done:
FUNC_LEAVE_API(ret_value)
}
+/* Return `true` if a second H5FD_t identical to `file`
+ * has an exclusive owner, `false` otherwise.
+ */
+bool
+H5FD_has_conflict(H5FD_t *file)
+{
+ H5FD_t *item;
+
+ TAILQ_FOREACH(item, &all_vfds, link) {
+ // skip "self", skip unowned
+ if (item == file || item->exc_owner == NULL)
+ continue;
+ if (H5FDcmp(file, item) == 0)
+ return true;
+ }
+ return false;
+}
+
/*-------------------------------------------------------------------------
* Function: H5FD_open
@@ -743,6 +763,8 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
if(NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed")
+ file->exc_owner = NULL;
+
/* Set the file access flags */
file->access_flags = flags;
@@ -774,10 +796,13 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
/* (This will be changed later, when the superblock is located) */
file->base_addr = 0;
+ TAILQ_INSERT_TAIL(&all_vfds, file, link);
+
/* Set return value */
ret_value = file;
done:
+ /* XXX We leak H5FD_t's on many error conditions. */
/* Can't cleanup 'file' information, since we don't know what type it is */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_open() */
@@ -832,6 +857,7 @@ herr_t
H5FD_close(H5FD_t *file)
{
const H5FD_class_t *driver;
+ H5FD_t *item;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
@@ -845,6 +871,12 @@ H5FD_close(H5FD_t *file)
if(H5I_dec_ref(file->driver_id) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID")
+ TAILQ_FOREACH(item, &all_vfds, link) {
+ if (item->exc_owner == file)
+ item->exc_owner = NULL;
+ }
+ TAILQ_REMOVE(&all_vfds, file, link);
+
/* Dispatch to the driver for actual close. If the driver fails to
* close the file then the file will be in an unusable state.
*/
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 9126371..4eeea36 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -317,6 +317,7 @@ H5_DLL herr_t H5FD_free_driver_info(hid_t driver_id, const void *driver_info);
H5_DLL hid_t H5FD_register(const void *cls, size_t size, hbool_t app_ref);
H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
+bool H5FD_has_conflict(H5FD_t *);
H5_DLL herr_t H5FD_close(H5FD_t *file);
H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2);
H5_DLL herr_t H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/);
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 61bf212..ab8a868 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -18,6 +18,7 @@
#ifndef _H5FDpublic_H
#define _H5FDpublic_H
+#include "H5queue.h"
#include "H5public.h"
#include "H5Fpublic.h" /*for H5F_close_degree_t */
@@ -319,6 +320,11 @@ typedef struct H5FD_free_t {
struct H5FD_t {
hid_t driver_id; /*driver ID for this file */
const H5FD_class_t *cls; /*constant class info */
+
+ TAILQ_ENTRY(H5FD_t) link; /* Linkage for list of all VFs. */
+ H5FD_t *exc_owner; /* Pointer to an exclusive owner
+ * or NULL if none.
+ */
unsigned long fileno; /* File 'serial' number */
unsigned access_flags; /* File access flags (from create or open) */
unsigned long feature_flags; /* VFL Driver feature Flags */
diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c
index 72906ff..af633e3 100644
--- a/src/H5FDvfd_swmr.c
+++ b/src/H5FDvfd_swmr.c
@@ -351,6 +351,8 @@ H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id,
maxaddr)) == NULL)
HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "can't set driver info");
+ file->hdf5_file_lf->exc_owner = &file->pub;
+
/* set pb_configured to FALSE. This field should not exist, but
* until we modify the file open procedure to create the page buffer
* before there is any file I/O when opening a file VFD SWMR reader,
diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h
index 94fe662..c6f5a97 100644
--- a/src/H5FDvfd_swmr_private.h
+++ b/src/H5FDvfd_swmr_private.h
@@ -12,7 +12,7 @@
#ifndef _H5FDvfd_swmr_private_H
#define _H5FDvfd_swmr_private_H
-#include "bsdqueue.h" /* for TAILQ_* */
+#include "H5queue.h" /* for TAILQ_* */
#include "hlog.h" /* for TAILQ_* */
/* Forward declaration */
diff --git a/src/H5Fint.c b/src/H5Fint.c
index d76f2b1..84fb1d1 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -1572,7 +1572,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
hbool_t ci_load = FALSE; /* whether MDC ci load requested */
hbool_t ci_write = FALSE; /* whether MDC CI write requested */
hbool_t file_create = FALSE; /* creating a new file or not */
- H5FD_t *underlying_lf = NULL; /* underlying file driver for VFD SWMR */
H5F_vfd_swmr_config_t *vfd_swmr_config_ptr = NULL; /* Points to VFD SMWR config info */
H5F_t *ret_value = NULL; /*actual return value */
@@ -1645,14 +1644,20 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags)
} /* end if */
- /* For VFD SWMR driver, retrieve the underlying vfd for the search in H5F__sfile_search() */
- if(H5FD_is_vfd_swmr_driver(lf))
- underlying_lf = H5FD_vfd_swmr_get_underlying_vfd(lf);
- else
- underlying_lf = lf;
+ /* Do not reuse a virtual file opened exclusively by a second virtual
+ * file.
+ */
+ if (H5FD_has_conflict(lf)) {
+ if(H5FD_close(lf) < 0) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
+ "file '%s' already open exclusively; could not close", name);
+ }
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
+ "file '%s' already open exclusively", name);
+ }
/* Is the file already open? */
- if((shared = H5F__sfile_search(underlying_lf)) != NULL) {
+ if((shared = H5F__sfile_search(lf)) != NULL) {
/*
* The file is already open, so use that one instead of the one we
* just opened. We only one one H5FD_t* per file so one doesn't
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 45ff0ee..1136cb4 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -27,7 +27,7 @@
#define _H5Fpkg_H
/* BSD queue macros */
-#include "bsdqueue.h"
+#include "H5queue.h"
/* Get package's private header */
#include "H5Fprivate.h"
diff --git a/src/H5MF.c b/src/H5MF.c
index c320f2c..dbaf17c 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -22,7 +22,7 @@
*-------------------------------------------------------------------------
*/
-#include "bsdqueue.h"
+#include "H5queue.h"
#include "hlog.h"
/****************/
diff --git a/src/bsdqueue.h b/src/H5queue.h
index 816acca..816acca 100644
--- a/src/bsdqueue.h
+++ b/src/H5queue.h
diff --git a/src/Makefile.am b/src/Makefile.am
index d917c3e..cb3fa3c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -139,7 +139,9 @@ if ROS3_VFD_CONDITIONAL
endif
# Public headers
-include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5version.h \
+include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h \
+ H5queue.h \
+ H5version.h \
H5Apublic.h H5ACpublic.h \
H5Cpublic.h H5Dpublic.h \
H5Epubgen.h H5Epublic.h H5ESpublic.h H5Fpublic.h \
diff --git a/src/hlog.h b/src/hlog.h
index 95e8055..2489a47 100644
--- a/src/hlog.h
+++ b/src/hlog.h
@@ -17,7 +17,7 @@
#include <syslog.h>
#include <sys/cdefs.h>
-#include "bsdqueue.h"
+#include "H5queue.h"
#ifndef _unused
#define _unused __attribute__((unused))