diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-12-11 18:26:51 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-12-11 18:26:51 (GMT) |
commit | c44fd88805c4b342f80167e9237e5ecf7f71a158 (patch) | |
tree | 7d4f50e19482ba113f9a858e0c9c3c50ef9d4051 | |
parent | e653e45eced98b037ed17b3174b3663acd04104f (diff) | |
download | hdf5-c44fd88805c4b342f80167e9237e5ecf7f71a158.zip hdf5-c44fd88805c4b342f80167e9237e5ecf7f71a158.tar.gz hdf5-c44fd88805c4b342f80167e9237e5ecf7f71a158.tar.bz2 |
[svn-r7932] Purpose:
Add new feature
Description:
Add new H5I{dec|get|inc}_ref() routines and tests for them.
Platforms tested:
FreeBSD 4.9 (sleipnir)
h5committest
-rw-r--r-- | src/H5I.c | 233 | ||||
-rw-r--r-- | src/H5Ipublic.h | 11 | ||||
-rw-r--r-- | test/tmisc.c | 441 |
3 files changed, 649 insertions, 36 deletions
@@ -118,6 +118,7 @@ H5FL_DEFINE_STATIC(H5I_id_info_t); static herr_t H5I_init_interface(void); static H5I_id_info_t *H5I_find_id(hid_t id); static hid_t H5I_get_file_id(hid_t obj_id); +static int H5I_get_ref(hid_t id); #ifdef H5I_DEBUG_OUTPUT static herr_t H5I_debug(H5I_type_t grp); #endif /* H5I_DEBUG_OUTPUT */ @@ -959,6 +960,44 @@ done: /*------------------------------------------------------------------------- + * Function: H5Idec_ref + * + * Purpose: Decrements the number of references outstanding for an ID. + * If the reference count for an ID reaches zero, the object + * will be closed. + * + * Return: Success: New reference count + * Failure: Negative + * + * Programmer: Quincey Koziol + * Dec 7, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Idec_ref(hid_t id) +{ + int ret_value; /* Return value */ + + FUNC_ENTER_API(H5Idec_ref, FAIL); + H5TRACE1("Is","i",id); + + /* Check arguments */ + if (id<0) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID"); + + /* Do actual decrement operation */ + if((ret_value = H5I_dec_ref(id))<0) + HGOTO_ERROR (H5E_ATOM, H5E_CANTDEC, FAIL, "can't decrement ID ref count"); + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Idec_ref() */ + + +/*------------------------------------------------------------------------- * Function: H5I_dec_ref * * Purpose: Decrements the number of references outstanding for an ID. @@ -999,41 +1038,47 @@ done: int H5I_dec_ref(hid_t id) { - H5I_type_t grp = H5I_GRP(id); /*group the object is in*/ - H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */ - H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */ - int ret_value=FAIL; /*return value */ + H5I_type_t grp; /*group the object is in*/ + H5I_id_group_t *grp_ptr; /*ptr to the group */ + H5I_id_info_t *id_ptr; /*ptr to the new ID */ + int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5I_dec_ref, FAIL); + /* Sanity check */ + assert(id>=0); + /* Check arguments */ + grp = H5I_GRP(id); + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number"); grp_ptr = H5I_id_group_list_g[grp]; if (grp_ptr == NULL || grp_ptr->count <= 0) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number"); /* General lookup of the ID */ - if ((id_ptr=H5I_find_id(id))) { - /* - * If this is the last reference to the object then invoke the group's - * free method on the object. If the free method is undefined or - * successful then remove the object from the group; otherwise leave - * the object in the group without decrementing the reference - * count. If the reference count is more than one then decrement the - * reference count without calling the free method. - * - * Beware: the free method may call other H5I functions. - */ - if (1==id_ptr->count) { - if (!grp_ptr->free_func || - (grp_ptr->free_func)(id_ptr->obj_ptr)>=0) { - H5I_remove(id); - ret_value = 0; - } else { - ret_value = FAIL; - } - } else { - ret_value = --(id_ptr->count); - } + if ((id_ptr=H5I_find_id(id))==NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID"); + + /* + * If this is the last reference to the object then invoke the group's + * free method on the object. If the free method is undefined or + * successful then remove the object from the group; otherwise leave + * the object in the group without decrementing the reference + * count. If the reference count is more than one then decrement the + * reference count without calling the free method. + * + * Beware: the free method may call other H5I functions. + */ + if (1==id_ptr->count) { + if (!grp_ptr->free_func || (grp_ptr->free_func)(id_ptr->obj_ptr)>=0) { + H5I_remove(id); + ret_value = 0; + } else { + ret_value = FAIL; + } + } else { + ret_value = --(id_ptr->count); } done: @@ -1042,6 +1087,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5Iinc_ref + * + * Purpose: Increments the number of references outstanding for an ID. + * + * Return: Success: New reference count + * Failure: Negative + * + * Programmer: Quincey Koziol + * Dec 7, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Iinc_ref(hid_t id) +{ + int ret_value; /* Return value */ + + FUNC_ENTER_API(H5Iinc_ref, FAIL); + H5TRACE1("Is","i",id); + + /* Check arguments */ + if (id<0) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID"); + + /* Do actual increment operation */ + if((ret_value = H5I_inc_ref(id))<0) + HGOTO_ERROR (H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count"); + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Iinc_ref() */ + + +/*------------------------------------------------------------------------- * Function: H5I_inc_ref * * Purpose: Increment the reference count for an object. @@ -1060,16 +1141,105 @@ done: int H5I_inc_ref(hid_t id) { - H5I_type_t grp = H5I_GRP(id); /*group the object is in*/ - H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */ - H5I_id_info_t *id_ptr = NULL; /*ptr to the ID */ - int ret_value; /* Return value */ + H5I_type_t grp; /*group the object is in*/ + H5I_id_group_t *grp_ptr; /*ptr to the group */ + H5I_id_info_t *id_ptr; /*ptr to the ID */ + int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5I_inc_ref, FAIL); + /* Sanity check */ + assert(id>=0); + + /* Check arguments */ + grp = H5I_GRP(id); + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number"); + grp_ptr = H5I_id_group_list_g[grp]; + if (!grp_ptr || grp_ptr->count<=0) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group"); + + /* General lookup of the ID */ + if (NULL==(id_ptr=H5I_find_id(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID"); + + /* Set return value */ + ret_value=++(id_ptr->count); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Iget_ref + * + * Purpose: Retrieves the number of references outstanding for an ID. + * + * Return: Success: Reference count + * Failure: Negative + * + * Programmer: Quincey Koziol + * Dec 7, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Iget_ref(hid_t id) +{ + int ret_value; /* Return value */ + + FUNC_ENTER_API(H5Iget_ref, FAIL); + H5TRACE1("Is","i",id); + /* Check arguments */ if (id<0) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID"); + + /* Do actual retrieve operation */ + if((ret_value = H5I_get_ref(id))<0) + HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count"); + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Iget_ref() */ + + +/*------------------------------------------------------------------------- + * Function: H5I_get_ref + * + * Purpose: Retrieve the reference count for an object. + * + * Return: Success: The reference count. + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, Decemeber 6, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5I_get_ref(hid_t id) +{ + H5I_type_t grp; /*group the object is in*/ + H5I_id_group_t *grp_ptr; /*ptr to the group */ + H5I_id_info_t *id_ptr; /*ptr to the ID */ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5I_get_ref, FAIL); + + /* Sanity check */ + assert(id>=0); + + /* Check arguments */ + grp = H5I_GRP(id); + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number"); grp_ptr = H5I_id_group_list_g[grp]; if (!grp_ptr || grp_ptr->count<=0) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group"); @@ -1077,14 +1247,13 @@ H5I_inc_ref(hid_t id) /* General lookup of the ID */ if (NULL==(id_ptr=H5I_find_id(id))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID"); - id_ptr->count++; /* Set return value */ ret_value=id_ptr->count; done: FUNC_LEAVE_NOAPI(ret_value); -} +} /* end H5I_get_ref() */ /*------------------------------------------------------------------------- diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index eb97994..9c4d950 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -27,6 +27,10 @@ * tracing output look better when hid_t values are large numbers. Change the * GROUP_BITS in H5I.c if the MAXID gets larger than 32 (an assertion will * fail otherwise). + * + * When adding groups here, add a section to the 'misc19' test in test/tmisc.c + * to verify that the H5I{inc|dec|get}_ref() routines work correctly with in. + * */ typedef enum { H5I_BADID = (-1), /*invalid Group */ @@ -59,8 +63,11 @@ extern "C" { /* Public API functions */ H5_DLL H5I_type_t H5Iget_type(hid_t id); -H5_DLL hid_t H5Iget_file_id(hid_t obj_id); -H5_DLL ssize_t H5Iget_name(hid_t object_id, char *name/*out*/, size_t size); +H5_DLL hid_t H5Iget_file_id(hid_t id); +H5_DLL ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size); +H5_DLL int H5Iinc_ref(hid_t id); +H5_DLL int H5Idec_ref(hid_t id); +H5_DLL int H5Iget_ref(hid_t id); #ifdef __cplusplus } diff --git a/test/tmisc.c b/test/tmisc.c index 9b750c8..4bfbde4 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -12,8 +12,6 @@ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* $Id$ */ - /*********************************************************** * * Test program: tmisc @@ -213,6 +211,11 @@ unsigned m13_rdata[MISC13_DIM1][MISC13_DIM2]; /* Data read from dataset #define MISC18_DSET1_NAME "Dataset1" #define MISC18_DSET2_NAME "Dataset2" +/* Definitions for misc. test #19 */ +#define MISC19_FILE "tmisc19.h5" +#define MISC19_DSET_NAME "Dataset" +#define MISC19_ATTR_NAME "Attribute" +#define MISC19_GROUP_NAME "Group" /**************************************************************** ** @@ -2907,6 +2910,438 @@ test_misc18(void) /**************************************************************** ** +** test_misc19(): Test incrementing & decrementing ref count on IDs +** +****************************************************************/ +static void +test_misc19(void) +{ + hid_t fid; /* File ID */ + hid_t sid; /* 'Space ID */ + hid_t did; /* Dataset ID */ + hid_t tid; /* 'Type ID */ + hid_t aid; /* Attribute ID */ + hid_t plid; /* Property List ID */ + hid_t pcid; /* Property Class ID */ + hid_t gid; /* Group ID */ + hid_t ecid; /* Error Class ID */ + hid_t emid; /* Error Message ID */ + hid_t esid; /* Error Stack ID */ + int rc; /* Reference count */ + herr_t ret; /* Generic return value */ + +/* Check H5I operations on files */ + + /* Create the file */ + fid = H5Fcreate(MISC19_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Check the reference count */ + rc = H5Iget_ref(fid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(fid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the file normally */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Check the reference count */ + rc = H5Iget_ref(fid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the file by decrementing the reference count */ + rc = H5Idec_ref(fid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the file again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Fclose(fid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Fclose"); + +/* Check H5I operations on property lists */ + + /* Create the property list */ + plid = H5Pcreate(H5P_DATASET_CREATE); + CHECK(plid, FAIL, "H5Pcreate"); + + /* Check the reference count */ + rc = H5Iget_ref(plid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(plid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the property list normally */ + ret = H5Pclose(plid); + CHECK(ret, FAIL, "H5Pclose"); + + /* Check the reference count */ + rc = H5Iget_ref(plid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the property list by decrementing the reference count */ + rc = H5Idec_ref(plid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the property list again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Pclose(plid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pclose"); + +/* Check H5I operations on property classes */ + + /* Create a property class */ + pcid = H5Pcreate_class(H5P_DATASET_CREATE,"foo",NULL,NULL,NULL,NULL,NULL,NULL); + CHECK(pcid, FAIL, "H5Pcreate_class"); + + /* Check the reference count */ + rc = H5Iget_ref(pcid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(pcid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the property class normally */ + ret = H5Pclose_class(pcid); + CHECK(ret, FAIL, "H5Pclose_class"); + + /* Check the reference count */ + rc = H5Iget_ref(pcid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the property class by decrementing the reference count */ + rc = H5Idec_ref(pcid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the property class again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Pclose_class(pcid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pclose_class"); + +/* Check H5I operations on datatypes */ + + /* Create a datatype */ + tid = H5Tcreate(H5T_OPAQUE,16); + CHECK(tid, FAIL, "H5Tcreate"); + + /* Check the reference count */ + rc = H5Iget_ref(tid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(tid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the datatype normally */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Check the reference count */ + rc = H5Iget_ref(tid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the datatype by decrementing the reference count */ + rc = H5Idec_ref(tid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the datatype again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Tclose(tid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Tclose"); + +/* Check H5I operations on dataspaces */ + + /* Create a dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Check the reference count */ + rc = H5Iget_ref(sid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(sid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the dataspace normally */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Check the reference count */ + rc = H5Iget_ref(sid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the dataspace by decrementing the reference count */ + rc = H5Idec_ref(sid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the dataspace again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Sclose(sid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sclose"); + +/* Check H5I operations on datasets */ + + /* Create a file */ + fid = H5Fcreate(MISC19_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create a dataset */ + did = H5Dcreate(fid,MISC19_DSET_NAME,H5T_NATIVE_INT,sid,H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate"); + + /* Check the reference count */ + rc = H5Iget_ref(did); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(did); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the dataset normally */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Check the reference count */ + rc = H5Iget_ref(did); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the dataset by decrementing the reference count */ + rc = H5Idec_ref(did); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the dataset again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Dclose(did); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + +/* Check H5I operations on attributes */ + + /* Create a file */ + fid = H5Fcreate(MISC19_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Open the root group */ + gid = H5Gopen(fid,"/"); + CHECK(gid, FAIL, "H5Gopen"); + + /* Create a dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create an attribute */ + aid = H5Acreate(gid,MISC19_ATTR_NAME,H5T_NATIVE_INT,sid,H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate"); + + /* Check the reference count */ + rc = H5Iget_ref(aid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(aid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the dataset normally */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Check the reference count */ + rc = H5Iget_ref(aid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the attribute by decrementing the reference count */ + rc = H5Idec_ref(aid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the attribute again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Aclose(aid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Aclose"); + + /* Close the root group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + +/* Check H5I operations on groups */ + + /* Create a file */ + fid = H5Fcreate(MISC19_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group */ + gid = H5Gcreate(fid,MISC19_GROUP_NAME,0); + CHECK(gid, FAIL, "H5Gcreate"); + + /* Check the reference count */ + rc = H5Iget_ref(gid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(gid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the group normally */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Check the reference count */ + rc = H5Iget_ref(gid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the group by decrementing the reference count */ + rc = H5Idec_ref(gid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the group again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Gclose(gid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Gclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + +/* Check H5I operations on error classes */ + + /* Create an error class */ + ecid = H5Eregister_class("foo","bar","baz"); + CHECK(ecid, FAIL, "H5Eregister_class"); + + /* Check the reference count */ + rc = H5Iget_ref(ecid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(ecid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the error class normally */ + ret = H5Eunregister_class(ecid); + CHECK(ret, FAIL, "H5Eunregister_class"); + + /* Check the reference count */ + rc = H5Iget_ref(ecid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the error class by decrementing the reference count */ + rc = H5Idec_ref(ecid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the error class again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Eunregister_class(ecid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Eunregister_class"); + +/* Check H5I operations on error messages */ + + /* Create an error class */ + ecid = H5Eregister_class("foo","bar","baz"); + CHECK(ecid, FAIL, "H5Eregister_class"); + + /* Create an error message */ + emid = H5Ecreate_msg(ecid,H5E_MAJOR,"mumble"); + CHECK(emid, FAIL, "H5Ecreate_msg"); + + /* Check the reference count */ + rc = H5Iget_ref(emid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(emid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the error message normally */ + ret = H5Eclose_msg(emid); + CHECK(ret, FAIL, "H5Eclose_msg"); + + /* Check the reference count */ + rc = H5Iget_ref(emid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the error message by decrementing the reference count */ + rc = H5Idec_ref(emid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the error message again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Eclose_msg(emid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Eclose_msg"); + + /* Close the error class */ + ret = H5Eunregister_class(ecid); + CHECK(ret, FAIL, "H5Eunregister_class"); + +/* Check H5I operations on error stacks */ + + /* Create an error stack */ + esid = H5Eget_current_stack(); + CHECK(esid, FAIL, "H5Eget_current_stack"); + + /* Check the reference count */ + rc = H5Iget_ref(esid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Inc the reference count */ + rc = H5Iinc_ref(esid); + VERIFY(rc, 2, "H5Iinc_ref"); + + /* Close the error stack normally */ + ret = H5Eclose_stack(esid); + CHECK(ret, FAIL, "H5Eclose_stack"); + + /* Check the reference count */ + rc = H5Iget_ref(esid); + VERIFY(rc, 1, "H5Iget_ref"); + + /* Close the error stack by decrementing the reference count */ + rc = H5Idec_ref(esid); + VERIFY(rc, 0, "H5Idec_ref"); + + /* Try closing the error stack again (should fail) */ + H5E_BEGIN_TRY { + ret = H5Eclose_stack(esid); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Eclose_stack"); + +} /* end test_misc19() */ + +/**************************************************************** +** ** test_misc(): Main misc. test routine. ** ****************************************************************/ @@ -2934,6 +3369,7 @@ test_misc(void) test_misc16(); /* Test array of fixed-length string */ test_misc17(); /* Test array of ASCII character */ test_misc18(); /* Test new object header information in H5G_stat_t struct */ + test_misc19(); /* Test incrementing & decrementing ref count on IDs */ } /* test_misc() */ @@ -2976,4 +3412,5 @@ cleanup_misc(void) HDremove(MISC16_FILE); HDremove(MISC17_FILE); HDremove(MISC18_FILE); + HDremove(MISC19_FILE); } |