[svn-r11060] Purpose: Fix bug (reported by user)

Description:
    The use of FileCreatPropList::DEFAULT sometimes caused failure
    in the reference counting area.  This occurs to all the default
    property lists, which also include FileAccPropList::DEFAULT,
    DSetCreatPropList::DEFAULT, and DSetMemXferPropList::DEFAULT.
    H5P_DEFAULT was used to create these default prop lists and
    because its value is 0, the id of these prop lists are 0, which
    is rejected by the H5I functions during the reference counting.

Solution:
    The main action to fix the above problem was to use
        H5P_FILE_CREATE
        H5P_FILE_ACCESS
        H5P_DATASET_CREATE
        H5P_DATASET_XFER
    to define the default property lists accordingly.  Yet, when this
    fix was applied, some bug in reference counting was revealed.
    It appeared that some ids were not incremented but were passed in
    for decrementing.  The following actions were then taken to fix and
    improve the current use of reference counting H5I functions.

        * added private func IdComponent::p_valid_id to verify that the
          id is a valid id and can be passed into an H5I function
        * used p_valid_id to validate an id before calling an H5I functions
          in the reference-counting member functions incRefCount,
          decRefCount, and getCounter
        * changed to use member function incRefCount, decRefCount, and
          getCounter instead of the C APIs H5Iinc_ref, H5Idec_ref, and
          H5Iget_ref throughout IdComponent.

    In addition, overloadings were added for incRefCount, decRefCount,
    and getCounter to take an id different than the id of the current
    instance; they can be convenient during debugging.

Platforms tested:
    Linux 2.4 (heping)
    SunOS 5.8 64-bit (sol)
    AIX 5.1 (copper)
This commit is contained in:
Binh-Minh Ribler
2005-07-10 06:26:56 -05:00
parent 6aa7ea9331
commit b14a4fd95f
14 changed files with 173 additions and 87 deletions

View File

@@ -41,35 +41,89 @@ IdComponent::IdComponent(const hid_t h5_id) : id(h5_id) {}
IdComponent::IdComponent( const IdComponent& original )
{
id = original.id;
H5Iinc_ref(id); // increment number of references to this id
incRefCount(); // increment number of references to this id
}
//--------------------------------------------------------------------------
// Function: IdComponent::incRefCount
///\brief Increment id reference counter.
///\brief Increment reference counter for a given id.
// Programmer Binh-Minh Ribler - May 2005
//--------------------------------------------------------------------------
void IdComponent::incRefCount(hid_t obj_id) const
{
if (p_valid_id(obj_id))
if (H5Iinc_ref(obj_id) < 0)
throw IdComponentException("IdComponent::incRefCount", "incrementing object ref count failed");
}
//--------------------------------------------------------------------------
// Function: IdComponent::incRefCount
///\brief Increment reference counter for the id of this object.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void IdComponent::incRefCount() { H5Iinc_ref(id); }
void IdComponent::incRefCount() const
{
incRefCount(id);
}
//--------------------------------------------------------------------------
// Function: IdComponent::decRefCount
///\brief Decrement id reference counter.
///\brief Decrement reference counter for a given id.
// Programmer Binh-Minh Ribler - May 2005
// Modification:
// Added the check for ref counter to give a little more info
// on why H5Idec_ref fails in some cases - BMR 5/19/2005
//--------------------------------------------------------------------------
void IdComponent::decRefCount(hid_t obj_id) const
{
if (p_valid_id(obj_id))
if (H5Idec_ref(obj_id) < 0)
if (H5Iget_ref(obj_id) <= 0)
throw IdComponentException("IdComponent::decRefCount",
"object ref count is 0 or negative");
else
throw IdComponentException("IdComponent::decRefCount",
"decrementing object ref count failed");
}
//--------------------------------------------------------------------------
// Function: IdComponent::decRefCount
///\brief Decrement reference counter for the id of this object.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void IdComponent::decRefCount()
void IdComponent::decRefCount() const
{
if(id>0)
if(H5Idec_ref(id)<0)
throw IdComponentException("IdComponent::decRefCount", "decrementing object ref count failed");
decRefCount(id);
}
//--------------------------------------------------------------------------
// Function: IdComponent::getCounter
///\brief Returns the reference counter to this identifier.
///\brief Returns the reference counter for a given id.
///\return Reference count
// Programmer Binh-Minh Ribler - May 2005
//--------------------------------------------------------------------------
int IdComponent::getCounter(hid_t obj_id) const
{
int counter = 0;
if (p_valid_id(obj_id))
{
counter = H5Iget_ref(obj_id);
if (counter < 0)
throw IdComponentException("IdComponent::incRefCount", "incrementing object ref count failed");
}
return (counter);
}
//--------------------------------------------------------------------------
// Function: IdComponent::getCounter
///\brief Returns the reference counter for the id of this object.
///\return Reference count
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
int IdComponent::getCounter() { return( H5Iget_ref(id)); }
int IdComponent::getCounter() const
{
return (getCounter(id));
}
//--------------------------------------------------------------------------
// Function: IdComponent::operator=
@@ -95,7 +149,7 @@ IdComponent& IdComponent::operator=( const IdComponent& rhs )
id = rhs.id;
// increment the reference counter
H5Iinc_ref(id);
incRefCount();
return( *this );
}
@@ -210,7 +264,7 @@ string IdComponent::p_get_file_name() const
// Convert the C file name and return
string file_name(name_C);
delete name_C;
delete []name_C;
return(file_name);
}
@@ -284,6 +338,26 @@ hid_t IdComponent::p_get_region(void *ref, H5R_type_t ref_type) const
return(space_id);
}
//
// Local functions used in this class
//
//--------------------------------------------------------------------------
// Function: p_valid_id
// Purpose: Verifies that the given id is a valid id so it can be passed
// into an H5I C function.
// Return true if id is valid, false, otherwise
// Programmer Binh-Minh Ribler - May, 2005
//--------------------------------------------------------------------------
bool IdComponent::p_valid_id(hid_t obj_id) const
{
H5I_type_t id_type = H5Iget_type(obj_id);
if (id_type <= H5I_BADID || id_type >= H5I_NTYPES)
return false;
else
return true;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
#ifndef H5_NO_NAMESPACE