summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5A.c28
-rw-r--r--src/H5Aint.c2
-rw-r--r--src/H5Apkg.h2
-rw-r--r--src/H5Atest.c2
-rw-r--r--src/H5Oattr.c2
-rw-r--r--src/H5Oattribute.c4
-rw-r--r--test/tattr.c165
8 files changed, 186 insertions, 21 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 519608f..8eda9ea 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -142,6 +142,8 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Fixed an assertion failure caused by opening an attribute multiple times
+ through multiple file handles. (NAF - 2009/02/06)
- 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 a2cc6ec..fac0110 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -829,7 +829,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 ea9a7f5..ae016c8 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 fe55023..4b130e6 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 */
@@ -9288,7 +9292,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");
@@ -9984,6 +9988,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.
**
****************************************************************/
@@ -10126,6 +10287,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 {
@@ -10148,6 +10310,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 */