summaryrefslogtreecommitdiffstats
path: root/src/H5FD.c
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2020-07-30 21:53:01 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2020-07-30 21:53:01 (GMT)
commit2a64d2fe93a0ba1da27c77df8a9e3b76e3cd5ee9 (patch)
tree7b3475f076365f2006ffaac55161183d4170c777 /src/H5FD.c
parent5632094d5c733af77003ecf4051a14f38645d993 (diff)
downloadhdf5-2a64d2fe93a0ba1da27c77df8a9e3b76e3cd5ee9.zip
hdf5-2a64d2fe93a0ba1da27c77df8a9e3b76e3cd5ee9.tar.gz
hdf5-2a64d2fe93a0ba1da27c77df8a9e3b76e3cd5ee9.tar.bz2
Change H5F_open to perform deduplication of open VFDs in a more flexible way,
using the new routine H5FDdeduplicate(). Simplify H5F_open() a bit, pushing some of the configuration checks into the SMWR VFD. For example, check that page buffering is enabled in H5FD_vfd_swmr_open() instead of in H5F_open(). Compare VFD SWMR configurations in H5FD_vfd_swmr_dedup() instead of in H5F_open(). Clone the default file-access property list at a new file-access property list ID, H5P_FILE_ACCESS_ANY_VFD. The new ID is used to indicate that if the file that's being opened is already open under an existing virtual file, and if that virtual file would not ordinarily be opened with the default FAPL, then it's ok to use that virtual file. Add a new optional method, `dedup`, to H5FD_class_t, and use it to customize a VFD's deduplication. Customize the SWMR VFD's deduplication. Make it honor H5P_FILE_ACCESS_ANY_VFD Embed the VFD SWMR configuration in the H5FD_vfd_swmr_t to facilitate comparison of configuration between new and old SWMR virtual files. In H5F__sfile_search(), match using a pointer comparison instead of H5FD_cmp(), because we will only ever enter H5F__sfile_search() with a deduplicated H5FD_t *.
Diffstat (limited to 'src/H5FD.c')
-rw-r--r--src/H5FD.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/H5FD.c b/src/H5FD.c
index 547eb8f..415ccf3 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -679,6 +679,73 @@ done:
FUNC_LEAVE_API(ret_value)
}
+/* Return `other` if `self` has no de-duplication method. Otherwise, return
+ * `other` if it duplicates `self`, `self` if `other` does NOT duplicate it,
+ * NULL if `other` conflicts with `self` or if there is an error.
+ *
+ * Unlike H5FD_deduplicate(), this routine does not free `self` under any
+ * circumstances.
+ */
+static H5FD_t *
+H5FD_dedup(H5FD_t *self, H5FD_t *other, hid_t fapl)
+{
+ H5FD_t *(*dedup)(H5FD_t *, H5FD_t *, hid_t);
+
+ if ((dedup = self->cls->dedup) != NULL)
+ return (*dedup)(self, other, fapl);
+
+ if (H5FDcmp(self, other) == 0)
+ return self;
+
+ return other;
+}
+
+/* If any other open H5FD_t is functionally equivalent to `file` under
+ * the given file-access properties, then return it and close `file`.
+ *
+ * If any other open H5FD_t is not equivalent to `file`, but its
+ * operation would conflict with `file`, then return NULL and close `file`.
+ */
+H5FD_t *
+H5FD_deduplicate(H5FD_t *file, hid_t fapl)
+{
+ H5FD_t *deduped = file, *item;
+
+ TAILQ_FOREACH(item, &all_vfds, link) {
+ /* skip "self" */
+ if (item == file)
+ continue;
+
+ /* skip files with exclusive owners, for now */
+ if (item->exc_owner != NULL)
+ continue;
+
+ if ((deduped = H5FD_dedup(item, file, fapl)) != file)
+ goto finish;
+ }
+
+ /* If we reach this stage, then we identified neither a conflict nor a
+ * duplicate. If any lower VFD with an exclusive owner matches `file`,
+ * return NULL to indicate the conflict.
+ */
+ TAILQ_FOREACH(item, &all_vfds, link) {
+ if (item == file || item->exc_owner == NULL)
+ continue;
+
+ if (H5FDcmp(file, item) == 0) {
+ deduped = NULL;
+ break;
+ }
+ }
+
+finish:
+ if (deduped != file && H5FD_close(file) < 0) {
+ HERROR(H5E_FILE, H5E_CANTOPENFILE, "could not close file");
+ return NULL;
+ }
+ return deduped;
+}
+
/* Return `true` if a second H5FD_t identical to `file`
* has an exclusive owner, `false` otherwise.
*/