summaryrefslogtreecommitdiffstats
path: root/test/API/tid.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/API/tid.c')
-rw-r--r--test/API/tid.c1413
1 files changed, 0 insertions, 1413 deletions
diff --git a/test/API/tid.c b/test/API/tid.c
deleted file mode 100644
index 649bacb..0000000
--- a/test/API/tid.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * All rights reserved. *
- * *
- * This file is part of HDF5. The full HDF5 copyright notice, including *
- * terms governing use, modification, and redistribution, is contained in *
- * the COPYING file, which can be found at the root of the source code *
- * distribution tree, or in https://www.hdfgroup.org/licenses. *
- * If you do not have access to either file, you may request a copy from *
- * help@hdfgroup.org. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* Test user-created identifiers (hid_t's) and identifier types. */
-
-#include "testhdf5.h"
-
-#if 0
-/* Include H5Ipkg.h to calculate max number of groups */
-#define H5I_FRIEND /*suppress error about including H5Ipkg */
-#include "H5Ipkg.h"
-#endif
-
-/*
- * Number of bits to use for ID Type in each ID. Increase if more types
- * are needed (though this will decrease the number of available IDs per
- * type). This is the only number that must be changed since all other bit
- * field sizes and masks are calculated from TYPE_BITS.
- */
-#define TYPE_BITS 7
-#define TYPE_MASK (((hid_t)1 << TYPE_BITS) - 1)
-
-#define H5I_MAX_NUM_TYPES TYPE_MASK
-
-static herr_t
-free_wrapper(void *p, void H5_ATTR_UNUSED **_ctx)
-{
- free(p);
- return SUCCEED;
-}
-
-/* Test basic functionality of registering and deleting types and IDs */
-static int
-basic_id_test(void)
-{
- H5I_type_t myType = H5I_BADID;
- hid_t arrayID = H5I_INVALID_HID;
- void *testObj = NULL;
- void *testPtr = NULL;
- char nameString[10];
- hid_t testID;
- ssize_t testSize = -1;
- herr_t err;
- int num_ref;
- hsize_t num_members;
-
- /* Try to register an ID with fictitious types */
- H5E_BEGIN_TRY
- arrayID = H5Iregister((H5I_type_t)420, testObj);
- H5E_END_TRY
-
- VERIFY(arrayID, H5I_INVALID_HID, "H5Iregister");
- if (arrayID != H5I_INVALID_HID)
- goto out;
-
- H5E_BEGIN_TRY
- arrayID = H5Iregister((H5I_type_t)-1, testObj);
- H5E_END_TRY
-
- VERIFY(arrayID, H5I_INVALID_HID, "H5Iregister");
- if (arrayID != H5I_INVALID_HID)
- goto out;
-
- /* Try to access IDs with fictitious types */
- H5E_BEGIN_TRY
- testPtr = H5Iobject_verify((hid_t)100, (H5I_type_t)0);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iobject_verify");
- if (testPtr != NULL)
- goto out;
-
- H5E_BEGIN_TRY
- testPtr = H5Iobject_verify((hid_t)700, (H5I_type_t)700);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iobject_verify");
- if (testPtr != NULL)
- goto out;
-
- /* Register a type */
- myType = H5Iregister_type((size_t)64, 0, free_wrapper);
-
- CHECK(myType, H5I_BADID, "H5Iregister_type");
- if (myType == H5I_BADID)
- goto out;
-
- /* Register an ID and retrieve the object it points to.
- * Once the ID has been registered, testObj will be freed when
- * its ID type is destroyed.
- */
- testObj = malloc(7 * sizeof(int));
- arrayID = H5Iregister(myType, testObj);
-
- CHECK(arrayID, H5I_INVALID_HID, "H5Iregister");
- if (arrayID == H5I_INVALID_HID) {
- free(testObj);
- goto out;
- }
-
- testPtr = (int *)H5Iobject_verify(arrayID, myType);
-
- CHECK_PTR_EQ(testPtr, testObj, "H5Iobject_verify");
- if (testPtr != testObj)
- goto out;
-
- /* Ensure that H5Iget_file_id and H5Iget_name() fail, since this
- * is an hid_t for the wrong kind of object
- */
- H5E_BEGIN_TRY
- testID = H5Iget_file_id(arrayID);
- H5E_END_TRY
-
- VERIFY(testID, H5I_INVALID_HID, "H5Iget_file_id");
- if (testID != H5I_INVALID_HID)
- goto out;
-
- H5E_BEGIN_TRY
- testSize = H5Iget_name(arrayID, nameString, (size_t)9);
- H5E_END_TRY
-
- VERIFY(testSize, -1, "H5Iget_name");
- if (testSize != -1)
- goto out;
-
- /* Make sure H5Iremove_verify catches objects of the wrong type */
- H5E_BEGIN_TRY
- testPtr = (int *)H5Iremove_verify(arrayID, (H5I_type_t)0);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iremove_verify");
- if (testPtr != NULL)
- goto out;
-
- H5E_BEGIN_TRY
- testPtr = (int *)H5Iremove_verify(arrayID, (H5I_type_t)((int)myType - 1));
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iremove_verify");
- if (testPtr != NULL)
- goto out;
-
- /* Remove an ID and make sure we can't access it */
- testPtr = (int *)H5Iremove_verify(arrayID, myType);
-
- CHECK_PTR(testPtr, "H5Iremove_verify");
- if (testPtr == NULL)
- goto out;
-
- H5E_BEGIN_TRY
- testPtr = (int *)H5Iobject_verify(arrayID, myType);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iobject_verify");
- if (testPtr != NULL)
- goto out;
-
- /* Delete the type and make sure we can't access objects within it */
- arrayID = H5Iregister(myType, testObj);
-
- err = H5Idestroy_type(myType);
- VERIFY(err, 0, "H5Idestroy_type");
- if (err != 0)
- goto out;
- VERIFY(H5Itype_exists(myType), 0, "H5Itype_exists");
- if (H5Itype_exists(myType) != 0)
- goto out;
-
- H5E_BEGIN_TRY
- VERIFY(H5Inmembers(myType, NULL), -1, "H5Inmembers");
- if (H5Inmembers(myType, NULL) != -1)
- goto out;
- H5E_END_TRY
-
- /* Register another type and another object in that type */
- myType = H5Iregister_type((size_t)64, 0, free_wrapper);
-
- CHECK(myType, H5I_BADID, "H5Iregister_type");
- if (myType == H5I_BADID)
- goto out;
-
- /* The memory that testObj pointed to should already have been
- * freed when the previous type was destroyed. Allocate new
- * memory for it.
- */
- testObj = malloc(7 * sizeof(int));
- arrayID = H5Iregister(myType, testObj);
-
- CHECK(arrayID, H5I_INVALID_HID, "H5Iregister");
- if (arrayID == H5I_INVALID_HID) {
- free(testObj);
- goto out;
- }
-
- err = H5Inmembers(myType, &num_members);
- CHECK(err, -1, "H5Inmembers");
- if (err < 0)
- goto out;
- VERIFY(num_members, 1, "H5Inmembers");
- if (num_members != 1)
- goto out;
-
- /* Increment references to type and ensure that dec_type_ref
- * doesn't destroy the type
- */
- num_ref = H5Iinc_type_ref(myType);
- VERIFY(num_ref, 2, "H5Iinc_type_ref");
- if (num_ref != 2)
- goto out;
- num_ref = H5Idec_type_ref(myType);
- VERIFY(num_ref, 1, "H5Idec_type_ref");
- if (num_ref != 1)
- goto out;
- err = H5Inmembers(myType, &num_members);
- CHECK(err, -1, "H5Inmembers");
- if (err < 0)
- goto out;
- VERIFY(num_members, 1, "H5Inmembers");
- if (num_members != 1)
- goto out;
-
- /* This call to dec_type_ref should destroy the type */
- num_ref = H5Idec_type_ref(myType);
- VERIFY(num_ref, 0, "H5Idec_type_ref");
- if (num_ref != 0)
- goto out;
- VERIFY(H5Itype_exists(myType), 0, "H5Itype_exists");
- if (H5Itype_exists(myType) != 0)
- goto out;
-
- H5E_BEGIN_TRY
- err = H5Inmembers(myType, &num_members);
- if (err >= 0)
- goto out;
- H5E_END_TRY
-
- return 0;
-
-out:
- /* Clean up type if it has been allocated and free memory used
- * by testObj
- */
- if (myType >= 0)
- H5Idestroy_type(myType);
-
- return -1;
-}
-
-/* A dummy search function for the next test */
-static int
-test_search_func(void H5_ATTR_UNUSED *ptr1, hid_t H5_ATTR_UNUSED id, void H5_ATTR_UNUSED *ptr2)
-{
- return 0;
-}
-
-/* Ensure that public functions cannot access "predefined" ID types */
-static int
-id_predefined_test(void)
-{
- void *testObj;
- hid_t testID;
- hid_t typeID = H5I_INVALID_HID;
- void *testPtr;
- herr_t testErr;
-
- testObj = malloc(sizeof(int));
-
- /*
- * Attempt to perform public functions on various library types
- */
-
- H5E_BEGIN_TRY
- testID = H5Iregister(H5I_FILE, testObj);
- H5E_END_TRY
-
- VERIFY(testID, H5I_INVALID_HID, "H5Iregister");
- if (testID != H5I_INVALID_HID)
- goto out;
-
- H5E_BEGIN_TRY
- testPtr = H5Isearch(H5I_GENPROP_LST, test_search_func, testObj);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Isearch");
- if (testPtr != NULL)
- goto out;
-
- H5E_BEGIN_TRY
- testErr = H5Inmembers(H5I_ERROR_STACK, NULL);
- H5E_END_TRY
-
- VERIFY(testErr, -1, "H5Inmembers");
- if (testErr != -1)
- goto out;
-
- H5E_BEGIN_TRY
- testErr = H5Iclear_type(H5I_FILE, 0);
- H5E_END_TRY
-
- VERIFY((testErr >= 0), 0, "H5Iclear_type");
- if (testErr >= 0)
- goto out;
-
- H5E_BEGIN_TRY
- testErr = H5Idestroy_type(H5I_DATASET);
- H5E_END_TRY
-
- VERIFY((testErr >= 0), 0, "H5Idestroy_type");
- if (testErr >= 0)
- goto out;
-
- H5E_BEGIN_TRY
- testErr = H5Itype_exists(H5I_GROUP);
- H5E_END_TRY
-
- VERIFY(testErr, -1, "H5Itype_exists");
- if (testErr != -1)
- goto out;
-
- H5E_BEGIN_TRY
- testErr = H5Itype_exists(H5I_ATTR);
- H5E_END_TRY
-
- VERIFY(testErr, -1, "H5Itype_exists");
- if (testErr != -1)
- goto out;
-
- /*
- * Create a datatype ID and try to perform illegal functions on it
- */
-
- typeID = H5Tcreate(H5T_OPAQUE, (size_t)42);
- CHECK(typeID, H5I_INVALID_HID, "H5Tcreate");
- if (typeID == H5I_INVALID_HID)
- goto out;
-
- H5E_BEGIN_TRY
- testPtr = H5Iremove_verify(typeID, H5I_DATATYPE);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iremove_verify");
- if (testPtr != NULL)
- goto out;
-
- H5E_BEGIN_TRY
- testPtr = H5Iobject_verify(typeID, H5I_DATATYPE);
- H5E_END_TRY
-
- CHECK_PTR_NULL(testPtr, "H5Iobject_verify");
- if (testPtr != NULL)
- goto out;
-
- H5Tclose(typeID);
-
- /* testObj was never registered as an atom, so it will not be
- * automatically freed. */
- free(testObj);
- return 0;
-
-out:
- if (typeID != H5I_INVALID_HID)
- H5Tclose(typeID);
- if (testObj != NULL)
- free(testObj);
-
- return -1;
-}
-
-/* Test the H5Iis_valid function */
-static int
-test_is_valid(void)
-{
- hid_t dtype; /* datatype id */
-#if 0
- int64_t nmembs1; /* number of type memnbers */
- int64_t nmembs2;
-#endif
- htri_t tri_ret; /* htri_t return value */
-#if 0
- herr_t ret; /* return value */
-#endif
-
- /* Create a datatype id */
- dtype = H5Tcopy(H5T_NATIVE_INT);
- CHECK(dtype, FAIL, "H5Tcopy");
- if (dtype < 0)
- goto out;
-
- /* Check that the ID is valid */
- tri_ret = H5Iis_valid(dtype);
- VERIFY(tri_ret, true, "H5Iis_valid");
- if (tri_ret != true)
- goto out;
-#if 0 /* Cannot call internal APIs and cannot call public H5Inmembers on library types */
- /* Artificially manipulate the reference counts so app_count is 0, and dtype
- * appears to be an internal id. This takes advantage of the fact that
- * H5Ipkg is included.
- */
- ret = H5I_inc_ref(dtype, false);
- CHECK(ret, FAIL, "H5I_inc_ref");
- if (ret < 0)
- goto out;
- ret = H5I_dec_app_ref(dtype);
- CHECK(ret, FAIL, "H5I_dec_ref");
- if (ret < 0)
- goto out;
-
- /* Check that dtype is invalid */
- tri_ret = H5Iis_valid(dtype);
- VERIFY(tri_ret, false, "H5Iis_valid");
- if (tri_ret != false)
- goto out;
-
- /* Close dtype and verify that it has been closed */
- nmembs1 = H5I_nmembers(H5I_DATATYPE);
- CHECK(nmembs1, FAIL, "H5I_nmembers");
- if (nmembs1 < 0)
- goto out;
- ret = H5I_dec_ref(dtype);
- CHECK(ret, FAIL, "H5I_dec_ref");
- if (ret < 0)
- goto out;
- nmembs2 = H5I_nmembers(H5I_DATATYPE);
- VERIFY(nmembs2, nmembs1 - 1, "H5I_nmembers");
- if (nmembs2 != nmembs1 - 1)
- goto out;
-
- /* Check that dtype is invalid */
- tri_ret = H5Iis_valid(dtype);
- VERIFY(tri_ret, false, "H5Iis_valid");
- if (tri_ret != false)
- goto out;
-#endif
- /* Check that an id of -1 is invalid */
- tri_ret = H5Iis_valid((hid_t)-1);
- VERIFY(tri_ret, false, "H4Iis_valid");
- if (tri_ret != false)
- goto out;
-
- return 0;
-
-out:
- /* Don't attempt to close dtype as we don't know the exact state of the
- * reference counts. Every state in this function will be automatically
- * closed at library exit anyways, as internal count is never > 1.
- */
- return -1;
-}
-
-/* Test the H5Iget_type function */
-static int
-test_get_type(void)
-{
- hid_t dtype; /* datatype id */
- H5I_type_t type_ret; /* return value */
-
- /* Create a datatype id */
- dtype = H5Tcopy(H5T_NATIVE_INT);
- CHECK(dtype, FAIL, "H5Tcopy");
- if (dtype < 0)
- goto out;
-
- /* Check that the ID is correct */
- type_ret = H5Iget_type(dtype);
- VERIFY(type_ret, H5I_DATATYPE, "H5Iget_type");
- if (type_ret == H5I_BADID)
- goto out;
-
- /* Check that the ID is correct */
- type_ret = H5Iget_type((hid_t)H5T_STRING);
- VERIFY(type_ret, H5I_BADID, "H5Iget_type");
- if (type_ret != H5I_BADID)
- goto out;
-
- /* Check that the ID is correct */
- type_ret = H5Iget_type((hid_t)-1);
- VERIFY(type_ret, H5I_BADID, "H5Iget_type");
- if (type_ret != H5I_BADID)
- goto out;
-
- H5Tclose(dtype);
-
- return 0;
-
-out:
- if (dtype != H5I_INVALID_HID)
- H5Tclose(dtype);
-
- return -1;
-}
-
-/* Test boundary cases with lots of types */
-
-/* Type IDs range from H5I_NTYPES to H5I_MAX_NUM_TYPES. The system will assign */
-/* IDs in sequential order until H5I_MAX_NUM_TYPES IDs have been given out, at which */
-/* point it will search for type IDs that were allocated but have since been */
-/* deleted. */
-/* This test will allocate IDs up to H5I_MAX_NUM_TYPES, ensure that IDs wrap around */
-/* to low values successfully, ensure that an error is thrown when all possible */
-/* type IDs are taken, then ensure that deleting types frees up their IDs. */
-/* Note that this test depends on the implementation of IDs, so may break */
-/* if the implementation changes. */
-/* Also note that if someone else registered a user-defined type and forgot to */
-/* destroy it, this test will mysteriously fail (because it will expect there to */
-/* be one more "free" type ID than there is). */
-/* H5I_NTYPES is defined in h5public.h, H5I_MAX_NUM_TYPES is defined in h5pkg.h */
-static int
-test_id_type_list(void)
-{
- H5I_type_t startType; /* The first type ID we were assigned in this test */
- H5I_type_t currentType;
- H5I_type_t testType;
- int i; /* Just a counter variable */
-
- startType = H5Iregister_type((size_t)8, 0, free_wrapper);
- CHECK(startType, H5I_BADID, "H5Iregister_type");
- if (startType == H5I_BADID)
- goto out;
-
- /* Sanity check */
- if ((int)startType >= H5I_MAX_NUM_TYPES || startType < H5I_NTYPES) {
- /* Error condition, throw an error */
- ERROR("H5Iregister_type");
- goto out;
- }
- /* Create types up to H5I_MAX_NUM_TYPES */
- for (i = startType + 1; i < H5I_MAX_NUM_TYPES; i++) {
- currentType = H5Iregister_type((size_t)8, 0, free_wrapper);
- CHECK(currentType, H5I_BADID, "H5Iregister_type");
- if (currentType == H5I_BADID)
- goto out;
- }
-
- /* Wrap around to low type ID numbers */
- for (i = H5I_NTYPES; i < startType; i++) {
- currentType = H5Iregister_type((size_t)8, 0, free_wrapper);
- CHECK(currentType, H5I_BADID, "H5Iregister_type");
- if (currentType == H5I_BADID)
- goto out;
- }
-
- /* There should be no room at the inn for a new ID type*/
- H5E_BEGIN_TRY
- testType = H5Iregister_type((size_t)8, 0, free_wrapper);
- H5E_END_TRY
-
- VERIFY(testType, H5I_BADID, "H5Iregister_type");
- if (testType != H5I_BADID)
- goto out;
-
- /* Now delete a type and try to insert again */
- H5Idestroy_type(H5I_NTYPES);
- testType = H5Iregister_type((size_t)8, 0, free_wrapper);
-
- VERIFY(testType, H5I_NTYPES, "H5Iregister_type");
- if (testType != H5I_NTYPES)
- goto out;
-
- /* Cleanup. Destroy all types. */
- for (i = H5I_NTYPES; i < H5I_MAX_NUM_TYPES; i++)
- H5Idestroy_type((H5I_type_t)i);
-
- return 0;
-
-out:
- /* Cleanup. For simplicity, just destroy all types and ignore errors. */
- H5E_BEGIN_TRY
- for (i = H5I_NTYPES; i < H5I_MAX_NUM_TYPES; i++)
- H5Idestroy_type((H5I_type_t)i);
- H5E_END_TRY
- return -1;
-}
-
-/* Test removing ids in callback for H5Iclear_type */
-
-/* There was a rare bug where, if an id free callback being called by
- * H5I_clear_type() removed another id in that type, a segfault could occur.
- * This test tests for that error (and freeing ids "out of order" within
- * H5Iclear_type() in general).
- *
- * NB: RCT = "remove clear type"
- */
-
-/* Macro definitions */
-#define RCT_MAX_NOBJS 25 /* Maximum number of objects in the list */
-#define RCT_MIN_NOBJS 5
-#define RCT_NITER 50 /* Number of times we cycle through object creation and deletion */
-
-/* Structure to hold the master list of objects */
-typedef struct rct_obj_list_t {
-
- /* Pointer to the objects */
- struct rct_obj_t *objects;
-
- /* The number of objects in the list */
- long count;
-
- /* The number of objects in the list that have not been freed */
- long remaining;
-} rct_obj_list_t;
-
-/* Structure for an object */
-typedef struct rct_obj_t {
- /* The ID for this object */
- hid_t id;
-
- /* The number of times this object has been freed */
- int nfrees;
-
- /* Whether we are currently freeing this object directly
- * through H5Idec_ref().
- */
- bool freeing;
-
- /* Pointer to the master list of all objects */
- rct_obj_list_t *list;
-} rct_obj_t;
-
-/* Free callback passed to H5Iclear_type()
- *
- * When invoked on a closing object, frees a random unfreed ID in the
- * master list of objects.
- */
-static herr_t
-rct_free_cb(void *_obj, void H5_ATTR_UNUSED **_ctx)
-{
- rct_obj_t *obj = (rct_obj_t *)_obj;
- long remove_nth;
- long i;
- herr_t ret;
-
- /* Mark this object as freed */
- obj->nfrees++;
-
- /* Decrement the number of objects in the list that have not been freed */
- obj->list->remaining--;
-
- /* If this object isn't already being freed by a callback free call and
- * the master object list still contains objects to free, pick another
- * object and free it.
- */
- if (!obj->freeing && (obj->list->remaining > 0)) {
-
- /* Pick a random object from the list. This is done by picking a
- * random number between 0 and the # of remaining unfreed objects
- * and then scanning through the list to find that nth unfreed
- * object.
- */
- remove_nth = HDrandom() % obj->list->remaining;
- for (i = 0; i < obj->list->count; i++)
- if (obj->list->objects[i].nfrees == 0) {
- if (remove_nth == 0)
- break;
- else
- remove_nth--;
- }
-
- /* Badness if we scanned through the list and didn't manage to
- * select one to delete (the list stats were probably updated
- * incorrectly).
- */
- if (i == obj->list->count) {
- ERROR("invalid obj_list");
- goto error;
- }
-
- /* Mark the object we're about to free so its own callback does
- * not free another object. We don't want to recursively free the
- * entire list when we free the first ID.
- */
- obj->list->objects[i].freeing = true;
-
- /* Decrement the reference count on the object */
- ret = H5Idec_ref(obj->list->objects[i].id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (ret == FAIL)
- goto error;
-
- /* Unset the "freeing" flag */
- obj->list->objects[i].freeing = false;
- }
-
- /* Verify the number of objects remaining in the master list is non-negative */
- if (obj->list->remaining < 0) {
- ERROR("invalid number of objects remaining");
- goto error;
- }
-
- return 0;
-
-error:
- return -1;
-} /* end rct_free_cb() */
-
-/* Test function */
-static int
-test_remove_clear_type(void)
-{
- H5I_type_t obj_type;
- rct_obj_list_t obj_list;
- rct_obj_t *objects = NULL; /* Convenience pointer to objects stored in master list */
- size_t list_size;
- long i, j;
- herr_t ret; /* return value */
-
- /* Register a user-defined type with our custom ID-deleting callback */
- obj_type = H5Iregister_type((size_t)8, 0, rct_free_cb);
- CHECK(obj_type, H5I_BADID, "H5Iregister_type");
- if (obj_type == H5I_BADID)
- goto error;
-
- /* Create an array to hold the objects in the master list */
- list_size = RCT_MAX_NOBJS * sizeof(rct_obj_t);
- obj_list.objects = malloc(list_size);
- CHECK_PTR(obj_list.objects, "calloc");
- if (NULL == obj_list.objects)
- goto error;
-
- /* Set a convenience pointer to the object array */
- objects = obj_list.objects;
-
- for (i = 0; i < RCT_NITER; i++) {
-
- /* The number of members in the type, according to the HDF5 library */
- hsize_t nmembers = 1234567; /* (init to fake number) */
-
- /* The number of objects found while scanning through the object list */
- int found;
-
- /*********************
- * Build object list *
- *********************/
-
- memset(obj_list.objects, 0, list_size);
-
- /* The number of objects used is a random number between the min and max */
- obj_list.count = obj_list.remaining =
- RCT_MIN_NOBJS + (HDrandom() % (long)(RCT_MAX_NOBJS - RCT_MIN_NOBJS + 1));
-
- /* Create the actual objects */
- for (j = 0; j < obj_list.count; j++) {
-
- /* Object setup */
- objects[j].nfrees = 0;
- objects[j].freeing = false;
- objects[j].list = &obj_list;
-
- /* Register an ID for it */
- objects[j].id = H5Iregister(obj_type, &objects[j]);
- CHECK(objects[j].id, FAIL, "H5Iregister");
- if (objects[j].id == FAIL)
- goto error;
-
- /* Bump the reference count by 1 (to 2) 50% of the time */
- if (HDrandom() % 2) {
- ret = H5Iinc_ref(objects[j].id);
- CHECK(ret, FAIL, "H5Iinc_ref");
- if (ret == FAIL)
- goto error;
- }
- }
-
- /******************************************
- * Clear the type with force set to false *
- ******************************************/
-
- /* Clear the type. Since force is false, only
- * IDs with a reference count of 1 will be cleared.
- */
- ret = H5Iclear_type(obj_type, false);
- CHECK(ret, FAIL, "H5Iclear_type");
- if (ret == FAIL)
- goto error;
-
- /* Verify that the object struct fields are sane and count the
- * number of unfreed objects
- */
- found = 0;
- for (j = 0; j < obj_list.count; j++) {
-
- if (objects[j].nfrees == 0) {
- /* Count unfreed objects */
- found++;
- }
- else {
- /* Every freed object should have been freed exactly once */
- VERIFY(objects[j].nfrees, 1, "object freed more than once");
- if (objects[j].nfrees != 1)
- goto error;
- }
-
- /* No object should still be marked as "freeing" */
- VERIFY(objects[j].freeing, false, "object marked as freeing");
- if (objects[j].freeing != false)
- goto error;
- }
-
- /* Verify the number of unfreed objects we found during our scan
- * matches the number stored in the list
- */
- VERIFY(obj_list.remaining, found, "incorrect number of objects remaining");
- if (obj_list.remaining != found)
- goto error;
-
- /* Make sure the HDF5 library confirms our count */
- ret = H5Inmembers(obj_type, &nmembers);
- CHECK(ret, FAIL, "H5Inmembers");
- if (ret == FAIL)
- goto error;
- VERIFY(nmembers, found, "The number of members remaining in the type did not match our count");
- if (nmembers != (hsize_t)found)
- goto error;
-
- /*****************************************
- * Clear the type with force set to true *
- *****************************************/
-
- /* Clear the type. Since force is true, all IDs will be cleared. */
- ret = H5Iclear_type(obj_type, true);
- CHECK(ret, FAIL, "H5Iclear_type");
- if (ret == FAIL)
- goto error;
-
- /* Verify that the object struct fields are sane */
- for (j = 0; j < obj_list.count; j++) {
-
- /* Every object should have been freed exactly once */
- VERIFY(objects[j].nfrees, 1, "object freed more than once");
- if (objects[j].nfrees != 1)
- goto error;
-
- /* No object should still be marked as "freeing" */
- VERIFY(objects[j].freeing, false, "object marked as freeing");
- if (objects[j].freeing != false)
- goto error;
- }
-
- /* Verify the number of objects is 0 */
- VERIFY(obj_list.remaining, 0, "objects remaining was not zero");
- if (obj_list.remaining != 0)
- goto error;
-
- /* Make sure the HDF5 library confirms zero members in the type */
- ret = H5Inmembers(obj_type, &nmembers);
- CHECK(ret, FAIL, "H5Inmembers");
- if (ret == FAIL)
- goto error;
- VERIFY(nmembers, 0, "The number of members remaining in the type was not zero");
- if (nmembers != 0)
- goto error;
- }
-
- /* Destroy the type */
- ret = H5Idestroy_type(obj_type);
- CHECK(ret, FAIL, "H5Idestroy_type");
- if (ret == FAIL)
- goto error;
-
- /* Free the object array */
- free(obj_list.objects);
-
- return 0;
-
-error:
- /* Cleanup. For simplicity, just destroy the types and ignore errors. */
- H5E_BEGIN_TRY
- {
- H5Idestroy_type(obj_type);
- }
- H5E_END_TRY
-
- free(obj_list.objects);
-
- return -1;
-} /* end test_remove_clear_type() */
-
-#if defined(H5VL_VERSION) && H5VL_VERSION >= 2
-/* Typedef for future objects */
-typedef struct {
- H5I_type_t obj_type; /* ID type for actual object */
-} future_obj_t;
-
-/* Global (static) future ID object type */
-H5I_type_t future_obj_type_g = H5I_BADID;
-
-/* Callback to free the actual object for future object test */
-static herr_t
-free_actual_object(void *_p, void H5_ATTR_UNUSED **_ctx)
-{
- int *p = (int *)_p;
-
- if (7 != *p)
- return FAIL;
-
- free(p);
-
- return SUCCEED;
-}
-
-/* Callback to realize a future object */
-static herr_t
-realize_future_cb(void *_future_obj, hid_t *actual_id)
-{
- future_obj_t *future_obj = (future_obj_t *)_future_obj; /* Future object */
- int *actual_obj; /* Pointer to the actual object */
-
- /* Check for bad future object */
- if (NULL == future_obj)
- return FAIL;
-
- /* Determine type of object to realize */
- if (H5I_DATASPACE == future_obj->obj_type) {
- hsize_t dims = 13;
-
- if ((*actual_id = H5Screate_simple(1, &dims, NULL)) < 0)
- return FAIL;
- }
- else if (H5I_DATATYPE == future_obj->obj_type) {
- if ((*actual_id = H5Tcopy(H5T_NATIVE_INT)) < 0)
- return FAIL;
- }
- else if (H5I_GENPROP_LST == future_obj->obj_type) {
- if ((*actual_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
- return FAIL;
- }
- else {
- /* Create a new object (the 'actual object') of the correct type */
- if (NULL == (actual_obj = malloc(sizeof(int))))
- return FAIL;
- *actual_obj = 7;
-
- /* Register actual object of the user-defined type */
- *actual_id = H5Iregister(future_obj->obj_type, actual_obj);
- CHECK(*actual_id, FAIL, "H5Iregister");
- if (*actual_id == FAIL)
- return FAIL;
- }
-
- return SUCCEED;
-}
-
-/* Callback to discard a future object */
-static herr_t
-discard_future_cb(void *future_obj)
-{
- if (NULL == future_obj)
- return FAIL;
-
- free(future_obj);
-
- return SUCCEED;
-}
-
-/* Callback to realize a future object when future objects are NULL*/
-static herr_t
-realize_future_generate_cb(void *_future_obj, hid_t *actual_id)
-{
- future_obj_t *future_obj = (future_obj_t *)_future_obj; /* Future object */
- int *actual_obj; /* Pointer to the actual object */
-
- if (NULL != future_obj)
- return FAIL;
- /* Create a new object (the 'actual object') of the correct type */
- if (NULL == (actual_obj = malloc(sizeof(int))))
- return FAIL;
- *actual_obj = 7;
-
- /* Register actual object without using future object info */
- *actual_id = H5Iregister(future_obj_type_g, actual_obj);
- CHECK(*actual_id, FAIL, "H5Iregister");
- if (*actual_id == FAIL)
- return FAIL;
-
- return SUCCEED;
-}
-
-/* Callback to discard a future object when future objects are NULL */
-static herr_t
-discard_future_generate_cb(void *future_obj)
-{
- if (NULL != future_obj)
- return FAIL;
-
- return SUCCEED;
-}
-
-/* Test function */
-static int
-test_future_ids(void)
-{
- H5I_type_t obj_type; /* New user-defined ID type */
- hid_t future_id; /* ID for future object */
- int fake_future_obj; /* "Fake" future object for tests */
- future_obj_t *future_obj; /* Future object */
- int *actual_obj; /* Actual object */
- int *actual_obj2; /* Another actual object */
- H5I_type_t id_type; /* Type of ID */
- H5T_class_t type_class; /* Datatype class */
- herr_t ret; /* Return value */
-
- /* Register a user-defined type with our custom ID-deleting callback */
- obj_type = H5Iregister_type((size_t)15, 0, free_actual_object);
- CHECK(obj_type, H5I_BADID, "H5Iregister_type");
- if (H5I_BADID == obj_type)
- goto error;
-
- /* Test basic error conditions */
- fake_future_obj = 0;
- H5E_BEGIN_TRY
- {
- future_id = H5Iregister_future(obj_type, &fake_future_obj, NULL, NULL);
- }
- H5E_END_TRY
- VERIFY(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID != future_id)
- goto error;
-
- H5E_BEGIN_TRY
- {
- future_id = H5Iregister_future(obj_type, &fake_future_obj, realize_future_cb, NULL);
- }
- H5E_END_TRY
- VERIFY(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID != future_id)
- goto error;
-
- H5E_BEGIN_TRY
- {
- future_id = H5Iregister_future(obj_type, &fake_future_obj, NULL, discard_future_cb);
- }
- H5E_END_TRY
- VERIFY(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID != future_id)
- goto error;
-
- H5E_BEGIN_TRY
- {
- future_id = H5Iregister_future(H5I_BADID, &fake_future_obj, realize_future_cb, discard_future_cb);
- }
- H5E_END_TRY
- VERIFY(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID != future_id)
- goto error;
-
- /* Test base use-case: create a future object and destroy type without
- * realizing the future object.
- */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = obj_type;
- future_id = H5Iregister_future(obj_type, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Destroy the type */
- ret = H5Idestroy_type(obj_type);
- CHECK(ret, FAIL, "H5Idestroy_type");
- if (FAIL == ret)
- goto error;
-
- /* Re-register a user-defined type with our custom ID-deleting callback */
- obj_type = H5Iregister_type((size_t)15, 0, free_actual_object);
- CHECK(obj_type, H5I_BADID, "H5Iregister_type");
- if (H5I_BADID == obj_type)
- goto error;
-
- /* Test base use-case: create a future object and realize the actual object. */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = obj_type;
- future_id = H5Iregister_future(obj_type, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- actual_obj = H5Iobject_verify(future_id, obj_type);
- CHECK_PTR(actual_obj, "H5Iobject_verify");
- if (NULL == actual_obj)
- goto error;
- VERIFY(*actual_obj, 7, "H5Iobject_verify");
- if (7 != *actual_obj)
- goto error;
-
- /* Retrieve the object again and verify that it's the same actual object */
- actual_obj2 = H5Iobject_verify(future_id, obj_type);
- CHECK_PTR(actual_obj2, "H5Iobject_verify");
- if (NULL == actual_obj2)
- goto error;
- VERIFY(*actual_obj2, 7, "H5Iobject_verify");
- if (7 != *actual_obj2)
- goto error;
- CHECK_PTR_EQ(actual_obj, actual_obj2, "H5Iobject_verify");
- if (actual_obj != actual_obj2)
- goto error;
-
- /* Destroy the type */
- ret = H5Idestroy_type(obj_type);
- CHECK(ret, FAIL, "H5Idestroy_type");
- if (FAIL == ret)
- goto error;
-
- /* Re-register a user-defined type with our custom ID-deleting callback */
- obj_type = H5Iregister_type((size_t)15, 0, free_actual_object);
- CHECK(obj_type, H5I_BADID, "H5Iregister_type");
- if (H5I_BADID == obj_type)
- goto error;
-
- /* Set the global future object type */
- future_obj_type_g = obj_type;
-
- /* Test "actual object generator" use-case: create a future object with
- * NULL object pointer, to create new object of predefined type when
- * future object is realized.
- */
- future_id = H5Iregister_future(obj_type, NULL, realize_future_generate_cb, discard_future_generate_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Realize the actual object, with will be dynamically allocated within
- * the 'realize' callback.
- */
- actual_obj = H5Iobject_verify(future_id, obj_type);
- CHECK_PTR(actual_obj, "H5Iobject_verify");
- if (NULL == actual_obj)
- goto error;
- VERIFY(*actual_obj, 7, "H5Iobject_verify");
- if (7 != *actual_obj)
- goto error;
-
- /* Reset the global future object type */
- future_obj_type_g = H5I_BADID;
-
- /* Retrieve the object again and verify that it's the same actual object */
- /* (Will fail if global future object type used) */
- actual_obj2 = H5Iobject_verify(future_id, obj_type);
- CHECK_PTR(actual_obj2, "H5Iobject_verify");
- if (NULL == actual_obj2)
- goto error;
- VERIFY(*actual_obj2, 7, "H5Iobject_verify");
- if (7 != *actual_obj2)
- goto error;
- CHECK_PTR_EQ(actual_obj, actual_obj2, "H5Iobject_verify");
- if (actual_obj != actual_obj2)
- goto error;
-
- /* Destroy the type */
- ret = H5Idestroy_type(obj_type);
- CHECK(ret, FAIL, "H5Idestroy_type");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- /* (DATASPACE) */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_DATASPACE;
- future_id = H5Iregister_future(H5I_DATASPACE, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* (Can't verify the type of the future ID, because the library's current
- * implementation realizes the object during sanity checks on the ID)
- */
-
- /* Close future object for pre-defined type without realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_DATASPACE;
- future_id = H5Iregister_future(H5I_DATASPACE, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Verify that the application believes the future ID is a dataspace */
- /* (Currently realizes the object "implicitly" during a sanity check) */
- id_type = H5Iget_type(future_id);
- CHECK(id_type, H5I_BADID, "H5Iget_type");
- if (H5I_BADID == id_type)
- goto error;
- if (H5I_DATASPACE != id_type)
- goto error;
-
- /* Close future object for pre-defined type without realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_DATASPACE;
- future_id = H5Iregister_future(H5I_DATASPACE, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Realize future dataspace by requesting its rank */
- ret = H5Sget_simple_extent_ndims(future_id);
- CHECK(ret, FAIL, "H5Sget_simple_extent_ndims");
- if (FAIL == ret)
- goto error;
- if (1 != ret)
- goto error;
-
- /* Verify that the application believes the ID is still a dataspace */
- id_type = H5Iget_type(future_id);
- CHECK(id_type, H5I_BADID, "H5Iget_type");
- if (H5I_BADID == id_type)
- goto error;
- if (H5I_DATASPACE != id_type)
- goto error;
-
- /* Close future object for pre-defined type after realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- /* (DATATYPE) */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_DATATYPE;
- future_id = H5Iregister_future(H5I_DATATYPE, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* (Can't verify the type of the future ID, because the library's current
- * implementation realizes the object during sanity checks on the ID)
- */
-
- /* Close future object for pre-defined type without realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_DATATYPE;
- future_id = H5Iregister_future(H5I_DATATYPE, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Verify that the application believes the future ID is a datatype */
- /* (Currently realizes the object "implicitly" during a sanity check) */
- id_type = H5Iget_type(future_id);
- CHECK(id_type, H5I_BADID, "H5Iget_type");
- if (H5I_BADID == id_type)
- goto error;
- if (H5I_DATATYPE != id_type)
- goto error;
-
- /* Close future object for pre-defined type without realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_DATATYPE;
- future_id = H5Iregister_future(H5I_DATATYPE, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Realize future datatype by requesting its class */
- type_class = H5Tget_class(future_id);
- CHECK(ret, FAIL, "H5Tget_class");
- if (FAIL == ret)
- goto error;
- if (H5T_INTEGER != type_class)
- goto error;
-
- /* Verify that the application believes the ID is still a datatype */
- id_type = H5Iget_type(future_id);
- CHECK(id_type, H5I_BADID, "H5Iget_type");
- if (H5I_BADID == id_type)
- goto error;
- if (H5I_DATATYPE != id_type)
- goto error;
-
- /* Close future object for pre-defined type after realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- /* (PROPERTY LIST) */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_GENPROP_LST;
- future_id = H5Iregister_future(H5I_GENPROP_LST, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* (Can't verify the type of the future ID, because the library's current
- * implementation realizes the object during sanity checks on the ID)
- */
-
- /* Close future object for pre-defined type without realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_GENPROP_LST;
- future_id = H5Iregister_future(H5I_GENPROP_LST, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Verify that the application believes the future ID is a property list */
- /* (Currently realizes the object "implicitly" during a sanity check) */
- id_type = H5Iget_type(future_id);
- CHECK(id_type, H5I_BADID, "H5Iget_type");
- if (H5I_BADID == id_type)
- goto error;
- if (H5I_GENPROP_LST != id_type)
- goto error;
-
- /* Close future object for pre-defined type without realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- /* Test base use-case: create a future object for a pre-defined type */
- future_obj = malloc(sizeof(future_obj_t));
- future_obj->obj_type = H5I_GENPROP_LST;
- future_id = H5Iregister_future(H5I_GENPROP_LST, future_obj, realize_future_cb, discard_future_cb);
- CHECK(future_id, H5I_INVALID_HID, "H5Iregister_future");
- if (H5I_INVALID_HID == future_id)
- goto error;
-
- /* Realize future property list by verifying its class */
- ret = H5Pisa_class(future_id, H5P_DATASET_XFER);
- CHECK(ret, FAIL, "H5Pisa_class");
- if (FAIL == ret)
- goto error;
- if (true != ret)
- goto error;
-
- /* Verify that the application believes the ID is still a property list */
- id_type = H5Iget_type(future_id);
- CHECK(id_type, H5I_BADID, "H5Iget_type");
- if (H5I_BADID == id_type)
- goto error;
- if (H5I_GENPROP_LST != id_type)
- goto error;
-
- /* Close future object for pre-defined type after realizing it */
- ret = H5Idec_ref(future_id);
- CHECK(ret, FAIL, "H5Idec_ref");
- if (FAIL == ret)
- goto error;
-
- return 0;
-
-error:
- /* Cleanup. For simplicity, just destroy the types and ignore errors. */
- H5E_BEGIN_TRY
- {
- H5Idestroy_type(obj_type);
- }
- H5E_END_TRY
-
- return -1;
-} /* end test_future_ids() */
-#endif
-
-void
-test_ids(void)
-{
- /* Set the random # seed */
- HDsrandom((unsigned)HDtime(NULL));
-
- if (basic_id_test() < 0)
- TestErrPrintf("Basic ID test failed\n");
- if (id_predefined_test() < 0)
- TestErrPrintf("Predefined ID type test failed\n");
- if (test_is_valid() < 0)
- TestErrPrintf("H5Iis_valid test failed\n");
- if (test_get_type() < 0)
- TestErrPrintf("H5Iget_type test failed\n");
- if (test_id_type_list() < 0)
- TestErrPrintf("ID type list test failed\n");
- if (test_remove_clear_type() < 0)
- TestErrPrintf("ID remove during H5Iclear_type test failed\n");
-#if defined(H5VL_VERSION) && H5VL_VERSION >= 2
- if (test_future_ids() < 0)
- TestErrPrintf("Future ID test failed\n");
-#endif
-}