summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-10-07 03:05:53 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-10-07 03:05:53 (GMT)
commit7f1379704fd291c2f1a16c0087690f0b2ce90e4c (patch)
tree57dfe51c994606b738c343603fc54dc1798065b3
parentccffe74623a2ffe256800649c5e2f113ce82b36d (diff)
downloadhdf5-7f1379704fd291c2f1a16c0087690f0b2ce90e4c.zip
hdf5-7f1379704fd291c2f1a16c0087690f0b2ce90e4c.tar.gz
hdf5-7f1379704fd291c2f1a16c0087690f0b2ce90e4c.tar.bz2
[svn-r17604] Description:
Correctly invoke generic property list class callbacks all the way to the root of the class hierarchy. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.6.1 (amazon) in debug mode Mac OS X/32 10.6.1 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
-rw-r--r--src/H5Pdcpl.c10
-rw-r--r--src/H5Pint.c67
-rw-r--r--test/tgenprop.c143
3 files changed, 180 insertions, 40 deletions
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index 9f8650c..2f7e280 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -1723,7 +1723,7 @@ H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags
/* Get filter information */
if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1791,7 +1791,7 @@ H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/
/* Get filter info */
if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info")
done:
FUNC_LEAVE_API(ret_value)
@@ -1873,13 +1873,13 @@ H5Premove_filter(hid_t plist_id, H5Z_filter_t filter)
/* Get pipeline info */
if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
/* Check if there are any filters */
if (pline.filter) {
/* Delete filter */
if(H5Z_delete(&pline, filter) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't delete filter")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't delete filter")
/* Put the I/O pipeline information back into the property list */
if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
@@ -2959,7 +2959,7 @@ H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/
/* Get filter info */
if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info")
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 364cab2..4da7f09 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -782,14 +782,22 @@ H5P_copy_plist(H5P_genplist_t *old_plist, hbool_t app_ref)
/* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
new_plist->plist_id=new_plist_id;
- /* Call the class callback (if it exists) now that we have the property list ID */
- if(new_plist->pclass->copy_func!=NULL) {
- if((new_plist->pclass->copy_func)(new_plist_id,old_plist->plist_id,old_plist->pclass->copy_data) < 0) {
- /* Delete ID, ignore return value */
- H5I_remove(new_plist_id);
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
+ /* Call the class callback (if it exists) now that we have the property list ID
+ * (up through chain of parent classes also)
+ */
+ tclass = new_plist->pclass;
+ while(NULL != tclass) {
+ if(NULL != tclass->copy_func) {
+ if((tclass->copy_func)(new_plist_id, old_plist->plist_id, old_plist->pclass->copy_data) < 0) {
+ /* Delete ID, ignore return value */
+ H5I_remove(new_plist_id);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
+ } /* end if */
} /* end if */
- } /* end if */
+
+ /* Go up to parent class */
+ tclass = tclass->parent;
+ } /* end while */
/* Set the class initialization flag */
new_plist->class_init=1;
@@ -1658,8 +1666,9 @@ done:
hid_t
H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref)
{
- H5P_genplist_t *plist=NULL; /* Property list created */
- hid_t plist_id=FAIL; /* Property list ID */
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+ H5P_genplist_t *plist = NULL; /* Property list created */
+ hid_t plist_id = FAIL; /* Property list ID */
hid_t ret_value; /* return value */
FUNC_ENTER_NOAPI(H5P_create_id, FAIL);
@@ -1677,14 +1686,22 @@ H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref)
/* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
plist->plist_id=plist_id;
- /* Call the class callback (if it exists) now that we have the property list ID */
- if(plist->pclass->create_func!=NULL) {
- if((plist->pclass->create_func)(plist_id,plist->pclass->create_data) < 0) {
- /* Delete ID, ignore return value */
- H5I_remove(plist_id);
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
+ /* Call the class callback (if it exists) now that we have the property list ID
+ * (up through chain of parent classes also)
+ */
+ tclass = plist->pclass;
+ while(NULL != tclass) {
+ if(NULL != tclass->create_func) {
+ if((tclass->create_func)(plist_id, tclass->create_data) < 0) {
+ /* Delete ID, ignore return value */
+ H5I_remove(plist_id);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
+ } /* end if */
} /* end if */
- } /* end if */
+
+ /* Go up to parent class */
+ tclass = tclass->parent;
+ } /* end while */
/* Set the class initialization flag */
plist->class_init=1;
@@ -4058,10 +4075,20 @@ H5P_close(void *_plist)
assert(plist);
- /* Make call to property list class close callback, if needed */
- if(plist->class_init!=0 && plist->pclass->close_func!=NULL) {
- /* Call user's "close" callback function, ignoring return value */
- (plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data);
+ /* Make call to property list class close callback, if needed
+ * (up through chain of parent classes also)
+ */
+ if(plist->class_init !=0) {
+ tclass = plist->pclass;
+ while(NULL != tclass) {
+ if(NULL != tclass->close_func) {
+ /* Call user's "close" callback function, ignoring return value */
+ (tclass->close_func)(plist->plist_id, tclass->close_data);
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass = tclass->parent;
+ } /* end while */
} /* end if */
/* Create the skip list to hold names of properties already seen
diff --git a/test/tgenprop.c b/test/tgenprop.c
index f87d4ec..1d3d766 100644
--- a/test/tgenprop.c
+++ b/test/tgenprop.c
@@ -367,11 +367,11 @@ test_genprop_class_iter(void)
/****************************************************************
**
-** test_genprop_cls_cb1(): Property List callback for test_genprop_class_callback
+** test_genprop_cls_*_cb1(): Property List callbacks for test_genprop_class_callback
**
****************************************************************/
static herr_t
-test_genprop_cls_cb1(hid_t list_id, void *create_data)
+test_genprop_cls_crt_cb1(hid_t list_id, void *create_data)
{
struct { /* Struct for iterations */
int count;
@@ -385,18 +385,33 @@ test_genprop_cls_cb1(hid_t list_id, void *create_data)
}
static herr_t
-test_genprop_cls_cb2(hid_t new_list_id, hid_t UNUSED old_list_id, void *create_data)
+test_genprop_cls_cpy_cb1(hid_t new_list_id, hid_t UNUSED old_list_id, void *copy_data)
{
struct { /* Struct for iterations */
int count;
hid_t id;
- } *count_struct=create_data;
+ } *count_struct=copy_data;
count_struct->count++;
count_struct->id=new_list_id;
return(SUCCEED);
}
+
+static herr_t
+test_genprop_cls_cls_cb1(hid_t list_id, void *create_data)
+{
+ struct { /* Struct for iterations */
+ int count;
+ hid_t id;
+ } *count_struct=create_data;
+
+ count_struct->count++;
+ count_struct->id=list_id;
+
+ return(SUCCEED);
+}
+
/****************************************************************
**
** test_genprop_class_callback(): Test basic generic property list code.
@@ -407,20 +422,22 @@ static void
test_genprop_class_callback(void)
{
hid_t cid1; /* Generic Property class ID */
+ hid_t cid2; /* Generic Property class ID */
hid_t lid1; /* Generic Property list ID */
hid_t lid2; /* Generic Property list ID */
+ hid_t lid3; /* Generic Property list ID */
size_t nprops; /* Number of properties in class */
struct { /* Struct for callbacks */
int count;
hid_t id;
- } crt_cb_struct, cls_cb_struct;
+ } crt_cb_struct, cpy_cb_struct, cls_cb_struct;
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Basic Generic Property List Class Callback Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,test_genprop_cls_cb1,&crt_cb_struct,NULL, NULL,test_genprop_cls_cb1,&cls_cb_struct);
+ cid1 = H5Pcreate_class(H5P_ROOT, CLASS1_NAME, test_genprop_cls_crt_cb1, &crt_cb_struct, test_genprop_cls_cpy_cb1, &cpy_cb_struct, test_genprop_cls_cls_cb1, &cls_cb_struct);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with no callbacks) */
@@ -435,18 +452,16 @@ test_genprop_class_callback(void)
ret = H5Pregister2(cid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
CHECK_I(ret, "H5Pregister2");
- /* Insert fourth property into class (with no callbacks) */
- ret = H5Pregister2(cid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- CHECK_I(ret, "H5Pregister2");
-
/* Check the number of properties in class */
ret = H5Pget_nprops(cid1,&nprops);
CHECK_I(ret, "H5Pget_nprops");
- VERIFY(nprops, 4, "H5Pget_nprops");
+ VERIFY(nprops, 3, "H5Pget_nprops");
/* Initialize class callback structs */
crt_cb_struct.count=0;
crt_cb_struct.id=(-1);
+ cpy_cb_struct.count=0;
+ cpy_cb_struct.id=(-1);
cls_cb_struct.count=0;
cls_cb_struct.id=(-1);
@@ -461,7 +476,7 @@ test_genprop_class_callback(void)
/* Check the number of properties in list */
ret = H5Pget_nprops(lid1,&nprops);
CHECK_I(ret, "H5Pget_nprops");
- VERIFY(nprops, 4, "H5Pget_nprops");
+ VERIFY(nprops, 3, "H5Pget_nprops");
/* Create another property list from the class */
lid2 = H5Pcreate(cid1);
@@ -474,7 +489,20 @@ test_genprop_class_callback(void)
/* Check the number of properties in list */
ret = H5Pget_nprops(lid2,&nprops);
CHECK_I(ret, "H5Pget_nprops");
- VERIFY(nprops, 4, "H5Pget_nprops");
+ VERIFY(nprops, 3, "H5Pget_nprops");
+
+ /* Create another property list by copying an existing list */
+ lid3 = H5Pcopy(lid1);
+ CHECK_I(lid3, "H5Pcopy");
+
+ /* Verify that the copy callback occurred */
+ VERIFY(cpy_cb_struct.count, 1, "H5Pcopy");
+ VERIFY(cpy_cb_struct.id, lid3, "H5Pcopy");
+
+ /* Check the number of properties in list */
+ ret = H5Pget_nprops(lid3, &nprops);
+ CHECK_I(ret, "H5Pget_nprops");
+ VERIFY(nprops, 3, "H5Pget_nprops");
/* Close first list */
ret = H5Pclose(lid1);
@@ -492,9 +520,75 @@ test_genprop_class_callback(void)
VERIFY(cls_cb_struct.count, 2, "H5Pclose");
VERIFY(cls_cb_struct.id, lid2, "H5Pclose");
- /* Close class */
+ /* Close third list */
+ ret = H5Pclose(lid3);
+ CHECK_I(ret, "H5Pclose");
+
+ /* Verify that the close callback occurred */
+ VERIFY(cls_cb_struct.count, 3, "H5Pclose");
+ VERIFY(cls_cb_struct.id, lid3, "H5Pclose");
+
+ /* Create another new generic class, derived from first class */
+ cid2 = H5Pcreate_class(cid1, CLASS2_NAME, test_genprop_cls_crt_cb1, &crt_cb_struct, test_genprop_cls_cpy_cb1, &cpy_cb_struct, test_genprop_cls_cls_cb1, &cls_cb_struct);
+ CHECK_I(cid2, "H5Pcreate_class");
+
+ /* Insert fourth property into class (with no callbacks) */
+ ret = H5Pregister2(cid2, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ CHECK_I(ret, "H5Pregister2");
+
+ /* Check the number of properties in class */
+ /* (only reports the number of properties in 2nd class) */
+ ret = H5Pget_nprops(cid2, &nprops);
+ CHECK_I(ret, "H5Pget_nprops");
+ VERIFY(nprops, 1, "H5Pget_nprops");
+
+ /* Create a property list from the 2nd class */
+ lid1 = H5Pcreate(cid2);
+ CHECK_I(lid1, "H5Pcreate");
+
+ /* Verify that both of the creation callbacks occurred */
+ VERIFY(crt_cb_struct.count, 4, "H5Pcreate");
+ VERIFY(crt_cb_struct.id, lid1, "H5Pcreate");
+
+ /* Check the number of properties in list */
+ ret = H5Pget_nprops(lid1, &nprops);
+ CHECK_I(ret, "H5Pget_nprops");
+ VERIFY(nprops, 4, "H5Pget_nprops");
+
+ /* Create another property list by copying existing list */
+ lid2 = H5Pcopy(lid1);
+ CHECK_I(lid2, "H5Pcopy");
+
+ /* Verify that both of the copy callbacks occurred */
+ VERIFY(cpy_cb_struct.count, 3, "H5Pcopy");
+ VERIFY(cpy_cb_struct.id, lid2, "H5Pcopy");
+
+ /* Check the number of properties in list */
+ ret = H5Pget_nprops(lid2, &nprops);
+ CHECK_I(ret, "H5Pget_nprops");
+ VERIFY(nprops, 4, "H5Pget_nprops");
+
+ /* Close first list */
+ ret = H5Pclose(lid1);
+ CHECK_I(ret, "H5Pclose");
+
+ /* Verify that both of the close callbacks occurred */
+ VERIFY(cls_cb_struct.count, 5, "H5Pclose");
+ VERIFY(cls_cb_struct.id, lid1, "H5Pclose");
+
+ /* Close second list */
+ ret = H5Pclose(lid2);
+ CHECK_I(ret, "H5Pclose");
+
+ /* Verify that both of the close callbacks occurred */
+ VERIFY(cls_cb_struct.count, 7, "H5Pclose");
+ VERIFY(cls_cb_struct.id, lid2, "H5Pclose");
+
+ /* Close classes */
ret = H5Pclose_class(cid1);
CHECK_I(ret, "H5Pclose_class");
+ ret = H5Pclose_class(cid2);
+ CHECK_I(ret, "H5Pclose_class");
} /* end test_genprop_class_callback() */
/****************************************************************
@@ -895,6 +989,25 @@ prop_cb_info prop3_cb_info; /* Callback statistics for property #3 */
/****************************************************************
**
+** test_genprop_cls_cpy_cb2(): Property Class callback for test_genprop_list_callback
+**
+****************************************************************/
+static herr_t
+test_genprop_cls_cpy_cb2(hid_t new_list_id, hid_t UNUSED old_list_id, void *create_data)
+{
+ struct { /* Struct for iterations */
+ int count;
+ hid_t id;
+ } *count_struct=create_data;
+
+ count_struct->count++;
+ count_struct->id=new_list_id;
+
+ return(SUCCEED);
+}
+
+/****************************************************************
+**
** test_genprop_prop_crt_cb1(): Property creation callback for test_genprop_list_callback
**
****************************************************************/
@@ -1063,7 +1176,7 @@ test_genprop_list_callback(void)
MESSAGE(5, ("Testing Basic Generic Property List Property Callback Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL,test_genprop_cls_cb2,&cop_cb_struct,NULL, NULL);
+ cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL,test_genprop_cls_cpy_cb2,&cop_cb_struct,NULL, NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with callbacks) */