From 5a6c75cc585c8e16277e235aa4240ff5b9ff8763 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 12 Feb 2009 14:09:10 -0500 Subject: [svn-r16478] Purpose: Fix problem with opening an attribute multiple times through multiple file handles. Description: An attribute's "oloc" field which specifies the file it resides in was located in the attribute's "shared" structure. So when an attribute was opened multiple times all of the handles for that attribute pointed to the same file id, even if different file id's were used to open the different handles for the attribute. The "oloc" has been moved to the top level H5A_t struct. Tested: jam, smirom (h5committest) --- release_docs/RELEASE.txt | 2 + src/H5A.c | 28 ++++---- src/H5Aint.c | 2 +- src/H5Apkg.h | 2 +- src/H5Atest.c | 2 +- src/H5Oattr.c | 2 +- src/H5Oattribute.c | 4 +- test/tattr.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 186 insertions(+), 21 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 7c07930..87e6497 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -114,6 +114,8 @@ Bug Fixes since HDF5-1.8.2 Library ------- + - Fixed an assertion failure caused by opening an attribute multiple times + through multiple file handles. NAF - 2009/02/12 - Fixed a problem that could prevent the user from adding attributes (or any object header message) in some circumstances. NAF - 2009/02/12 - Fixed a bug that could cause problems when an attribute was added to a diff --git a/src/H5A.c b/src/H5A.c index 0af4aaf..325f7be 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -440,7 +440,7 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, attr->shared->initialized = TRUE; /*for now, set to false later*/ /* Copy the object header information */ - if(H5O_loc_copy(&(attr->shared->oloc), loc->oloc, H5_COPY_DEEP) < 0) + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") /* Deep copy of the group hierarchy path */ @@ -450,9 +450,9 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, /* Check if any of the pieces should be (or are already) shared in the * SOHM table */ - if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0) + if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed") - if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0) + if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed") /* Check whether datatype is committed & increment ref count @@ -469,8 +469,8 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, * datatype and dataspace messages themselves, or the size of the "shared" * messages if either or both of them are shared. */ - attr->shared->dt_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt); - attr->shared->ds_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds); + attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt); + attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds); /* Get # of elements for attribute's dataspace */ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) @@ -482,16 +482,16 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt); /* Hold the symbol table entry (and file) open */ - if(H5O_open(&(attr->shared->oloc)) < 0) + if(H5O_open(&(attr->oloc)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") attr->obj_opened = TRUE; /* Set the version to encode the attribute with */ - if(H5A_set_version(attr->shared->oloc.file, attr) < 0) + if(H5A_set_version(attr->oloc.file, attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version") /* Insert the attribute into the object header */ - if(H5O_attr_create(&(attr->shared->oloc), dxpl_id, attr) < 0) + if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header") /* Register the new attribute and get an ID for it */ @@ -737,7 +737,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) #if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG) /* Clear object location */ - if(H5O_loc_reset(&(attr->shared->oloc)) < 0) + if(H5O_loc_reset(&(attr->oloc)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location") #endif /* H5_USING_MEMCHECKER */ @@ -746,7 +746,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") /* Deep copy of the symbol table entry */ - if(H5O_loc_copy(&(attr->shared->oloc), loc->oloc, H5_COPY_DEEP) < 0) + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") /* Deep copy of the group hier. path */ @@ -754,7 +754,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry") /* Hold the symbol table entry (and file) open */ - if(H5O_open(&(attr->shared->oloc)) < 0) + if(H5O_open(&(attr->oloc)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") attr->obj_opened = TRUE; @@ -1032,7 +1032,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id) } /* end else */ /* Modify the attribute in the object header */ - if(H5O_attr_write(&(attr->shared->oloc), dxpl_id, attr) < 0) + if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute") } /* end if */ @@ -2432,7 +2432,7 @@ H5A_close(H5A_t *attr) HDassert(attr->shared); /* Close the object's symbol-table entry */ - if(attr->obj_opened && (H5O_close(&(attr->shared->oloc)) < 0)) + if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0)) HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info") /* Reference count can be 0. It only happens when H5A_create fails. */ @@ -2486,7 +2486,7 @@ H5A_oloc(H5A_t *attr) HDassert(attr); /* Set return value */ - ret_value = &(attr->shared->oloc); + ret_value = &(attr->oloc); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Aint.c b/src/H5Aint.c index 1b69ea3..a0d151f 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -830,7 +830,7 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure") /* Don't have an opened group location for copy */ - H5O_loc_reset(&(attr_dst->shared->oloc)); + H5O_loc_reset(&(attr_dst->oloc)); H5G_name_reset(&(attr_dst->path)); attr_dst->obj_opened = FALSE; diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 9027864..afe82b8 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -76,7 +76,6 @@ typedef struct H5A_shared_t { unsigned version; /* Version to encode attribute with */ hbool_t initialized;/* Indicate whether the attribute has been modified */ - H5O_loc_t oloc; /* Object location for object attribute is on */ char *name; /* Attribute's name */ H5T_cset_t encoding; /* Character encoding of attribute name */ @@ -96,6 +95,7 @@ typedef struct H5A_shared_t { /* Define the main attribute structure */ struct H5A_t { H5O_shared_t sh_loc; /* Shared message info (must be first) */ + H5O_loc_t oloc; /* Object location for object attribute is on */ hbool_t obj_opened; /* Object header entry opened? */ H5G_name_t path; /* Group hierarchy path */ H5A_shared_t *shared; /* Shared attribute information */ diff --git a/src/H5Atest.c b/src/H5Atest.c index de03a25..df88472 100644 --- a/src/H5Atest.c +++ b/src/H5Atest.c @@ -139,7 +139,7 @@ H5A_get_shared_rc_test(hid_t attr_id, hsize_t *ref_count) HDassert(H5O_msg_is_shared(H5O_ATTR_ID, attr)); /* Retrieve ref count for shared or shareable attribute */ - if(H5SM_get_refcount(attr->shared->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID, + if(H5SM_get_refcount(attr->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID, &attr->sh_loc, ref_count) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") diff --git a/src/H5Oattr.c b/src/H5Oattr.c index b375791..27b9d5e 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -812,7 +812,7 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in mesg->obj_opened); HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Object:", - mesg->shared->oloc.addr); + mesg->oloc.addr); /* Check for attribute creation order index on the attribute */ if(mesg->shared->crt_idx != H5O_MAX_CRT_ORDER_IDX) diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 0aec591..1153c7e 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -700,14 +700,14 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "not an attribute") /* Get file serial number for attribute */ - if(H5F_get_fileno((*attr)->shared->oloc.file, &attr_fnum) < 0) + if(H5F_get_fileno((*attr)->oloc.file, &attr_fnum) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number") /* Verify whether it's the right object. The attribute name, object address * to which the attribute is attached, and file serial number should all * match. */ if(!strcmp(name_to_open, (*attr)->shared->name) && - loc->addr == (*attr)->shared->oloc.addr && + loc->addr == (*attr)->oloc.addr && loc_fnum == attr_fnum) { ret_value = TRUE; break; diff --git a/test/tattr.c b/test/tattr.c index 2ed2b64..ca4b7a2 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -135,6 +135,10 @@ float attr_data5=(float)-5.123; /* Test data for 5th attribute */ #define BUG2_NATTR 100 #define BUG2_NATTR2 16 +#define BUG3_DSET_NAME "dset" +#define BUG3_DT_NAME "dt" +#define BUG3_ATTR_NAME "attr" + /* Attribute iteration struct */ typedef struct { H5_iter_order_t order; /* Direction of iteration */ @@ -9292,7 +9296,7 @@ test_attr_shared_unlink(hid_t fcpl, hid_t fapl) attr = H5Acreate2(dataset, attrname, attr_tid, big_sid, H5P_DEFAULT, H5P_DEFAULT); CHECK(attr, FAIL, "H5Acreate2"); - /* Check that attribute is shared */ + /* ChecFk that attribute is shared */ is_shared = H5A_is_shared_test(attr); VERIFY(is_shared, TRUE, "H5A_is_shared_test"); @@ -9988,6 +9992,163 @@ test_attr_bug4(hid_t fcpl, hid_t fapl) /**************************************************************** ** +** test_attr_bug5(): Test basic H5A (attribute) code. +** Tests opening an attribute multiple times through +** objects opened through different file handles. +** +****************************************************************/ +static void +test_attr_bug5(hid_t fcpl, hid_t fapl) +{ + hid_t fid1, fid2; /* File IDs */ + hid_t gid1, gid2; /* Group IDs */ + hid_t did1, did2; /* Dataset IDs */ + hid_t tid1, tid2; /* Datatype IDs */ + hid_t aidg1, aidg2, + aidd1, aidd2, + aidt1, aidt2; /* Attribute IDs */ + hid_t sid; /* Dataspace ID */ + hsize_t dims[1] = {5}; /* Attribute dimensions */ + herr_t ret; /* Generic return status */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Opening an Attribute Through Multiple Files Concurrently\n")); + + /* Create dataspace ID for attributes and datasets */ + sid = H5Screate_simple(1, dims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Create file */ + fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Open root group */ + gid1 = H5Gopen2(fid1, "/", H5P_DEFAULT); + CHECK(gid1, FAIL, "H5Gopen2"); + + /* Create and commit datatype */ + tid1 = H5Tcopy(H5T_STD_I32LE); + CHECK(tid1, FAIL, "H5Tcopy"); + ret = H5Tcommit2(fid1, BUG3_DT_NAME, tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Create dataset */ + did1 = H5Dcreate2(fid1, BUG3_DSET_NAME, tid1, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did1, FAIL, "H5Dcreate2"); + + /* Create attribute on root group */ + aidg1 = H5Acreate2(gid1, BUG3_ATTR_NAME, tid1, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aidg1, FAIL, "H5Acreate2"); + + /* Create attribute on dataset */ + aidd1 = H5Acreate2(did1, BUG3_ATTR_NAME, tid1, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aidd1, FAIL, "H5Acreate2"); + + /* Create attribute on datatype */ + aidt1 = H5Acreate2(tid1, BUG3_ATTR_NAME, tid1, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aidt1, FAIL, "H5Acreate2"); + + /* Close all IDs */ + ret = H5Aclose(aidt1); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidd1); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidg1); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Dclose(did1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Gclose(gid1); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Open file twice */ + fid1 = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl); + CHECK(fid1, FAIL, "H5Fopen"); + fid2 = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl); + CHECK(fid2, FAIL, "H5Fopen"); + + /* Open the root group twice */ + gid1 = H5Gopen2(fid1, "/", H5P_DEFAULT); + CHECK(gid1, FAIL, "H5Gopen2"); + gid2 = H5Gopen2(fid2, "/", H5P_DEFAULT); + CHECK(gid2, FAIL, "H5Gopen2"); + + /* Open the root group attribute twice */ + aidg1 = H5Aopen(gid1, BUG3_ATTR_NAME, H5P_DEFAULT); + CHECK(aidg1, FAIL, "H5Aopen"); + aidg2 = H5Aopen(gid2, BUG3_ATTR_NAME, H5P_DEFAULT); + CHECK(aidg1, FAIL, "H5Aopen"); + + /* Open the dataset twice */ + did1 = H5Dopen2(fid1, BUG3_DSET_NAME, H5P_DEFAULT); + CHECK(did1, FAIL, "H5Dopen2"); + did2 = H5Dopen2(fid2, BUG3_DSET_NAME, H5P_DEFAULT); + CHECK(did2, FAIL, "H5Dopen2"); + + /* Open the dataset attribute twice */ + aidd1 = H5Aopen(did1, BUG3_ATTR_NAME, H5P_DEFAULT); + CHECK(aidd1, FAIL, "H5Aopen"); + aidd2 = H5Aopen(did2, BUG3_ATTR_NAME, H5P_DEFAULT); + CHECK(aidd1, FAIL, "H5Aopen"); + + /* Open the datatype twice */ + tid1 = H5Topen2(fid1, BUG3_DT_NAME, H5P_DEFAULT); + CHECK(tid1, FAIL, "H5Topen2"); + tid2 = H5Topen2(fid2, BUG3_DT_NAME, H5P_DEFAULT); + CHECK(tid2, FAIL, "H5Topen2"); + + /* Open the datatype attribute twice */ + aidt1 = H5Aopen(tid1, BUG3_ATTR_NAME, H5P_DEFAULT); + CHECK(aidt1, FAIL, "H5Aopen"); + aidt2 = H5Aopen(tid2, BUG3_ATTR_NAME, H5P_DEFAULT); + CHECK(aidt2, FAIL, "H5Aopen"); + + /* Close all attributes */ + ret = H5Aclose(aidg1); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidg2); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidd1); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidd2); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidt1); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Aclose(aidt2); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close root groups */ + ret = H5Gclose(gid1); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close datasets */ + ret = H5Dclose(did1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(did2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close datatypes */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Tclose(tid2); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close files */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_bug5() */ + +/**************************************************************** +** ** test_attr(): Main H5A (attribute) testing routine. ** ****************************************************************/ @@ -10130,6 +10291,7 @@ test_attr(void) test_attr_bug2(my_fcpl, my_fapl); /* Test many deleted attributes */ test_attr_bug3(my_fcpl, my_fapl); /* Test "self referential" attributes */ test_attr_bug4(my_fcpl, my_fapl); /* Test attributes on named datatypes */ + test_attr_bug5(my_fcpl, my_fapl); /* Test opening/closing attributes through different file handles */ } /* end for */ } /* end if */ else { @@ -10152,6 +10314,7 @@ test_attr(void) test_attr_bug2(fcpl, my_fapl); /* Test many deleted attributes */ test_attr_bug3(fcpl, my_fapl); /* Test "self referential" attributes */ test_attr_bug4(fcpl, my_fapl); /* Test attributes on named datatypes */ + test_attr_bug5(fcpl, my_fapl); /* Test opening/closing attributes through different file handles */ } /* end else */ } /* end for */ -- cgit v0.12