summaryrefslogtreecommitdiffstats
path: root/test/tid.c
diff options
context:
space:
mode:
authorDana Robinson <43805+derobins@users.noreply.github.com>2020-11-17 18:06:39 (GMT)
committerGitHub <noreply@github.com>2020-11-17 18:06:39 (GMT)
commita50d211755cb272b2e468144e7d892a4c90813c4 (patch)
tree5ef471321caab6a2f9d14eef0f9cab462c8d73f5 /test/tid.c
parent0db2d6c21211cc78dbde8e9b1a1588902aec152c (diff)
downloadhdf5-a50d211755cb272b2e468144e7d892a4c90813c4.zip
hdf5-a50d211755cb272b2e468144e7d892a4c90813c4.tar.gz
hdf5-a50d211755cb272b2e468144e7d892a4c90813c4.tar.bz2
Switch ID code to use a hash table instead of a skip list (#52)
* Brings hash table ID code over from Bitbucket branch * Includes reformatting via clang. * Excludes uthash.h from reformatting. * Still has the failing test issue in tid.c. This should only be a problem if a custom ID type is used and its free function deletes other IDs. * Fixes munged H5_GCC_DIAG_ON/OFF macros in H5I.c The H5_GCC_DIAG_ON/OFF macros used to turn off fallthrough warnings in uthash.h (external code) were munged when formatting with clang due to their lack of quotes. e.g.; H5_GCC_DIAG_OFF(implicit-fallthrough) was munged to: H5_GCC_DIAG_OFF(implicit - fallthrough) which compiles, but is useless. So, with quotes, this is now: H5_GCC_DIAG_OFF("implicit-fallthrough") which survives reformatting with clang. * Fixes issues with user callbacks in the ID hash tables The skip lists (previously) used to handle IDs use a mark-and-sweep scheme to deal with user-defined ID delete callbacks which themselves delete other IDs in the list. The uthash hash table implementation used to manage the IDs in this feature branch does not have this ability. This commit restores the skip lists for non-library ID types in lieu of significantly modifying the uthash code. The hash tables are used to manage the library IDs as those do not delete other IDs when they are closed. * Adds uthash.h to MANIFEST * Removes implicit-fallthrough diagnostic disable Removing -Wimplicit-fallthrough=5 means that the uthash code no longer raises warnings so the H5_GCC_DIAG_OFF/ON macros that disabled those warnings have been removed from H5I.c. * Adds a test to ensure you can delete IDs in the H5Iiterate() callback
Diffstat (limited to 'test/tid.c')
-rw-r--r--test/tid.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/test/tid.c b/test/tid.c
index 27135fc..d3d3116 100644
--- a/test/tid.c
+++ b/test/tid.c
@@ -763,6 +763,79 @@ out:
return -1;
} /* end test_remove_clear_type() */
+
+/* Test that IDs can be deleted while iterating */
+
+#define N_ITERATE_IDS 128
+
+/* A callback that (maybe) closes a random ID when invoked */
+static herr_t
+iterate_delete_op(hid_t H5_ATTR_UNUSED id, void *udata)
+{
+ hid_t *ids = (hid_t *)udata;
+ int closed_index;
+ hid_t closed_id;
+
+ /* Maybe close an ID
+ *
+ * Do nothing when an ID has already been closed so we don't
+ * close ALL the IDs.
+ *
+ * Closing the ID we're currently iterating on is also acceptable.
+ */
+ closed_index = HDrandom() % N_ITERATE_IDS;
+ closed_id = ids[closed_index];
+
+ if (closed_id != H5I_INVALID_HID) {
+ if (H5Sclose(closed_id) < 0)
+ return -1;
+ ids[closed_index] = H5I_INVALID_HID;
+ }
+
+ return 0;
+} /* end iterate_delete_op() */
+
+static int
+test_iteration_remove(void)
+{
+ hid_t *ids = NULL;
+ int i;
+
+ /* Create a bunch of IDs of a single library type */
+ if (NULL == (ids = malloc(N_ITERATE_IDS * sizeof(hid_t))))
+ goto error;
+ for (i = 0; i < N_ITERATE_IDS; i++)
+ if ((ids[i] = H5Screate(H5S_NULL)) == H5I_INVALID_HID)
+ goto error;
+
+ /* Iterate over the IDs, (maybe) closing a random one in the callback */
+ if (H5Iiterate(H5I_DATASPACE, iterate_delete_op, ids) < 0)
+ goto error;
+
+ /* Close and free */
+ for (i = 0; i < N_ITERATE_IDS; i++) {
+ if (ids[i] == H5I_INVALID_HID)
+ continue;
+ if (H5Sclose(ids[i]) < 0)
+ goto error;
+ ids[i] = H5I_INVALID_HID;
+ }
+ HDfree(ids);
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY
+ if (ids != NULL)
+ for (i = 0; i < N_ITERATE_IDS; i++)
+ H5Sclose(ids[i]);
+ H5E_END_TRY
+
+ HDfree(ids);
+
+ return -1;
+} /* end test_iteration_remove() */
+
void
test_ids(void)
{
@@ -781,4 +854,6 @@ test_ids(void)
TestErrPrintf("ID type list test failed\n");
if (test_remove_clear_type() < 0)
TestErrPrintf("ID remove during H5Iclear_type test failed\n");
+ if (test_iteration_remove() < 0)
+ TestErrPrintf("Removing random IDs while iterating failed\n");
}