diff options
-rw-r--r-- | src/H5A.c | 4 | ||||
-rw-r--r-- | src/H5D.c | 4 | ||||
-rw-r--r-- | src/H5T.c | 36 | ||||
-rw-r--r-- | src/H5Tprivate.h | 1 | ||||
-rw-r--r-- | test/dtypes.c | 157 | ||||
-rw-r--r-- | test/mount.c | 3 |
6 files changed, 205 insertions, 0 deletions
@@ -1268,6 +1268,10 @@ H5Aget_type(hid_t attr_id) if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") + /* Patch the datatype's "top level" file pointer */ + if(H5T_patch_file(attr->shared->dt, attr->oloc.file) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") + /* * Copy the attribute's datatype. If the type is a named type then * reopen the type before returning it to the user. Make the type @@ -523,6 +523,10 @@ H5Dget_type(hid_t dset_id) if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + /* Patch the datatype's "top level" file pointer */ + if(H5T_patch_file(dset->shared->type, dset->oloc.file) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") + /* Copy the dataset's datatype */ if(NULL == (dt = H5T_copy(dset->shared->type, H5T_COPY_REOPEN))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype") @@ -5301,3 +5301,39 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_set_latest_version() */ + +/*------------------------------------------------------------------------- + * Function: H5T_patch_file + * + * Purpose: Patch the top-level file pointers contained in dt to point + * to f, if dt is a committed type. This is possible because + * the top-level file pointer can be closed out from under + * dt while dt is contained in the shared file's cache. + * + * Return: SUCCEED + * + * Programmer: Neil Fortner + * Thursday, July 14, 2011 + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_patch_file(H5T_t *dt, H5F_t *f) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5T_patch_file, FAIL) + + /* Sanity check */ + HDassert(dt); + HDassert(f); + + if(H5T_STATE_OPEN == dt->shared->state || H5T_STATE_NAMED == dt->shared->state) { + dt->oloc.file = f; + dt->sh_loc.file = f; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_patch_file() */ + diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index c70eea0..0c96896 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -135,6 +135,7 @@ H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); H5_DLL uint32_t H5T_hash(H5F_t * file, const H5T_t *dt); H5_DLL herr_t H5T_set_latest_version(H5T_t *dt); +H5_DLL herr_t H5T_patch_file(H5T_t *dt, H5F_t *f); H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt); /* Reference specific functions */ diff --git a/test/dtypes.c b/test/dtypes.c index 5ca7f9f..f01e94e 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -6811,6 +6811,162 @@ error: /*------------------------------------------------------------------------- + * Function: test_delete_obj_named_fileid + * + * Purpose: Tests that objects that use named datatypes through + * different file IDs get the correct file IDs + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Thursday, July 28, 2011 + * + *------------------------------------------------------------------------- + */ +static int +test_delete_obj_named_fileid(hid_t fapl) +{ + hid_t filea1 = -1, filea2 = -1, fileb = -1; /* File IDs */ + hid_t dset_fid = -1; /* File ID from dataset */ + hid_t type_fid = -1; /* File ID from datatype */ + hid_t attr_fid = -1; /* File ID from attribute */ + hid_t type = -1; /* Datatype ID */ + hid_t attr = -1; /* Attribute ID */ + hid_t dset = -1; /* Dataset ID */ + hid_t fapl2 = -1; /* File access property list ID */ + hbool_t new_format; /* Whether to use old or new format */ + char filename[1024], filename2[1024]; + + TESTING("deleting objects that use named datatypes"); + + /* Set up filenames & FAPLs */ + if((fapl2 = H5Pcopy(fapl)) < 0) FAIL_STACK_ERROR + h5_fixname(FILENAME[8], fapl, filename, sizeof filename); + h5_fixname(FILENAME[9], fapl2, filename2, sizeof filename2); + + /* Loop over old & new format files */ + for(new_format = FALSE; new_format <= TRUE; new_format++) { + /* Create test file, with attribute that uses committed datatype */ + create_del_obj_named_test_file(filename, fapl, new_format); + +/* Test getting file ID for dataset opened through different file ID */ + if((filea1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + + if((filea2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + + if((dset = H5Dopen2(filea1, DEL_OBJ_NAMED_DATASET, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Verify file ID from dataset matches correct file */ + dset_fid = H5Iget_file_id(dset); + if(dset_fid != filea1) TEST_ERROR + H5Fclose(dset_fid); + + /* Verify file ID from datatype (from dataset) matches correct file */ + type = H5Dget_type(dset); + type_fid = H5Iget_file_id(type); + if(type_fid != filea1) TEST_ERROR + H5Fclose(type_fid); + H5Tclose(type); + + if(H5Dclose(dset) < 0) FAIL_STACK_ERROR + + if(H5Fclose(filea1) < 0) FAIL_STACK_ERROR + + if((fileb = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl2)) < 0) FAIL_STACK_ERROR + + if((filea1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + + if((dset = H5Dopen2(filea1, DEL_OBJ_NAMED_DATASET, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Verify file ID from dataset matches correct file */ + dset_fid = H5Iget_file_id(dset); + if(dset_fid != filea1) TEST_ERROR + H5Fclose(dset_fid); + + /* Verify file ID from datatype (from dataset) matches correct file */ + type = H5Dget_type(dset); + type_fid = H5Iget_file_id(type); + if(type_fid != filea1) TEST_ERROR + H5Fclose(type_fid); + H5Tclose(type); + + if(H5Dclose(dset) < 0) FAIL_STACK_ERROR + + if(H5Fclose(filea1) < 0) FAIL_STACK_ERROR + if(H5Fclose(filea2) < 0) FAIL_STACK_ERROR + if(H5Fclose(fileb) < 0) FAIL_STACK_ERROR + + + /* Create test file, with attribute that uses committed datatype */ + create_del_obj_named_test_file(filename, fapl, new_format); + +/* Test getting file ID for attribute opened through different file ID */ + if((filea1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + if((filea2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + + if((attr = H5Aopen_by_name(filea1, DEL_OBJ_NAMED_DATASET, DEL_OBJ_NAMED_ATTRIBUTE, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Verify file ID from dataset matches correct file */ + attr_fid = H5Iget_file_id(attr); + if(attr_fid != filea1) TEST_ERROR + H5Fclose(attr_fid); + + /* Verify file ID from datatype (from dataset) matches correct file */ + type = H5Aget_type(attr); + type_fid = H5Iget_file_id(type); + if(type_fid != filea1) TEST_ERROR + H5Fclose(type_fid); + H5Tclose(type); + + if(H5Aclose(attr) < 0) FAIL_STACK_ERROR + + if(H5Fclose(filea1) < 0) FAIL_STACK_ERROR + + if((fileb = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl2)) < 0) FAIL_STACK_ERROR + + if((filea1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR + + if((attr = H5Aopen_by_name(filea1, DEL_OBJ_NAMED_DATASET, DEL_OBJ_NAMED_ATTRIBUTE, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Verify file ID from dataset matches correct file */ + attr_fid = H5Iget_file_id(attr); + if(attr_fid != filea1) TEST_ERROR + H5Fclose(attr_fid); + + /* Verify file ID from datatype (from dataset) matches correct file */ + type = H5Aget_type(attr); + type_fid = H5Iget_file_id(type); + if(type_fid != filea1) TEST_ERROR + H5Fclose(type_fid); + H5Tclose(type); + + if(H5Aclose(attr) < 0) FAIL_STACK_ERROR + + if(H5Fclose(filea1) < 0) FAIL_STACK_ERROR + if(H5Fclose(filea2) < 0) FAIL_STACK_ERROR + if(H5Fclose(fileb) < 0) FAIL_STACK_ERROR + } /* end for */ + + if(H5Pclose(fapl2) < 0) FAIL_STACK_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Tclose(attr); + H5Dclose(dset); + H5Pclose(fapl2); + H5Fclose(filea1); + H5Fclose(filea2); + H5Fclose(fileb); + } H5E_END_TRY; + return 1; +} /* end test_delete_obj_named_fileid() */ + + +/*------------------------------------------------------------------------- * Function: test_deprec * * Purpose: Tests deprecated API routines for datatypes. @@ -7004,6 +7160,7 @@ main(void) nerrors += test_int_float_except(); nerrors += test_named_indirect_reopen(fapl); nerrors += test_delete_obj_named(fapl); + nerrors += test_delete_obj_named_fileid(fapl); nerrors += test_set_order_compound(fapl); nerrors += test_str_create(); #ifndef H5_NO_DEPRECATED_SYMBOLS diff --git a/test/mount.c b/test/mount.c index bcd9eb3..b7180fa 100644 --- a/test/mount.c +++ b/test/mount.c @@ -1042,6 +1042,9 @@ test_interlink(hid_t fapl) /* Close IDs */ if(H5Sclose(space) < 0) FAIL_STACK_ERROR if(H5Tclose(type) < 0) FAIL_STACK_ERROR +#else /* NOT_NOW */ + SKIPPED(); + HDputs(" Test skipped due file pointer sharing issue (Jira 7638)."); #endif /* NOT_NOW */ /* Shut down */ |