diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2002-10-14 19:56:13 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2002-10-14 19:56:13 (GMT) |
commit | 754cf917b499d4774e8b0495755741f21e29037e (patch) | |
tree | f852dfe74382c9d0c04e6a513605648113f23778 /src/H5P.c | |
parent | 4629204d864aa936baca552d742e5d1c2bd1f15c (diff) | |
download | hdf5-754cf917b499d4774e8b0495755741f21e29037e.zip hdf5-754cf917b499d4774e8b0495755741f21e29037e.tar.gz hdf5-754cf917b499d4774e8b0495755741f21e29037e.tar.bz2 |
[svn-r5992] Purpose:
Bug fix
Description:
Generic property classes where incorrectly reference counting their
users, in certain cases, causing a memory leak.
Solution:
Cleanup reference counting code & unify in H5P_access_class()
Platforms tested:
FreeBSD 4.6 (sleipnir) w and w/o parallel
Linux 2.2.x (eirene) w/FORTRAN & C++
Solaris 2.7 (arabica) w/FORTRAN
IRIX64 6.5 (modi4) w/FORTRAN & parallel
Diffstat (limited to 'src/H5P.c')
-rw-r--r-- | src/H5P.c | 36 |
1 files changed, 13 insertions, 23 deletions
@@ -402,11 +402,6 @@ H5P_copy_pclass(H5P_genclass_t *pclass) } /* end for */ } /* end if */ - /* Increment parent class's derived class value */ - if(new_pclass->parent!=NULL) - if(H5P_access_class(new_pclass->parent,H5P_MOD_INC_CLS)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count"); - /* Set the return value */ ret_value=new_pclass; @@ -1007,16 +1002,20 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) break; case H5P_MOD_INC_REF: /* Increment the ID reference count*/ + /* Reset the deleted flag if incrementing the reference count */ + if(pclass->deleted) + pclass->deleted=0; pclass->ref_count++; break; case H5P_MOD_DEC_REF: /* Decrement the ID reference count*/ pclass->ref_count--; - break; - case H5P_MOD_CHECK: /* NOOP, just check if we can delete the class */ + /* Mark the class object as deleted if reference count drops to zero */ + if(pclass->ref_count==0) + pclass->deleted=1; break; - + case H5P_MOD_ERR: case H5P_MOD_MAX: assert(0 && "Invalid H5P class modification"); @@ -1024,6 +1023,8 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) /* Check if we can release the class information now */ if(pclass->deleted && pclass->plists==0 && pclass->classes==0 ) { + H5P_genclass_t *par_class=pclass->parent; /* Pointer to class's parent */ + assert(pclass->name); H5MM_xfree(pclass->name); @@ -1031,6 +1032,10 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) H5P_free_all_prop(pclass->props,pclass->hashsize,0); H5MM_xfree(pclass); + + /* Reduce the number of dependent classes on parent class also */ + if(par_class!=NULL) + H5P_access_class(par_class, H5P_MOD_DEC_CLS); } /* end if */ FUNC_LEAVE (SUCCEED); @@ -5029,21 +5034,6 @@ H5P_close_class(void *_pclass) if(H5P_access_class(pclass,H5P_MOD_DEC_REF)<0) HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL, "Can't decrement ID ref count"); - /* Check if the object should go away */ - if(pclass->ref_count==0) { - /* Decrement parent class's dependant property class value! */ - if(pclass->parent) - if (H5P_access_class(pclass->parent, H5P_MOD_DEC_CLS) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL,"Can't decrement class ref count"); - - /* Mark class as deleted */ - pclass->deleted = 1; - - /* Check dependancies on this class, deleting it if allowed */ - if (H5P_access_class(pclass, H5P_MOD_CHECK) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL,"Can't check class ref count"); - } /* end if */ - done: FUNC_LEAVE (ret_value); } /* H5P_close_class() */ |