From e78909e53965b8365c4fb87b84f5f7852da9d36f Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Wed, 5 Nov 2008 14:07:40 -0500 Subject: [svn-r16036] Purpose: add H5Iis_valid function Description: H5Iis_valid function added. This function checks if the id is valid (i.e. it is currently registered and visible to the application), and returns TRUE if it is valid, or FALSE otherwise. It should never return an error. Tested: kagiso, linew, smirom (h5committest) --- release_docs/RELEASE.txt | 2 ++ src/H5I.c | 47 ++++++++++++++++++++++++++ src/H5Ipublic.h | 1 + test/tid.c | 86 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 132 insertions(+), 4 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8f2c381..0f20d6f 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -51,6 +51,8 @@ New Features Library: -------- + - Added H5Iis_valid() function to check if an id is valid without producing + an error message. (NAF - 2008/11/5) - Added two new public routines: H5Pget_elink_fapl() and H5Pset_elink_fapl(). (see bug #1247) (VC - 2008/10/13) - Improved free space tracking in file to be faster. (QAK - 2008/10/06) diff --git a/src/H5I.c b/src/H5I.c index 40fec88..f29624b 100644 --- a/src/H5I.c +++ b/src/H5I.c @@ -1844,6 +1844,53 @@ done: /*------------------------------------------------------------------------- + * Function: H5Iis_valid + * + * Purpose: Check if the given id is valid. And id is valid if it is in + * use and has an application reference count of at least 1. + * + * Return: Success: TRUE if the id is valid, FALSE otherwise. + * + * Failure: Negative (never fails currently) + * + * Programmer: Neil Fortner + * Friday, October 31, 2008 (boo) + * + *------------------------------------------------------------------------- + */ +htri_t +H5Iis_valid(hid_t id) +{ + H5I_id_type_t *type_ptr; /* ptr to ID's type */ + H5I_id_info_t *id_ptr; /* ptr to the ID */ + H5I_type_t type; /* ID's type */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_API(H5Iis_valid, FAIL) + + type = H5I_TYPE(id); + /* Check for conditions that would cause H5I_find_id to throw an assertion */ + if (type <= H5I_BADID || type >= H5I_next_type) + HGOTO_DONE(FALSE); + + type_ptr = H5I_id_type_list_g[type]; + if (!type_ptr || type_ptr->count <= 0) + ret_value = FALSE; + + /* Find the ID */ + else if (NULL == (id_ptr = H5I_find_id(id))) + ret_value = FALSE; + + /* Check if the found id is an internal id */ + else if (!id_ptr->app_count) + ret_value = FALSE; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Iis_valid() */ + + +/*------------------------------------------------------------------------- * Function: H5Isearch * * Purpose: Apply function FUNC to each member of type TYPE and return a diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index 108f040..608bc9c 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -95,6 +95,7 @@ H5_DLL int H5Iget_type_ref(H5I_type_t type); H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key); H5_DLL herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members); H5_DLL htri_t H5Itype_exists(H5I_type_t type); +H5_DLL htri_t H5Iis_valid(hid_t id); #ifdef __cplusplus } diff --git a/test/tid.c b/test/tid.c index 8eb4e24..f3c00fc 100644 --- a/test/tid.c +++ b/test/tid.c @@ -112,7 +112,7 @@ static int basic_id_test(void) H5E_END_TRY VERIFY(testSize, -1, "H5Iget_name"); - if(testSize != 0) + if(testSize != -1) goto out; /* Make sure H5Iremove_verify catches objects of the wrong type */ @@ -332,6 +332,83 @@ out: } +/* Test the H5Iis_valid function */ +static int test_is_valid(void) +{ + hid_t dtype; /* datatype id */ + int nmembs1; /* number of type memnbers */ + int nmembs2; + htri_t tri_ret; /* htri_t return value */ + herr_t 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 valid */ + tri_ret = H5Iis_valid(dtype); + VERIFY(tri_ret, TRUE, "H5Iis_valid"); + if (tri_ret != TRUE) + goto out; + + /* 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_ref(dtype, TRUE); + 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, FALSE); + 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; + + /* Check that an id of -1 is invalid */ + tri_ret = H5Iis_valid(-1); + VERIFY(tri_ret, FALSE, "H5Iis_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 boundary cases with lots of types */ /* Type IDs range from H5I_NTYPES to MAX_NUM_TYPES. The system will assign */ @@ -418,8 +495,9 @@ out: void test_ids(void) { - basic_id_test(); - id_predefined_test(); - test_id_type_list(); + 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_id_type_list() < 0) TestErrPrintf("ID type list test failed\n"); } -- cgit v0.12