[svn-r13101] Description:

Change to more complicated method of re-adding an attribute whose name
changes size, in order to get memory accesses correct.

Tested on:
    Linux/32 2.6 (chicago)
    Linux/64 2.6 (chicago2)
This commit is contained in:
Quincey Koziol 2007-01-03 10:04:55 -05:00
parent 9aa47d6ad5
commit b5a2e7c634

View File

@ -853,29 +853,55 @@ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, H5_ITER_ERROR, "renaming a shared attribu
/* Mark message as dirty */ /* Mark message as dirty */
mesg->dirty = TRUE; mesg->dirty = TRUE;
/* Check for attribute name getting longer */ /* Check for attribute message changing size */
if(HDstrlen(udata->new_name) > HDstrlen(udata->old_name)) { if(HDstrlen(udata->new_name) != HDstrlen(udata->old_name)) {
/* Increment attribute count */ H5A_t *attr; /* Attribute to re-add */
/* (must be incremented before call to H5O_msg_append_real(), in order for
* sanity checks to pass - QAK)
*/
if(oh->version > H5O_VERSION_1)
oh->nattrs++;
/* Append attribute to object header */ /* Take ownership of the message's native info (the attribute)
if(H5O_msg_append_real(udata->f, udata->dxpl_id, oh, H5O_MSG_ATTR, 0, 0, mesg->native, oh_flags_ptr) < 0) * so any shared objects in the file aren't adjusted (and
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to relocate attribute in header") * possibly deleted) when the message is released.
*/
/* (We do this more complicated sequence of actions because the
* simpler solution of adding the modified attribute first
* and then deleting the old message can re-allocate the
* list of messages during the "add the modified attribute"
* step, invalidating the message pointer we have here - QAK)
*/
attr = mesg->native;
mesg->native = NULL;
/* If the later version of the object header format, decrement attribute */ /* If the later version of the object header format, decrement attribute */
/* (must be decremented before call to H5O_release_mesg(), in order for /* (must be decremented before call to H5O_release_mesg(),
* sanity checks to pass - QAK) * so that the sanity checks pass - QAK)
*/ */
if(oh->version > H5O_VERSION_1) if(oh->version > H5O_VERSION_1)
oh->nattrs--; oh->nattrs--;
/* Convert message into a null message (i.e. delete it) */ /* Delete old attribute */
if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, TRUE, TRUE) < 0) /* (doesn't decrement the link count on shared components becuase
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to convert into null message") * the "native" pointer has been reset)
*/
if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, FALSE, FALSE) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to release previous attribute")
/* Increment attribute count */
/* (must be incremented before call to H5O_msg_append_real(),
* so that the sanity checks pass - QAK)
*/
if(oh->version > H5O_VERSION_1)
oh->nattrs++;
/* Append renamed attribute to object header */
/* (increments the link count on shared components) */
if(H5O_msg_append_real(udata->f, udata->dxpl_id, oh, H5O_MSG_ATTR, 0, 0, attr, oh_flags_ptr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to relocate renamed attribute in header")
/* Decrement the link count on shared components */
if(H5O_attr_delete(udata->f, udata->dxpl_id, attr, TRUE) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to delete attribute")
/* Release the local copy of the attribute */
H5O_msg_free_real(H5O_MSG_ATTR, attr);
} /* end if */ } /* end if */
/* Indicate that we found an existing attribute with the old name */ /* Indicate that we found an existing attribute with the old name */