From 25b702e2bed191bcba75dd715863e94f926e70ea Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 8 Oct 1997 15:37:02 -0500 Subject: [svn-r113] Added mechanism for reference counting IDs. This is to facilitate sharing an ID between multiple interfaces in memory. Changes included adding a parameter to the H5Ainit_group call for the function to call to free the structure associated with an ID when its reference count drops to zero and two new function calls: H5Ainc_ref & H5Adec_ref which increment and decrement the reference count of IDs. Its still possible to call H5Aremove_atom on a ID with multiple references, leaving dangling IDs in memory... --- src/H5A.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/H5Aprivate.h | 5 +-- src/H5Apublic.h | 37 +++++++++++++++++++-- 3 files changed, 136 insertions(+), 5 deletions(-) diff --git a/src/H5A.c b/src/H5A.c index e12d9cd..4cf2197 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -130,7 +130,8 @@ static herr_t H5A_init_interface(void) *******************************************************************************/ intn H5Ainit_group(group_t grp, /* IN: Group to initialize */ intn hash_size, /* IN: Minimum hash table size to use for group */ - uintn reserved /* IN: Number of hash table entries to reserve */ + uintn reserved, /* IN: Number of hash table entries to reserve */ + void (*free_func)(void *) /* IN: Function to call when releasing ref counted objects */ ) { atom_group_t *grp_ptr=NULL; /* ptr to the atomic group */ @@ -172,6 +173,7 @@ intn H5Ainit_group(group_t grp, /* IN: Group to initialize */ grp_ptr->wrapped=0; grp_ptr->atoms=0; grp_ptr->nextid=reserved; + grp_ptr->free_func=free; if((grp_ptr->atom_list=(atom_info_t **)HDcalloc(hash_size,sizeof(atom_info_t *)))==NULL) HGOTO_DONE(FAIL); } /* end if */ @@ -298,6 +300,7 @@ hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in * /* Create the atom & it's ID */ atm_id=MAKE_ATOM(grp,grp_ptr->nextid); atm_ptr->id=atm_id; + atm_ptr->count=1; /* reference count all objects (even if no 'free' function defined */ atm_ptr->obj_ptr=object; atm_ptr->next=NULL; @@ -359,6 +362,49 @@ done: /****************************************************************************** NAME + H5Ainc_ref - Adds a reference to a reference counted atom. + + DESCRIPTION + Increments the number of references outstanding for an atom. This will + fail if the group is not a reference counted group. + + RETURNS + SUCCEED/FAIL + +*******************************************************************************/ +intn H5Ainc_ref(hid_t atm /* IN: Atom to increment reference count for */ +) +{ + group_t grp=ATOM_TO_GROUP(atm); /* Group the object is in */ + atom_group_t *grp_ptr=NULL; /* ptr to the atomic group */ + atom_info_t *atm_ptr=NULL; /* ptr to the new atom */ + intn ret_value=FAIL; + + FUNC_ENTER (H5Ainc_ref, H5A_init_interface, FAIL); + + grp_ptr=atom_group_list[grp]; + if(grp_ptr==NULL || grp_ptr->count<=0 || grp_ptr->free_func==NULL) + HGOTO_DONE(FAIL); + + /* General lookup of the atom */ + if((atm_ptr=H5A_find_atom(atm))!=NULL) + { + atm_ptr->count++; + ret_value=SUCCEED; + } /* end if */ + +done: + if(ret_value == FAIL) + { /* Error condition cleanup */ + + } /* end if */ + + /* Normal function cleanup */ + FUNC_LEAVE(ret_value); +} /* end H5Ainc_ref() */ + +/****************************************************************************** + NAME H5Aatom_object - Returns to the object ptr for the atom DESCRIPTION @@ -536,6 +582,57 @@ done: /****************************************************************************** NAME + H5Adec_ref - Decrements a reference to a reference counted atom. + + DESCRIPTION + Decrements the number of references outstanding for an atom. This will + fail if the group is not a reference counted group. The atom group's + 'free' function will be called for the atom if the reference count for the + atom reaches 0. + + RETURNS + SUCCEED/FAIL + +*******************************************************************************/ +intn H5Adec_ref(hid_t atm /* IN: Atom to decrement reference count for */ +) +{ + group_t grp=ATOM_TO_GROUP(atm); /* Group the object is in */ + atom_group_t *grp_ptr=NULL; /* ptr to the atomic group */ + atom_info_t *atm_ptr=NULL; /* ptr to the new atom */ + VOIDP obj; /* object to call 'free' function with */ + intn ret_value=FAIL; + + FUNC_ENTER (H5Adec_ref, H5A_init_interface, FAIL); + + grp_ptr=atom_group_list[grp]; + if(grp_ptr==NULL || grp_ptr->count<=0 || grp_ptr->free_func==NULL) + HGOTO_DONE(FAIL); + + /* General lookup of the atom */ + if((atm_ptr=H5A_find_atom(atm))!=NULL) + { + /* Decrement the reference count */ + atm_ptr->count--; + + /* If the reference count is zero, remove the object from the group */ + if(atm_ptr->count==0 && (obj=H5Aremove_atom(atm))!=NULL) + grp_ptr->free_func(obj); /* call the user's 'free' function for the atom's information */ + ret_value=SUCCEED; + } /* end if */ + +done: + if(ret_value == FAIL) + { /* Error condition cleanup */ + + } /* end if */ + + /* Normal function cleanup */ + FUNC_LEAVE(ret_value); +} /* end H5Adec_ref() */ + +/****************************************************************************** + NAME H5Asearch_atom - Search for an object in a group and get it's pointer. DESCRIPTION diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h index 97b8688..38a7512 100644 --- a/src/H5Aprivate.h +++ b/src/H5Aprivate.h @@ -67,7 +67,8 @@ /* Atom information structure used */ typedef struct atom_info_struct_tag { - hid_t id; /* atom ID for this info */ + hid_t id; /* atom ID for this info */ + uintn count; /* ref. count for this atom */ VOIDP *obj_ptr; /* pointer associated with the atom */ struct atom_info_struct_tag *next; /* link to next atom (in case of hash-clash) */ }atom_info_t; @@ -80,9 +81,9 @@ typedef struct atom_group_struct_tag { intn hash_size; /* size of the hash table to store the atoms in */ uintn atoms; /* current number of atoms held */ uintn nextid; /* atom ID to use for the next atom */ + void (*free_func)(void *); /* Pointer to function to call when releasing ref counted object */ atom_info_t **atom_list;/* pointer to an array of ptrs to atoms */ }atom_group_t; - #endif diff --git a/src/H5Apublic.h b/src/H5Apublic.h index 8bc5b7f..36cceed 100644 --- a/src/H5Apublic.h +++ b/src/H5Apublic.h @@ -70,9 +70,10 @@ extern "C" { Returns SUCCEED if successful and FAIL otherwise *******************************************************************************/ -intn H5Ainit_group(group_t grp, /* IN: Group to initialize */ +intn H5Ainit_group(group_t grp, /* IN: Group to initialize */ intn hash_size, /* IN: Minimum hash table size to use for group */ - uintn reserved /* IN: Number of hash table entries to reserve */ + uintn reserved, /* IN: Number of hash table entries to reserve */ + void (*free_func)(void *) /* IN: Function to call when releasing ref counted objects */ ); /****************************************************************************** @@ -114,6 +115,21 @@ hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in * /****************************************************************************** NAME + H5Ainc_ref - Adds a reference to a reference counted atom. + + DESCRIPTION + Increments the number of references outstanding for an atom. This will + fail if the group is not a reference counted group. + + RETURNS + SUCCEED/FAIL + +*******************************************************************************/ +intn H5Ainc_ref(hid_t atm /* IN: Atom to increment reference count for */ +); + +/****************************************************************************** + NAME H5Aatom_object - Returns to the object ptr for the atom DESCRIPTION @@ -156,6 +172,23 @@ VOIDP H5Aremove_atom(hid_t atm /* IN: Atom to remove */ /****************************************************************************** NAME + H5Adec_ref - Decrements a reference to a reference counted atom. + + DESCRIPTION + Decrements the number of references outstanding for an atom. This will + fail if the group is not a reference counted group. The atom group's + 'free' function will be called for the atom if the reference count for the + atom reaches 0. + + RETURNS + SUCCEED/FAIL + +*******************************************************************************/ +intn H5Adec_ref(hid_t atm /* IN: Atom to decrement reference count for */ +); + +/****************************************************************************** + NAME H5Asearch_atom - Search for an object in a group and get it's pointer. DESCRIPTION -- cgit v0.12