diff options
author | David Young <dyoung@hdfgroup.org> | 2020-07-10 20:09:29 (GMT) |
---|---|---|
committer | David Young <dyoung@hdfgroup.org> | 2020-07-10 20:09:29 (GMT) |
commit | 2e66b5cf86c1a184e01eea6b67b52ac82648573a (patch) | |
tree | 6cf56f85fdc4f2b433a127d1c8d4d66dc59a8e65 | |
parent | 5493f4faacd7984bf8e442786a33e49598118788 (diff) | |
download | hdf5-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.
-rw-r--r-- | src/H5FD.c | 32 | ||||
-rw-r--r-- | src/H5FDprivate.h | 1 | ||||
-rw-r--r-- | src/H5FDpublic.h | 6 | ||||
-rw-r--r-- | src/H5FDvfd_swmr.c | 2 | ||||
-rw-r--r-- | src/H5FDvfd_swmr_private.h | 2 | ||||
-rw-r--r-- | src/H5Fint.c | 19 | ||||
-rw-r--r-- | src/H5Fpkg.h | 2 | ||||
-rw-r--r-- | src/H5MF.c | 2 | ||||
-rw-r--r-- | src/H5queue.h (renamed from src/bsdqueue.h) | 0 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/hlog.h | 2 |
11 files changed, 60 insertions, 12 deletions
@@ -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" @@ -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 \ @@ -17,7 +17,7 @@ #include <syslog.h> #include <sys/cdefs.h> -#include "bsdqueue.h" +#include "H5queue.h" #ifndef _unused #define _unused __attribute__((unused)) |