mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-07 16:37:56 +08:00
[svn-r27615] Description:
Protect dataset that's closing from being flushed again, if it's the last one holding a file open. Tested on: MacOSX/64 10.10.5 (amazon) w/serial & parallel (h5committest forthcoming)
This commit is contained in:
parent
1103585dc1
commit
097d2de6f8
85
src/H5Dint.c
85
src/H5Dint.c
@ -1486,7 +1486,7 @@ done:
|
||||
herr_t
|
||||
H5D_close(H5D_t *dataset)
|
||||
{
|
||||
unsigned free_failed = FALSE;
|
||||
hbool_t free_failed = FALSE;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
@ -1506,16 +1506,18 @@ H5D_close(H5D_t *dataset)
|
||||
if(H5D__flush_real(dataset, H5AC_dxpl_id) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush cached dataset info")
|
||||
|
||||
/* Free the data sieve buffer, if it's been allocated */
|
||||
if(dataset->shared->cache.contig.sieve_buf) {
|
||||
HDassert(dataset->shared->layout.type != H5D_COMPACT); /* We should never have a sieve buffer for compact storage */
|
||||
|
||||
dataset->shared->cache.contig.sieve_buf = (unsigned char *)H5FL_BLK_FREE(sieve_buf,dataset->shared->cache.contig.sieve_buf);
|
||||
} /* end if */
|
||||
/* Set a flag to indicate the dataset is closing, before we start freeing things */
|
||||
/* (Avoids problems with flushing datasets twice, when one is holding
|
||||
* the file open and it iterates through dataset to flush them -QAK)
|
||||
*/
|
||||
dataset->shared->closing = TRUE;
|
||||
|
||||
/* Free cached information for each kind of dataset */
|
||||
switch(dataset->shared->layout.type) {
|
||||
case H5D_CONTIGUOUS:
|
||||
/* Free the data sieve buffer, if it's been allocated */
|
||||
if(dataset->shared->cache.contig.sieve_buf)
|
||||
dataset->shared->cache.contig.sieve_buf = (unsigned char *)H5FL_BLK_FREE(sieve_buf,dataset->shared->cache.contig.sieve_buf);
|
||||
break;
|
||||
|
||||
case H5D_CHUNKED:
|
||||
@ -1562,8 +1564,9 @@ H5D_close(H5D_t *dataset)
|
||||
* Release datatype, dataspace and creation property list -- there isn't
|
||||
* much we can do if one of these fails, so we just continue.
|
||||
*/
|
||||
free_failed = (unsigned)(H5I_dec_ref(dataset->shared->type_id) < 0 || H5S_close(dataset->shared->space) < 0 ||
|
||||
H5I_dec_ref(dataset->shared->dcpl_id) < 0);
|
||||
free_failed = (H5I_dec_ref(dataset->shared->type_id) < 0) ||
|
||||
(H5S_close(dataset->shared->space) < 0) ||
|
||||
(H5I_dec_ref(dataset->shared->dcpl_id) < 0);
|
||||
|
||||
/* Remove the dataset from the list of opened objects in the file */
|
||||
if(H5FO_top_decr(dataset->oloc.file, dataset->oloc.addr) < 0)
|
||||
@ -2459,44 +2462,48 @@ H5D__flush_real(H5D_t *dataset, hid_t dxpl_id)
|
||||
|
||||
/* Check args */
|
||||
HDassert(dataset);
|
||||
HDassert(dataset->shared);
|
||||
|
||||
/* Check for metadata changes that will require updating the object's modification time */
|
||||
if(dataset->shared->layout_dirty || dataset->shared->space_dirty) {
|
||||
unsigned update_flags = H5O_UPDATE_TIME; /* Modification time flag */
|
||||
/* Avoid flushing the dataset (again) if it's closing */
|
||||
if(!dataset->shared->closing) {
|
||||
/* Check for metadata changes that will require updating the object's modification time */
|
||||
if(dataset->shared->layout_dirty || dataset->shared->space_dirty) {
|
||||
unsigned update_flags = H5O_UPDATE_TIME; /* Modification time flag */
|
||||
|
||||
/* Pin the object header */
|
||||
if(NULL == (oh = H5O_pin(&dataset->oloc, dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
|
||||
/* Pin the object header */
|
||||
if(NULL == (oh = H5O_pin(&dataset->oloc, dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
|
||||
|
||||
/* Update the layout on disk, if it's been changed */
|
||||
if(dataset->shared->layout_dirty) {
|
||||
if(H5D__layout_oh_write(dataset, dxpl_id, oh, update_flags) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update layout/pline/efl info")
|
||||
dataset->shared->layout_dirty = FALSE;
|
||||
/* Update the layout on disk, if it's been changed */
|
||||
if(dataset->shared->layout_dirty) {
|
||||
if(H5D__layout_oh_write(dataset, dxpl_id, oh, update_flags) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update layout/pline/efl info")
|
||||
dataset->shared->layout_dirty = FALSE;
|
||||
|
||||
/* Reset the "update the modification time" flag, so we only do it once */
|
||||
update_flags = 0;
|
||||
/* Reset the "update the modification time" flag, so we only do it once */
|
||||
update_flags = 0;
|
||||
} /* end if */
|
||||
|
||||
/* Update the dataspace on disk, if it's been changed */
|
||||
if(dataset->shared->space_dirty) {
|
||||
if(H5S_write(dataset->oloc.file, dxpl_id, oh, update_flags, dataset->shared->space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace")
|
||||
dataset->shared->space_dirty = FALSE;
|
||||
|
||||
/* Reset the "update the modification time" flag, so we only do it once */
|
||||
update_flags = 0;
|
||||
} /* end if */
|
||||
|
||||
/* _Somebody_ should have update the modification time! */
|
||||
HDassert(update_flags == 0);
|
||||
} /* end if */
|
||||
|
||||
/* Update the dataspace on disk, if it's been changed */
|
||||
if(dataset->shared->space_dirty) {
|
||||
if(H5S_write(dataset->oloc.file, dxpl_id, oh, update_flags, dataset->shared->space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace")
|
||||
dataset->shared->space_dirty = FALSE;
|
||||
|
||||
/* Reset the "update the modification time" flag, so we only do it once */
|
||||
update_flags = 0;
|
||||
} /* end if */
|
||||
|
||||
/* _Somebody_ should have update the modification time! */
|
||||
HDassert(update_flags == 0);
|
||||
/* Flush cached raw data for each kind of dataset layout */
|
||||
if(dataset->shared->layout.ops->flush &&
|
||||
(dataset->shared->layout.ops->flush)(dataset, dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush raw data")
|
||||
} /* end if */
|
||||
|
||||
/* Flush cached raw data for each kind of dataset layout */
|
||||
if(dataset->shared->layout.ops->flush &&
|
||||
(dataset->shared->layout.ops->flush)(dataset, dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush raw data")
|
||||
|
||||
done:
|
||||
/* Release pointer to object header */
|
||||
if(oh != NULL)
|
||||
|
@ -408,6 +408,7 @@ typedef struct H5D_rdcdc_t {
|
||||
*/
|
||||
typedef struct H5D_shared_t {
|
||||
size_t fo_count; /* Reference count */
|
||||
hbool_t closing; /* Flag to indicate dataset is closing */
|
||||
hid_t type_id; /* ID for dataset's datatype */
|
||||
H5T_t *type; /* Datatype for this dataset */
|
||||
H5S_t *space; /* Dataspace of this dataset */
|
||||
|
Loading…
Reference in New Issue
Block a user