diff options
-rw-r--r-- | release_docs/RELEASE.txt | 2 | ||||
-rw-r--r-- | src/H5I.c | 47 | ||||
-rw-r--r-- | src/H5Ipublic.h | 1 | ||||
-rw-r--r-- | 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) @@ -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 } @@ -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"); } |