mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-17 16:10:24 +08:00
[svn-r11093] Purpose:
Bug fix Description: Rewrite code for mounting files to clean up layers of kludges and implement a much cleaner and more maintainable design. Platforms tested: FreeBSD 4.11 (sleipnir) Linux 2.4
This commit is contained in:
parent
e9d54ca186
commit
bb31e94a92
1
MANIFEST
1
MANIFEST
@ -622,7 +622,6 @@ a------------------------------------------------------------------------------
|
||||
./test/family_v1.6_00001.h5
|
||||
./test/family_v1.6_00002.h5
|
||||
./test/family_v1.6_00003.h5
|
||||
./test/filename.c
|
||||
./test/fill_old.h5
|
||||
./test/fillval.c
|
||||
./test/flush1.c
|
||||
|
108
src/H5.c
108
src/H5.c
@ -2098,9 +2098,6 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
|
||||
case H5I_FILE:
|
||||
fprintf(out, "%ld (file)", (long)obj);
|
||||
break;
|
||||
case H5I_FILE_CLOSING:
|
||||
fprintf(out, "%ld (file closing)", (long)obj);
|
||||
break;
|
||||
case H5I_GROUP:
|
||||
fprintf(out, "%ld (group)", (long)obj);
|
||||
break;
|
||||
@ -2300,60 +2297,57 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
|
||||
} else {
|
||||
H5I_type_t id_type = va_arg (ap, H5I_type_t); /*lint !e64 Type mismatch not really occuring */
|
||||
switch (id_type) {
|
||||
case H5I_UNINIT:
|
||||
fprintf (out, "H5I_UNINIT");
|
||||
break;
|
||||
case H5I_BADID:
|
||||
fprintf (out, "H5I_BADID");
|
||||
break;
|
||||
case H5I_FILE:
|
||||
fprintf (out, "H5I_FILE");
|
||||
break;
|
||||
case H5I_FILE_CLOSING:
|
||||
fprintf (out, "H5I_FILE_CLOSING");
|
||||
break;
|
||||
case H5I_GROUP:
|
||||
fprintf (out, "H5I_GROUP");
|
||||
break;
|
||||
case H5I_DATATYPE:
|
||||
fprintf (out, "H5I_DATATYPE");
|
||||
break;
|
||||
case H5I_DATASPACE:
|
||||
fprintf (out, "H5I_DATASPACE");
|
||||
break;
|
||||
case H5I_DATASET:
|
||||
fprintf (out, "H5I_DATASET");
|
||||
break;
|
||||
case H5I_ATTR:
|
||||
fprintf (out, "H5I_ATTR");
|
||||
break;
|
||||
case H5I_REFERENCE:
|
||||
fprintf (out, "H5I_REFERENCE");
|
||||
break;
|
||||
case H5I_VFL:
|
||||
fprintf (out, "H5I_VFL");
|
||||
break;
|
||||
case H5I_GENPROP_CLS:
|
||||
fprintf (out, "H5I_GENPROP_CLS");
|
||||
break;
|
||||
case H5I_GENPROP_LST:
|
||||
fprintf (out, "H5I_GENPROP_LST");
|
||||
break;
|
||||
case H5I_ERROR_CLASS:
|
||||
fprintf (out, "H5I_ERROR_CLASS");
|
||||
break;
|
||||
case H5I_ERROR_MSG:
|
||||
fprintf (out, "H5I_ERROR_MSG");
|
||||
break;
|
||||
case H5I_ERROR_STACK:
|
||||
fprintf (out, "H5I_ERROR_STACK");
|
||||
break;
|
||||
case H5I_NTYPES:
|
||||
fprintf (out, "H5I_NTYPES");
|
||||
break;
|
||||
default:
|
||||
fprintf (out, "%ld", (long)id_type);
|
||||
break;
|
||||
case H5I_UNINIT:
|
||||
fprintf (out, "H5I_UNINIT");
|
||||
break;
|
||||
case H5I_BADID:
|
||||
fprintf (out, "H5I_BADID");
|
||||
break;
|
||||
case H5I_FILE:
|
||||
fprintf (out, "H5I_FILE");
|
||||
break;
|
||||
case H5I_GROUP:
|
||||
fprintf (out, "H5I_GROUP");
|
||||
break;
|
||||
case H5I_DATATYPE:
|
||||
fprintf (out, "H5I_DATATYPE");
|
||||
break;
|
||||
case H5I_DATASPACE:
|
||||
fprintf (out, "H5I_DATASPACE");
|
||||
break;
|
||||
case H5I_DATASET:
|
||||
fprintf (out, "H5I_DATASET");
|
||||
break;
|
||||
case H5I_ATTR:
|
||||
fprintf (out, "H5I_ATTR");
|
||||
break;
|
||||
case H5I_REFERENCE:
|
||||
fprintf (out, "H5I_REFERENCE");
|
||||
break;
|
||||
case H5I_VFL:
|
||||
fprintf (out, "H5I_VFL");
|
||||
break;
|
||||
case H5I_GENPROP_CLS:
|
||||
fprintf (out, "H5I_GENPROP_CLS");
|
||||
break;
|
||||
case H5I_GENPROP_LST:
|
||||
fprintf (out, "H5I_GENPROP_LST");
|
||||
break;
|
||||
case H5I_ERROR_CLASS:
|
||||
fprintf (out, "H5I_ERROR_CLASS");
|
||||
break;
|
||||
case H5I_ERROR_MSG:
|
||||
fprintf (out, "H5I_ERROR_MSG");
|
||||
break;
|
||||
case H5I_ERROR_STACK:
|
||||
fprintf (out, "H5I_ERROR_STACK");
|
||||
break;
|
||||
case H5I_NTYPES:
|
||||
fprintf (out, "H5I_NTYPES");
|
||||
break;
|
||||
default:
|
||||
fprintf (out, "%ld", (long)id_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
17
src/H5D.c
17
src/H5D.c
@ -4101,8 +4101,6 @@ done:
|
||||
*
|
||||
* Date: August 14, 2002
|
||||
*
|
||||
* Comments: Just flushing the compact data information currently.
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@ -4110,11 +4108,11 @@ done:
|
||||
herr_t
|
||||
H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
|
||||
{
|
||||
int num_dsets; /* Number of datasets in file */
|
||||
unsigned num_dsets; /* Number of datasets in file */
|
||||
hid_t *id_list=NULL; /* list of dataset IDs */
|
||||
H5D_t *dataset=NULL; /* Dataset pointer */
|
||||
unsigned u; /* Index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
int j; /* Index variable */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5D_flush, FAIL)
|
||||
|
||||
@ -4122,18 +4120,17 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
|
||||
assert(f);
|
||||
|
||||
/* Update layout message for compact dataset */
|
||||
if((num_dsets=H5F_get_obj_count(f, H5F_OBJ_DATASET))<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset count")
|
||||
num_dsets=H5F_get_obj_count(f, H5F_OBJ_DATASET);
|
||||
|
||||
/* Check for something to do */
|
||||
if(num_dsets>0) {
|
||||
H5_CHECK_OVERFLOW(num_dsets,int,size_t);
|
||||
H5_CHECK_OVERFLOW(num_dsets,unsigned,size_t);
|
||||
if(NULL==(id_list=H5MM_malloc((size_t)num_dsets*sizeof(hid_t))))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate memory for ID list")
|
||||
if(H5F_get_obj_ids(f, H5F_OBJ_DATASET, -1, id_list)<0)
|
||||
if(H5F_get_obj_ids(f, H5F_OBJ_DATASET, -1, id_list) != num_dsets)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset ID list")
|
||||
for(j=0; j<num_dsets; j++) {
|
||||
if(NULL==(dataset=H5I_object_verify(id_list[j], H5I_DATASET)))
|
||||
for(u = 0; u < num_dsets; u++) {
|
||||
if(NULL==(dataset=H5I_object_verify(id_list[u], H5I_DATASET)))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset object")
|
||||
|
||||
/* Flush the raw data buffer, if we have a dirty one */
|
||||
|
715
src/H5F.c
715
src/H5F.c
@ -60,6 +60,12 @@ typedef struct H5F_olist_t {
|
||||
int max_index; /* Maximum # of IDs to put into array */
|
||||
} H5F_olist_t;
|
||||
|
||||
/* Struct for tracking "shared" file structs */
|
||||
typedef struct H5F_sfile_node_t {
|
||||
H5F_file_t *shared; /* Pointer to "shared" struct */
|
||||
struct H5F_sfile_node_t *next; /* Pointer to next node */
|
||||
} H5F_sfile_node_t;
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
|
||||
#ifdef NOT_YET
|
||||
@ -67,19 +73,31 @@ static herr_t H5F_flush_all(hbool_t invalidate);
|
||||
static int H5F_flush_all_cb(void *f, hid_t fid, void *_invalidate);
|
||||
#endif /* NOT_YET */
|
||||
|
||||
static herr_t H5F_close(H5F_t *f);
|
||||
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id);
|
||||
static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id);
|
||||
static herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags);
|
||||
static int H5F_get_objects(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
|
||||
static unsigned H5F_get_objects(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
|
||||
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
|
||||
static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle);
|
||||
|
||||
/* Routines to operate on the shared file list */
|
||||
static herr_t H5F_shared_add(H5F_file_t *shared);
|
||||
static H5F_file_t * H5F_shared_search(H5FD_t *lf);
|
||||
static herr_t H5F_shared_remove(H5F_file_t *shared);
|
||||
|
||||
/* Declare a free list to manage the H5F_t struct */
|
||||
H5FL_DEFINE_STATIC(H5F_t);
|
||||
|
||||
/* Declare a free list to manage the H5F_file_t struct */
|
||||
H5FL_DEFINE_STATIC(H5F_file_t);
|
||||
|
||||
/* Declare a free list to manage the H5F_sfile_node_t struct */
|
||||
H5FL_DEFINE_STATIC(H5F_sfile_node_t);
|
||||
|
||||
/* Declare a local variable to track the shared file information */
|
||||
H5F_sfile_node_t *H5F_sfile_head_g = NULL;
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_init
|
||||
@ -220,15 +238,9 @@ H5F_init_interface(void)
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_init_interface)
|
||||
|
||||
/*
|
||||
* Initialize the atom group for the file IDs. There are two groups:
|
||||
* the H5I_FILE group contains all the ID's for files which are currently
|
||||
* open at the public API level while the H5I_FILE_CLOSING group contains
|
||||
* ID's for files for which the application has called H5Fclose() but
|
||||
* which are pending completion because there are object headers still
|
||||
* open within the file.
|
||||
* Initialize the atom group for the file IDs.
|
||||
*/
|
||||
if (H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE ||
|
||||
H5I_register_type(H5I_FILE_CLOSING, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE)
|
||||
if (H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE)
|
||||
HGOTO_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface")
|
||||
|
||||
/* ========== File Creation Property Class Initialization ============*/
|
||||
@ -438,13 +450,11 @@ H5F_term_interface(void)
|
||||
if (H5_interface_initialize_g) {
|
||||
if ((n=H5I_nmembers(H5I_FILE))!=0) {
|
||||
H5I_clear_type(H5I_FILE, FALSE);
|
||||
} else if ((n=H5I_nmembers(H5I_FILE_CLOSING))!=0) {
|
||||
/* Attempt to unmount any child files from files that are closing */
|
||||
(void)H5I_search(H5I_FILE_CLOSING, H5F_term_unmount_cb, NULL);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Make certain we've cleaned up all the shared file objects */
|
||||
HDassert(H5F_sfile_head_g == NULL);
|
||||
|
||||
H5I_dec_type_ref(H5I_FILE);
|
||||
H5I_dec_type_ref(H5I_FILE_CLOSING);
|
||||
H5_interface_initialize_g = 0;
|
||||
n = 1; /*H5I*/
|
||||
}
|
||||
@ -962,17 +972,15 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
unsigned
|
||||
H5F_get_obj_count(const H5F_t *f, unsigned types)
|
||||
{
|
||||
int ret_value; /* Return value */
|
||||
unsigned ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_get_obj_count)
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_count)
|
||||
|
||||
if((ret_value=H5F_get_objects(f, types, -1, NULL)) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get counts of opened file IDs and object IDs in the file")
|
||||
ret_value=H5F_get_objects(f, types, -1, NULL);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
@ -1014,7 +1022,7 @@ done:
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_get_object_ids
|
||||
* Function: H5F_get_obj_ids
|
||||
*
|
||||
* Purpose: Private function to return a list of opened object IDs.
|
||||
*
|
||||
@ -1027,17 +1035,15 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
unsigned
|
||||
H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *oid_list)
|
||||
{
|
||||
int ret_value; /* Return value */
|
||||
unsigned ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_get_obj_ids)
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_ids)
|
||||
|
||||
if((ret_value=H5F_get_objects(f, types, max_objs, oid_list)) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object IDs opened in the file")
|
||||
ret_value = H5F_get_objects(f, types, max_objs, oid_list);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
@ -1057,12 +1063,12 @@ done:
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
static unsigned
|
||||
H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_list)
|
||||
{
|
||||
unsigned obj_id_count=0; /* Number of open IDs */
|
||||
H5F_olist_t olist; /* Structure to hold search results */
|
||||
int ret_value; /* Return value */
|
||||
unsigned ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_objects)
|
||||
|
||||
@ -1084,45 +1090,42 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis
|
||||
|
||||
/* Search through file IDs to count the number, and put their
|
||||
* IDs on the object list */
|
||||
if( (types & H5F_OBJ_FILE) && H5I_nmembers(H5I_FILE) > 0 ) {
|
||||
if(types & H5F_OBJ_FILE) {
|
||||
olist.obj_type = H5I_FILE;
|
||||
(void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist);
|
||||
}
|
||||
} /* end if */
|
||||
|
||||
/* Search through dataset IDs to count number of datasets, and put their
|
||||
* IDs on the object list */
|
||||
if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_DATASET) && H5I_nmembers(H5I_DATASET) > 0 ) {
|
||||
if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATASET) ) {
|
||||
olist.obj_type = H5I_DATASET;
|
||||
(void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist);
|
||||
}
|
||||
|
||||
/* Search through group IDs to count number of groups, and put their
|
||||
* IDs on the object list */
|
||||
if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_GROUP) && H5I_nmembers(H5I_GROUP) > 0 ) {
|
||||
if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_GROUP) ) {
|
||||
olist.obj_type = H5I_GROUP;
|
||||
(void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist);
|
||||
}
|
||||
|
||||
/* Search through datatype IDs to count number of named datatypes, and put their
|
||||
* IDs on the object list */
|
||||
if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_DATATYPE) && H5I_nmembers(H5I_DATATYPE) > 0 ) {
|
||||
if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATATYPE) ) {
|
||||
olist.obj_type = H5I_DATATYPE;
|
||||
(void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist);
|
||||
}
|
||||
|
||||
/* Search through attribute IDs to count number of attributes, and put their
|
||||
* IDs on the object list */
|
||||
if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_ATTR) && H5I_nmembers(H5I_ATTR) > 0 ) {
|
||||
if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_ATTR) ) {
|
||||
olist.obj_type = H5I_ATTR;
|
||||
(void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist);
|
||||
}
|
||||
|
||||
/* Set the number of objects currently open */
|
||||
H5_ASSIGN_OVERFLOW(ret_value,obj_id_count,unsigned,int);
|
||||
ret_value = obj_id_count;
|
||||
|
||||
#ifdef LATER
|
||||
done:
|
||||
#endif /* LATER */
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
@ -1294,39 +1297,6 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_equal
|
||||
*
|
||||
* Purpose: Compares NEEDLE to a file from the HAYSTACK.
|
||||
*
|
||||
* Return: Success: Returns positive if two files are equal,
|
||||
* zero otherwise.
|
||||
*
|
||||
* Failure: Negative
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, August 2, 1999
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
H5F_equal(void *_haystack, hid_t UNUSED id, void *_needle)
|
||||
{
|
||||
H5F_t *haystack = (H5F_t*)_haystack;
|
||||
const H5FD_t *needle = (const H5FD_t*)_needle;
|
||||
int retval;
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_equal)
|
||||
|
||||
retval = (0==H5FD_cmp(haystack->shared->lf, needle));
|
||||
|
||||
FUNC_LEAVE_NOAPI(retval)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_locate_signature
|
||||
@ -1557,20 +1527,19 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
|
||||
* The cache might be created with a different number of elements and
|
||||
* the access property list should be updated to reflect that.
|
||||
*/
|
||||
if ( SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)) ) {
|
||||
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, \
|
||||
"unable to create meta data cache")
|
||||
|
||||
}
|
||||
if ( SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)) )
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache")
|
||||
|
||||
/* Create the file's "open object" information */
|
||||
if(H5FO_create(f)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object TBBT")
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure")
|
||||
|
||||
/* Add new "shared" struct to list of open files */
|
||||
if(H5F_shared_add(f->shared) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files")
|
||||
} /* end else */
|
||||
|
||||
f->shared->nrefs++;
|
||||
f->nrefs = 1;
|
||||
|
||||
/* Set return value */
|
||||
ret_value = f;
|
||||
@ -1627,77 +1596,83 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_dest)
|
||||
|
||||
if (f && 1==f->nrefs) {
|
||||
if (1==f->shared->nrefs) {
|
||||
/*
|
||||
* Do not close the root group since we didn't count it, but free
|
||||
* the memory associated with it.
|
||||
*/
|
||||
if (f->shared->root_grp) {
|
||||
/* Free the ID to name buffer */
|
||||
if(H5G_free_grp_name(f->shared->root_grp)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
/* Sanity check */
|
||||
HDassert(f);
|
||||
|
||||
/* Free the memory for the root group */
|
||||
if(H5G_free(f->shared->root_grp)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
f->shared->root_grp=NULL;
|
||||
}
|
||||
if (H5AC_dest(f, dxpl_id)) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
}
|
||||
if (H5FO_dest(f)<0) {
|
||||
if (1==f->shared->nrefs) {
|
||||
/* Remove shared file struct from list of open files */
|
||||
if(H5F_shared_remove(f->shared) < 0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
|
||||
/*
|
||||
* Do not close the root group since we didn't count it, but free
|
||||
* the memory associated with it.
|
||||
*/
|
||||
if (f->shared->root_grp) {
|
||||
/* Free the ID to name buffer */
|
||||
if(H5G_free_grp_name(f->shared->root_grp)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
f->shared->cwfs = H5MM_xfree (f->shared->cwfs);
|
||||
if (H5G_node_close(f)<0) {
|
||||
} /* end if */
|
||||
|
||||
/* Free the memory for the root group */
|
||||
if(H5G_free(f->shared->root_grp)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
f->shared->root_grp=NULL;
|
||||
}
|
||||
if (H5AC_dest(f, dxpl_id)) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
}
|
||||
if (H5FO_dest(f)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
f->shared->cwfs = H5MM_xfree (f->shared->cwfs);
|
||||
if (H5G_node_close(f)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
|
||||
/* Destroy file creation properties */
|
||||
if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id))
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list")
|
||||
if((ret_value=H5I_dec_ref(f->shared->fcpl_id)) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list")
|
||||
/* Destroy file creation properties */
|
||||
if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) {
|
||||
HERROR(H5E_PLIST, H5E_BADTYPE, "not a property list");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
if((ret_value=H5I_dec_ref(f->shared->fcpl_id)) < 0) {
|
||||
HERROR(H5E_PLIST, H5E_CANTFREE, "can't close property list");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
} /* end if */
|
||||
|
||||
/* Destroy shared file struct */
|
||||
if (H5FD_close(f->shared->lf)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
}
|
||||
f->shared = H5FL_FREE(H5F_file_t,f->shared);
|
||||
|
||||
} else if (f->shared->nrefs>0) {
|
||||
/*
|
||||
* There are other references to the shared part of the file.
|
||||
* Only decrement the reference count.
|
||||
*/
|
||||
--f->shared->nrefs;
|
||||
}
|
||||
/* Close low-level file */
|
||||
if (H5FD_close(f->shared->lf)<0) {
|
||||
HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
|
||||
ret_value = FAIL; /*but keep going*/
|
||||
}
|
||||
|
||||
/* Free the non-shared part of the file */
|
||||
f->name = H5MM_xfree(f->name);
|
||||
f->mtab.child = H5MM_xfree(f->mtab.child);
|
||||
f->mtab.nalloc = 0;
|
||||
H5FL_FREE(H5F_t,f);
|
||||
} else if (f && f->nrefs>0) {
|
||||
/*
|
||||
* There are other references to this file. Only decrement the
|
||||
* reference count.
|
||||
*/
|
||||
--f->nrefs;
|
||||
/* Destroy shared file struct */
|
||||
f->shared = H5FL_FREE(H5F_file_t,f->shared);
|
||||
|
||||
} else if (f->shared->nrefs>0) {
|
||||
/*
|
||||
* There are other references to the shared part of the file.
|
||||
* Only decrement the reference count.
|
||||
*/
|
||||
--f->shared->nrefs;
|
||||
}
|
||||
|
||||
done:
|
||||
/* Free the non-shared part of the file */
|
||||
f->name = H5MM_xfree(f->name);
|
||||
f->mtab.child = H5MM_xfree(f->mtab.child);
|
||||
f->mtab.nalloc = 0;
|
||||
H5FL_FREE(H5F_t,f);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
} /* end H5F_dest() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1836,8 +1811,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
} /* end if */
|
||||
|
||||
/* Is the file already open? */
|
||||
if ((file=H5I_search(H5I_FILE, H5F_equal, lf))!=NULL ||
|
||||
(file=H5I_search(H5I_FILE_CLOSING, H5F_equal, lf))!=NULL) {
|
||||
if ((shared = H5F_shared_search(lf)) != NULL) {
|
||||
/*
|
||||
* The file is already open, so use that one instead of the one we
|
||||
* just opened. We only one one H5FD_t* per file so one doesn't
|
||||
@ -1847,24 +1821,17 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
* exists), or if the new request adds write access (since the
|
||||
* readers don't expect the file to change under them).
|
||||
*/
|
||||
if(H5FD_close(lf)<0) {
|
||||
file = NULL; /*to prevent destruction of wrong file*/
|
||||
if(H5FD_close(lf)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info")
|
||||
} /* end if */
|
||||
if (flags & H5F_ACC_TRUNC) {
|
||||
file = NULL; /*to prevent destruction of wrong file*/
|
||||
if (flags & H5F_ACC_TRUNC)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open")
|
||||
}
|
||||
if (flags & H5F_ACC_EXCL) {
|
||||
file = NULL; /*to prevent destruction of wrong file*/
|
||||
if (flags & H5F_ACC_EXCL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists")
|
||||
}
|
||||
if ((flags & H5F_ACC_RDWR) && 0==(file->intent & H5F_ACC_RDWR)) {
|
||||
file = NULL; /*to prevent destruction of wrong file*/
|
||||
if ((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only")
|
||||
}
|
||||
|
||||
if ((file = H5F_new(file->shared, fcpl_id, fapl_id)) == NULL)
|
||||
/* Allocate new "high-level" file struct */
|
||||
if ((file = H5F_new(shared, fcpl_id, fapl_id)) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object")
|
||||
|
||||
lf = file->shared->lf;
|
||||
@ -2608,26 +2575,58 @@ H5F_close(H5F_t *f)
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_close)
|
||||
|
||||
assert(f->nrefs>0);
|
||||
/* Sanity check */
|
||||
HDassert(f);
|
||||
HDassert(f->file_id > 0); /* This routine should only be called when a file ID's ref count drops to zero */
|
||||
|
||||
/*
|
||||
* If this file is referenced more than once then just decrement the
|
||||
* count and return.
|
||||
*/
|
||||
if (f->nrefs>1) {
|
||||
/* Decrement reference counts */
|
||||
if (H5F_dest(f, H5AC_dxpl_id)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
|
||||
HGOTO_DONE(SUCCEED)
|
||||
} /* end if */
|
||||
/* Reset the file ID for this file */
|
||||
f->file_id = -1;
|
||||
|
||||
/* Double-check that this file should be closed */
|
||||
assert(1==f->nrefs);
|
||||
|
||||
/* if close degree if "semi" and there are objects left open and we are
|
||||
* holding open the file with this file ID, fail now */
|
||||
if(f->shared->fc_degree==H5F_CLOSE_SEMI && f->nopen_objs>0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open")
|
||||
/* Attempt to close the file/mount hierarchy */
|
||||
if(H5F_try_close(f) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_close() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_try_close
|
||||
*
|
||||
* Purpose: Attempts to close a file due to one of several actions:
|
||||
* - The reference count on the file ID dropped to zero
|
||||
* - The last open object was closed in the file
|
||||
* - The file was unmounted
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_try_close(H5F_t *f)
|
||||
{
|
||||
unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */
|
||||
unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_try_close)
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(f);
|
||||
|
||||
/* Check if this file is already in the process of closing */
|
||||
if(f->closing)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Get the number of open objects and open files on this file/mount hierarchy */
|
||||
if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy")
|
||||
|
||||
/*
|
||||
* Close file according to close degree:
|
||||
@ -2642,134 +2641,81 @@ H5F_close(H5F_t *f)
|
||||
switch(f->shared->fc_degree) {
|
||||
case H5F_CLOSE_WEAK:
|
||||
/*
|
||||
* If object headers are still open then delay deletion of
|
||||
* If file or object IDS are still open then delay deletion of
|
||||
* resources until they have all been closed. Flush all
|
||||
* caches and update the object eader anyway so that failing toi
|
||||
* close all objects isn't a major problem. If the file is on
|
||||
* the H5I_FILE list then move it to the H5I_FILE_CLOSING list
|
||||
* instead.
|
||||
* caches and update the object header anyway so that failing to
|
||||
* close all objects isn't a major problem.
|
||||
*/
|
||||
if (f->nopen_objs>0) {
|
||||
#ifdef H5F_DEBUG
|
||||
if (H5DEBUG(F)) {
|
||||
fprintf(H5DEBUG(F), "H5F: H5F_close(%s): %u object header%s still "
|
||||
"open (file close will complete when %s closed)\n",
|
||||
f->name,
|
||||
f->nopen_objs,
|
||||
1 == f->nopen_objs?" is":"s are",
|
||||
1 == f->nopen_objs?"that header is":"those headers are");
|
||||
}
|
||||
#endif
|
||||
/* If the only open objects are the groups that are mount points, */
|
||||
/* allow the file to close and shut things down */
|
||||
if(f->nopen_objs == f->mtab.nmounts) {
|
||||
unsigned u; /* Local index variable */
|
||||
hbool_t really_close; /* Whether to delay the file close by going to a "closing" state */
|
||||
|
||||
/* Check for open groups on mount points */
|
||||
really_close = TRUE;
|
||||
for(u = 0; u < f->mtab.nmounts; u++) {
|
||||
if(H5G_get_shared_count(f->mtab.child[u].group) > 1) {
|
||||
really_close = FALSE;
|
||||
break;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
|
||||
/* If we really want to close this file now */
|
||||
if(really_close)
|
||||
break;
|
||||
} /* end if */
|
||||
|
||||
/* Register an ID for closing the file later */
|
||||
if (!f->closing)
|
||||
f->closing = H5I_register(H5I_FILE_CLOSING, f);
|
||||
|
||||
/* Invalidate file ID */
|
||||
f->file_id = -1;
|
||||
|
||||
if ((nopen_files + nopen_objs) > 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
} else {
|
||||
if (f->closing) {
|
||||
|
||||
#ifdef H5F_DEBUG
|
||||
if (H5DEBUG(F))
|
||||
fprintf(H5DEBUG(F), "H5F: H5F_close: operation completing\n");
|
||||
#endif
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
break;
|
||||
|
||||
case H5F_CLOSE_SEMI:
|
||||
/* Can leave safely if file IDs are still open on this file */
|
||||
if (nopen_files > 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Sanity check: If close degree if "semi" and we have gotten this
|
||||
* far and there are objects left open, bail out now */
|
||||
HDassert(nopen_files == 0 && nopen_objs == 0);
|
||||
|
||||
/* If we've gotten this far (ie. there are no open objects in the file), fall through to flush & close */
|
||||
break;
|
||||
|
||||
case H5F_CLOSE_STRONG:
|
||||
/* Force to close all opened objects in file */
|
||||
while(f->nopen_objs > 0) {
|
||||
int obj_count; /* # of open objects */
|
||||
hid_t objs[128]; /* Array of objects to close */
|
||||
int i; /* Local index variable */
|
||||
/* If there are other open files in the hierarchy, we can leave now */
|
||||
if(nopen_files > 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Get the list of IDs of open dataset objects */
|
||||
while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
|
||||
|
||||
/* Try to close all the open objects */
|
||||
for(i=0; i<obj_count; i++)
|
||||
if(H5I_dec_ref(objs[i]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
|
||||
/* Get the list of IDs of open group objects */
|
||||
while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_GROUP, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
|
||||
|
||||
/* Try to close all the open objects */
|
||||
for(i=0; i<obj_count; i++)
|
||||
if(H5I_dec_ref(objs[i]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
|
||||
/* Get the list of IDs of open named datatype objects */
|
||||
while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
|
||||
|
||||
/* Try to close all the open objects */
|
||||
for(i=0; i<obj_count; i++)
|
||||
if(H5I_dec_ref(objs[i]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
|
||||
/* Get the list of IDs of open attribute objects */
|
||||
while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
|
||||
|
||||
/* Try to close all the open objects */
|
||||
for(i=0; i<obj_count; i++)
|
||||
if(H5I_dec_ref(objs[i]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
} /* end while */
|
||||
/* If we've gotten this far (ie. there are no open file IDs in the file/mount hierarchy), fall through to flush & close */
|
||||
break;
|
||||
|
||||
default:
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree")
|
||||
} /* end switch */
|
||||
|
||||
/*
|
||||
* Unmount and close each child before closing the current file.
|
||||
/* Mark this file as closing (prevents re-entering file shutdown code below) */
|
||||
f->closing = TRUE;
|
||||
|
||||
/* If the file close degree is "strong", close all the open objects in this file */
|
||||
if(f->shared->fc_degree == H5F_CLOSE_STRONG) {
|
||||
HDassert(nopen_files == 0);
|
||||
|
||||
/* Forced close of all opened objects in this file */
|
||||
if(f->nopen_objs > 0) {
|
||||
unsigned obj_count; /* # of open objects */
|
||||
hid_t objs[128]; /* Array of objects to close */
|
||||
unsigned u; /* Local index variable */
|
||||
|
||||
/* Get the list of IDs of open dataset, group, named datatype & attribute objects */
|
||||
while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) {
|
||||
|
||||
/* Try to close all the open objects in this file */
|
||||
for(u = 0; u < obj_count; u++)
|
||||
if(H5I_dec_ref(objs[u]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
|
||||
} /* end while */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Check if this is a child file in a mounting hierarchy & proceed up the
|
||||
* hierarchy if so.
|
||||
*/
|
||||
assert(NULL==f->mtab.parent);
|
||||
if(f->mtab.parent)
|
||||
if(H5F_try_close(f->mtab.parent) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file")
|
||||
|
||||
/* Unmount and close each child before closing the current file. */
|
||||
if(H5F_close_mounts(f) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child file")
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files")
|
||||
|
||||
/* Invalidate file ID */
|
||||
f->file_id = -1;
|
||||
|
||||
/* Flush at this point since the file will be closed */
|
||||
|
||||
/* Dump debugging info */
|
||||
#if H5AC_DUMP_STATS_ON_CLOSE
|
||||
/* Dump debugging info */
|
||||
H5AC_stats(f);
|
||||
#endif /* H5AC_DUMP_STATS_ON_CLOSE */
|
||||
|
||||
/* Only try to flush the file if it was opened with write access */
|
||||
/* Flush at this point since the file will be closed */
|
||||
/* (Only try to flush the file if it was opened with write access) */
|
||||
if(f->intent&H5F_ACC_RDWR) {
|
||||
#ifdef H5_HAVE_FPHDF5
|
||||
/*
|
||||
@ -2803,12 +2749,12 @@ H5F_close(H5F_t *f)
|
||||
* shared H5F_file_t struct. If the reference count for the H5F_file_t
|
||||
* struct reaches zero then destroy it also.
|
||||
*/
|
||||
if (H5F_dest(f,H5AC_dxpl_id)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
|
||||
if (H5F_dest(f, H5AC_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_close() */
|
||||
} /* end H5F_try_close() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -2835,14 +2781,42 @@ done:
|
||||
herr_t
|
||||
H5Fclose(hid_t file_id)
|
||||
{
|
||||
H5F_t *f;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_API(H5Fclose, FAIL)
|
||||
H5TRACE1("e","i",file_id);
|
||||
|
||||
/* Check/fix arguments. */
|
||||
if (NULL==H5I_object_verify(file_id,H5I_FILE))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file atom")
|
||||
if (NULL == (f = H5I_object_verify(file_id,H5I_FILE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID")
|
||||
|
||||
/* Perform checks for "semi" file close degree here, since closing the
|
||||
* file ID will mess things up if we need to return FAIL */
|
||||
if(f->shared->fc_degree == H5F_CLOSE_SEMI) {
|
||||
int ref_count; /* Reference count for file's ID */
|
||||
|
||||
/* Get the reference count for this ID */
|
||||
if((ref_count = H5I_get_ref(file_id)) < 0)
|
||||
HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count")
|
||||
|
||||
/* If we will be decrementing the reference count to zero, check for objects open */
|
||||
if(ref_count == 1) {
|
||||
unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */
|
||||
unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */
|
||||
|
||||
/* Get the number of open objects and open files on this file/mount hierarchy */
|
||||
if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy")
|
||||
|
||||
/* If there are no other file IDs open on this file/mount hier., but
|
||||
* there are still open objects, issue an error and bail out now,
|
||||
* before decrementing the file ID's reference count and triggering
|
||||
* a "real" attempt at closing the file */
|
||||
if(nopen_files == 1 && nopen_objs > 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/*
|
||||
* Decrement reference count on atom. When it reaches zero the file will
|
||||
@ -2898,6 +2872,9 @@ H5Freopen(hid_t file_id)
|
||||
/* Keep old file's read/write intent in new file */
|
||||
new_file->intent=old_file->intent;
|
||||
|
||||
/* Duplicate old file's name */
|
||||
new_file->name = H5MM_xstrdup(old_file->name);
|
||||
|
||||
if ((ret_value=H5I_register(H5I_FILE, new_file))<0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
|
||||
|
||||
@ -2906,7 +2883,7 @@ H5Freopen(hid_t file_id)
|
||||
|
||||
done:
|
||||
if (ret_value<0 && new_file)
|
||||
if(H5F_close(new_file)<0)
|
||||
if(H5F_dest(new_file, H5AC_dxpl_id)<0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file")
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
}
|
||||
@ -3292,15 +3269,9 @@ H5F_get_id(H5F_t *file)
|
||||
assert(file);
|
||||
|
||||
if(file->file_id == -1) {
|
||||
if(H5I_remove(file->closing)==NULL)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_READERROR, FAIL, "unable to remove from closing list")
|
||||
|
||||
/* Get an atom for the file */
|
||||
if ((file->file_id = H5I_register(H5I_FILE, file))<0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file")
|
||||
|
||||
/* Indicate file is not closing */
|
||||
file->closing = 0;
|
||||
} else {
|
||||
/* Increment reference count on atom. */
|
||||
if (H5I_inc_ref(file->file_id)<0)
|
||||
@ -4154,21 +4125,33 @@ done:
|
||||
ssize_t
|
||||
H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
|
||||
{
|
||||
H5G_entry_t *ent; /*symbol table entry */
|
||||
H5G_entry_t *ent; /*symbol table entry */
|
||||
H5F_t *f; /* Top file in mount hierarchy */
|
||||
size_t len=0;
|
||||
ssize_t ret_value;
|
||||
|
||||
FUNC_ENTER_API (H5Fget_name, FAIL)
|
||||
H5TRACE3("Zs","ixz",obj_id,name,size);
|
||||
|
||||
/* get symbol table entry */
|
||||
if((ent = H5G_loc(obj_id))==NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID")
|
||||
/* For file IDs, get the file object directly */
|
||||
/* (This prevents the H5G_loc() call from returning the file pointer for
|
||||
* the top file in a mount hierarchy)
|
||||
*/
|
||||
if(H5I_get_type(obj_id) == H5I_FILE ) {
|
||||
if (NULL==(f=H5I_object(obj_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Get symbol table entry */
|
||||
if((ent = H5G_loc(obj_id))==NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID")
|
||||
f = ent->file;
|
||||
} /* end else */
|
||||
|
||||
len = HDstrlen(ent->file->name);
|
||||
len = HDstrlen(f->name);
|
||||
|
||||
if(name) {
|
||||
HDstrncpy(name, ent->file->name, MIN(len+1,size));
|
||||
HDstrncpy(name, f->name, MIN(len+1,size));
|
||||
if(len >= size)
|
||||
name[size-1]='\0';
|
||||
} /* end if */
|
||||
@ -4179,3 +4162,143 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Fget_name() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_shared_add
|
||||
*
|
||||
* Purpose: Add a "shared" file struct to the list of open files
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Monday, July 18, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_shared_add(H5F_file_t *shared)
|
||||
{
|
||||
H5F_sfile_node_t *new; /* New shared file node */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_shared_add)
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(shared);
|
||||
|
||||
/* Allocate new shared file node */
|
||||
if (NULL == (new = H5FL_CALLOC(H5F_sfile_node_t)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
|
||||
/* Set shared file value */
|
||||
new->shared = shared;
|
||||
|
||||
/* Prepend to list of shared files open */
|
||||
new->next = H5F_sfile_head_g;
|
||||
H5F_sfile_head_g = new;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_shared_add() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_shared_search
|
||||
*
|
||||
* Purpose: Search for a "shared" file with low-level file info that
|
||||
* matches
|
||||
*
|
||||
* Return: Non-NULL on success / NULL on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Monday, July 18, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5F_file_t *
|
||||
H5F_shared_search(H5FD_t *lf)
|
||||
{
|
||||
H5F_sfile_node_t *curr; /* Current shared file node */
|
||||
H5F_file_t *ret_value = NULL; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_shared_search)
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(lf);
|
||||
|
||||
/* Iterate through low-level files for matching low-level file info */
|
||||
curr = H5F_sfile_head_g;
|
||||
while(curr) {
|
||||
/* Check for match */
|
||||
if(0==H5FD_cmp(curr->shared->lf, lf))
|
||||
HGOTO_DONE(curr->shared)
|
||||
|
||||
/* Advance to next shared file node */
|
||||
curr = curr->next;
|
||||
} /* end while */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_shared_search() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_shared_remove
|
||||
*
|
||||
* Purpose: Remove a "shared" file struct from the list of open files
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Monday, July 18, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_shared_remove(H5F_file_t *shared)
|
||||
{
|
||||
H5F_sfile_node_t *curr; /* Current shared file node */
|
||||
H5F_sfile_node_t *last; /* Last shared file node */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_shared_remove)
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(shared);
|
||||
|
||||
/* Locate shared file node with correct shared file */
|
||||
last = NULL;
|
||||
curr = H5F_sfile_head_g;
|
||||
while(curr && curr->shared != shared) {
|
||||
/* Advance to next node */
|
||||
last = curr;
|
||||
curr = curr->next;
|
||||
} /* end while */
|
||||
|
||||
/* Indicate error if the node wasn't found */
|
||||
if(curr == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOTFOUND, FAIL, "can't find shared file info")
|
||||
|
||||
/* Remove node found from list */
|
||||
if(last != NULL)
|
||||
/* Removing middle or tail node in list */
|
||||
last->next = curr->next;
|
||||
else
|
||||
/* Removing head node in list */
|
||||
H5F_sfile_head_g = curr->next;
|
||||
|
||||
/* Release the shared file node struct */
|
||||
/* (the shared file info itself is freed elsewhere) */
|
||||
H5FL_FREE(H5F_sfile_node_t, curr);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_shared_remove() */
|
||||
|
||||
|
180
src/H5Fmount.c
180
src/H5Fmount.c
@ -86,7 +86,7 @@ H5F_close_mounts(H5F_t *f)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close child group")
|
||||
|
||||
/* Close the child file */
|
||||
if(H5F_close(f->mtab.child[u].file) < 0)
|
||||
if(H5F_try_close(f->mtab.child[u].file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file")
|
||||
} /* end if */
|
||||
f->mtab.nmounts = 0;
|
||||
@ -95,46 +95,6 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_close_mounts() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_term_unmount_cb
|
||||
*
|
||||
* Purpose: H5F_term_interface' callback function. This routine
|
||||
* unmounts child files from files that are in the "closing"
|
||||
* state.
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, Jun 30, 2005
|
||||
*
|
||||
* Modification:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void UNUSED *key)
|
||||
{
|
||||
H5F_t *f = (H5F_t *)obj_ptr; /* Alias for search info */
|
||||
int ret_value = FALSE; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5F_term_unmount_cb)
|
||||
|
||||
assert(f);
|
||||
|
||||
if(f->mtab.nmounts) {
|
||||
/* Unmount all child files */
|
||||
if(H5F_close_mounts(f) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child file")
|
||||
|
||||
/* Decrement reference count for file */
|
||||
H5I_dec_ref(obj_id);
|
||||
} /* end if */
|
||||
else
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "no files to unmount")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* end H5F_term_unmount_cb() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_mount
|
||||
@ -181,7 +141,8 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
|
||||
assert(TRUE==H5P_isa_class(plist_id,H5P_MOUNT));
|
||||
|
||||
/*
|
||||
* Check that the child isn't mounted, that the mount point exists, and
|
||||
* Check that the child isn't mounted, that the mount point exists, that
|
||||
* the parent & child files have the same file close degree, and
|
||||
* that the mount wouldn't introduce a cycle in the mount tree.
|
||||
*/
|
||||
if (child->mtab.parent)
|
||||
@ -197,6 +158,9 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
|
||||
if (ancestor==child)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle")
|
||||
}
|
||||
|
||||
if(parent->shared->fc_degree != child->shared->fc_degree)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mounted file has different file close degree than parent")
|
||||
|
||||
/*
|
||||
* Use a binary search to locate the position that the child should be
|
||||
@ -239,7 +203,10 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
|
||||
parent->mtab.child[md].group = mount_point;
|
||||
parent->mtab.child[md].file = child;
|
||||
child->mtab.parent = parent;
|
||||
child->nrefs++;
|
||||
|
||||
/* Set the group's mountpoint flag */
|
||||
if(H5G_mount(parent->mtab.child[md].group)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to set group mounted flag")
|
||||
|
||||
/* Search the open IDs and replace names for mount operation */
|
||||
/* We pass H5G_UNKNOWN as object type; search all IDs */
|
||||
@ -317,8 +284,7 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
|
||||
mnt_ent = H5G_entof(mounted);
|
||||
ent = H5G_entof(child->shared->root_grp);
|
||||
|
||||
if (child->mtab.parent &&
|
||||
H5F_addr_eq(mnt_ent->header, ent->header)) {
|
||||
if (child->mtab.parent && H5F_addr_eq(mnt_ent->header, ent->header)) {
|
||||
/*
|
||||
* We've been given the root group of the child. We do a reverse
|
||||
* lookup in the parent's mount table to find the correct entry.
|
||||
@ -332,18 +298,21 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
|
||||
|
||||
/* Unmount the child */
|
||||
parent->mtab.nmounts -= 1;
|
||||
if(H5G_unmount(parent->mtab.child[md].group)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag")
|
||||
if(H5G_close(parent->mtab.child[i].group)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group")
|
||||
child->mtab.parent = NULL;
|
||||
if(H5F_close(child)<0)
|
||||
if(H5F_try_close(child)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file")
|
||||
|
||||
/* Eliminate the mount point from the table */
|
||||
HDmemmove(parent->mtab.child+i, parent->mtab.child+i+1,
|
||||
(parent->mtab.nmounts-i)* sizeof(parent->mtab.child[0]));
|
||||
ret_value = SUCCEED;
|
||||
}
|
||||
}
|
||||
assert(ret_value>=0);
|
||||
|
||||
HDassert(ret_value>=0);
|
||||
} else {
|
||||
/*
|
||||
* We've been given the mount point in the parent. We use a binary
|
||||
@ -368,11 +337,15 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
|
||||
|
||||
/* Unmount the child */
|
||||
parent->mtab.nmounts -= 1;
|
||||
if(H5G_unmount(parent->mtab.child[md].group)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag")
|
||||
if(H5G_close(parent->mtab.child[md].group)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group")
|
||||
parent->mtab.child[md].file->mtab.parent = NULL;
|
||||
if(H5F_close(parent->mtab.child[md].file)<0)
|
||||
if(H5F_try_close(parent->mtab.child[md].file)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file")
|
||||
|
||||
/* Eliminate the mount point from the table */
|
||||
HDmemmove(parent->mtab.child+md, parent->mtab.child+md+1,
|
||||
(parent->mtab.nmounts-md)*sizeof(parent->mtab.child[0]));
|
||||
ret_value = SUCCEED;
|
||||
@ -621,100 +594,89 @@ done:
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_check_mounts_recurse
|
||||
* Function: H5F_mount_count_ids_recurse
|
||||
*
|
||||
* Purpose: Helper routine for checking for file mounting hierarchies to
|
||||
* close.
|
||||
* Purpose: Helper routine for counting number of open IDs in mount
|
||||
* hierarchy.
|
||||
*
|
||||
* Return: TRUE if entire hierarchy can be closed / FALSE otherwise
|
||||
* Return: <none>
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Saturday, July 2, 2005
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static hbool_t
|
||||
H5F_check_mounts_recurse(H5F_t *f)
|
||||
static void
|
||||
H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs)
|
||||
{
|
||||
hbool_t ret_value = FALSE; /* Return value */
|
||||
unsigned u; /* Local index value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_check_mounts_recurse)
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_mount_count_ids_recurse)
|
||||
|
||||
/* Check if this file is closing and if the only objects left open are
|
||||
* the mount points */
|
||||
if((f->closing || (f->nrefs == 1 && f->mtab.parent)) && f->nopen_objs == f->mtab.nmounts) {
|
||||
unsigned u;
|
||||
/* Sanity check */
|
||||
HDassert(f);
|
||||
HDassert(nopen_files);
|
||||
HDassert(nopen_objs);
|
||||
|
||||
/* Iterate over files mounted in this file and check if all can be closed */
|
||||
for(u = 0; u < f->mtab.nmounts; u++) {
|
||||
if(H5G_get_shared_count(f->mtab.child[u].group) > 1
|
||||
|| !H5F_check_mounts_recurse(f->mtab.child[u].file))
|
||||
HGOTO_DONE(FALSE)
|
||||
} /* end for */
|
||||
/* If this file is still open, increment number of file IDs open */
|
||||
if(f->file_id > 0)
|
||||
*nopen_files += 1;
|
||||
|
||||
/* Set return value */
|
||||
ret_value = TRUE;
|
||||
} /* end if */
|
||||
/* Increment number of open objects in file
|
||||
* (Reduced by number of mounted files, we'll add back in the mount point's
|
||||
* groups later, if they are open)
|
||||
*/
|
||||
*nopen_objs += (f->nopen_objs - f->mtab.nmounts);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_check_mounts_recurse() */
|
||||
/* Iterate over files mounted in this file and add in their open ID counts also */
|
||||
for(u = 0; u < f->mtab.nmounts; u++) {
|
||||
/* Increment the open object count if the mount point group has an open ID */
|
||||
if(H5G_get_shared_count(f->mtab.child[u].group) > 1)
|
||||
*nopen_objs += 1;
|
||||
|
||||
H5F_mount_count_ids_recurse(f->mtab.child[u].file, nopen_files, nopen_objs);
|
||||
} /* end for */
|
||||
|
||||
FUNC_LEAVE_NOAPI_VOID
|
||||
} /* end H5F_mount_count_ids_recurse() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_check_mounts
|
||||
* Function: H5F_mount_count_ids
|
||||
*
|
||||
* Purpose: Check for file mounting hierarchies that have been created
|
||||
* and that now are composed completely of files that are closing
|
||||
* and have no more open objects in them.
|
||||
* Purpose: Count the number of open file & object IDs in a mount hierarchy
|
||||
*
|
||||
* When such a mounting hierarchy is detected, unmount and close
|
||||
* all the files involved.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Saturday, July 2, 2005
|
||||
* Tues, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_check_mounts(H5F_t *f)
|
||||
H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs)
|
||||
{
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5F_check_mounts, FAIL)
|
||||
FUNC_ENTER_NOAPI(H5F_mount_count_ids, FAIL)
|
||||
|
||||
/* Only try to close files for files involved in a mounting hierarchy */
|
||||
if(f->mtab.parent || f->mtab.nmounts) {
|
||||
H5F_t *top = f; /* Pointer to the top file in the hierarchy */
|
||||
/* Sanity check */
|
||||
HDassert(f);
|
||||
HDassert(nopen_files);
|
||||
HDassert(nopen_objs);
|
||||
|
||||
/* Find the top file in the mounting hierarchy */
|
||||
while(top->mtab.parent) {
|
||||
/* Get out early if we detect that this hierarchy won't close */
|
||||
if(top->nopen_objs != top->mtab.nmounts || !top->closing)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
/* Find the top file in the mounting hierarchy */
|
||||
while(f->mtab.parent)
|
||||
f = f->mtab.parent;
|
||||
|
||||
/* Advance toward the top of the hierarchy */
|
||||
top = top->mtab.parent;
|
||||
} /* end while */
|
||||
|
||||
/* Check for closing the hierarchy */
|
||||
if(H5F_check_mounts_recurse(top)) {
|
||||
/* Unmount all child files */
|
||||
if(H5F_close_mounts(top) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child file")
|
||||
|
||||
if(H5I_dec_ref(top->closing) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't decrement file closing ID")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
/* Count open IDs in the hierarchy */
|
||||
H5F_mount_count_ids_recurse(f, nopen_files, nopen_objs);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_check_mounts() */
|
||||
} /* end H5F_mount_count_ids() */
|
||||
|
||||
|
@ -93,7 +93,7 @@ typedef struct H5F_file_t {
|
||||
haddr_t freespace_addr; /* Relative address of free-space info */
|
||||
haddr_t driver_addr; /* File driver information block address*/
|
||||
hbool_t fam_to_sec2; /* Is h5repart changing driver from family to sec2 */
|
||||
|
||||
|
||||
unsigned super_chksum; /* Superblock checksum */
|
||||
unsigned drvr_chksum; /* Driver info block checksum */
|
||||
H5AC_t *cache; /* The object cache */
|
||||
@ -144,13 +144,12 @@ typedef struct H5F_mtab_t {
|
||||
* indicate that the file is mounted on some other file).
|
||||
*/
|
||||
struct H5F_t {
|
||||
unsigned nrefs; /* Reference count */
|
||||
unsigned intent; /* The flags passed to H5F_open()*/
|
||||
char *name; /* Name used to open file */
|
||||
H5F_file_t *shared; /* The shared file info */
|
||||
unsigned nopen_objs; /* Number of open object headers*/
|
||||
hid_t file_id; /* ID of this file */
|
||||
hid_t closing; /* H5I_FILE_CLOSING ID or zero */
|
||||
hbool_t closing; /* File is in the process of being closed */
|
||||
H5F_mtab_t mtab; /* File mount table */
|
||||
};
|
||||
|
||||
@ -165,14 +164,14 @@ H5_DLL void H5F_encode_length_unusual(const H5F_t *f, uint8_t **p, uint8_t *l);
|
||||
#endif /* NOT_YET */
|
||||
|
||||
/* General routines */
|
||||
H5_DLL herr_t H5F_close(H5F_t *f);
|
||||
H5_DLL herr_t H5F_try_close(H5F_t *f);
|
||||
H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id);
|
||||
|
||||
/* File mount related routines */
|
||||
H5_DLL herr_t H5F_mountpoint(struct H5G_entry_t *find/*in,out*/);
|
||||
H5_DLL herr_t H5F_close_mounts(H5F_t *f);
|
||||
H5_DLL int H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void *key);
|
||||
H5_DLL herr_t H5F_check_mounts(H5F_t *f);
|
||||
H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs);
|
||||
|
||||
/* Superblock related routines */
|
||||
H5_DLL hsize_t H5F_init_superblock(const H5F_t *f, hid_t dxpl_id);
|
||||
|
@ -438,8 +438,8 @@ H5_DLL hid_t H5F_get_access_plist(H5F_t *f);
|
||||
H5_DLL unsigned H5F_get_intent(const H5F_t *f);
|
||||
H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum);
|
||||
H5_DLL hid_t H5F_get_id(H5F_t *file);
|
||||
H5_DLL int H5F_get_obj_count(const H5F_t *f, unsigned types);
|
||||
H5_DLL int H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
|
||||
H5_DLL unsigned H5F_get_obj_count(const H5F_t *f, unsigned types);
|
||||
H5_DLL unsigned H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
|
||||
H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
|
||||
H5_DLL haddr_t H5F_get_eoa(const H5F_t *f);
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
|
88
src/H5G.c
88
src/H5G.c
@ -2091,7 +2091,8 @@ H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")
|
||||
}
|
||||
|
||||
grp->shared->fo_count =1;
|
||||
/* Set open object count */
|
||||
grp->shared->fo_count = 1;
|
||||
}
|
||||
else {
|
||||
if(NULL == (grp = H5FL_CALLOC(H5G_t)))
|
||||
@ -2101,7 +2102,10 @@ H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
|
||||
if(H5G_ent_copy(&(grp->ent), ent, H5G_COPY_SHALLOW)<0)
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTCOPY, NULL, "can't copy group entry")
|
||||
|
||||
grp->shared=shared_fo;
|
||||
/* Point to shared group info */
|
||||
grp->shared = shared_fo;
|
||||
|
||||
/* Increment shared reference count */
|
||||
shared_fo->fo_count++;
|
||||
}
|
||||
|
||||
@ -2254,11 +2258,14 @@ H5G_close(H5G_t *grp)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close");
|
||||
H5FL_FREE (H5G_shared_t, grp->shared);
|
||||
} else {
|
||||
/* Check if this group was the last object holding open a mounted file
|
||||
* hierarchy and close down the file hierarchy if so */
|
||||
if(grp->shared->fo_count == 1)
|
||||
if(H5F_check_mounts(grp->ent.file) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy");
|
||||
/* If this group is a mount point and the mount point is the last open
|
||||
* reference to the group, then attempt to close down the file hierarchy
|
||||
*/
|
||||
if(grp->shared->mounted && grp->shared->fo_count == 1) {
|
||||
/* Attempt to close down the file hierarchy */
|
||||
if(H5F_try_close(grp->ent.file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
|
||||
} /* end if */
|
||||
|
||||
if(H5G_free_ent_name(&(grp->ent))<0)
|
||||
{
|
||||
@ -2271,7 +2278,7 @@ H5G_close(H5G_t *grp)
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
}
|
||||
} /* end H5G_close() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -2547,6 +2554,9 @@ H5G_loc (hid_t loc_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry for root group");
|
||||
|
||||
/* Patch up root group's symbol table entry to reflect this file */
|
||||
/* (Since the root group info is only stored once for files which
|
||||
* share an underlying low-level file)
|
||||
*/
|
||||
/* (but only for non-mounted files) */
|
||||
if(!f->mtab.parent)
|
||||
ret_value->file = f;
|
||||
@ -4121,8 +4131,68 @@ H5G_get_shared_count(H5G_t *grp)
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_get_shared_count);
|
||||
|
||||
/* Check args */
|
||||
assert(grp && grp->shared);
|
||||
HDassert(grp && grp->shared);
|
||||
|
||||
FUNC_LEAVE_NOAPI(grp->shared->fo_count);
|
||||
} /* end H5G_get_shared_count() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_mount
|
||||
*
|
||||
* Purpose: Sets the 'mounted' flag for a group
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5G_mount(H5G_t *grp)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_mount);
|
||||
|
||||
/* Check args */
|
||||
HDassert(grp && grp->shared);
|
||||
HDassert(grp->shared->mounted == FALSE);
|
||||
|
||||
/* Set the 'mounted' flag */
|
||||
grp->shared->mounted = TRUE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||||
} /* end H5G_mount() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_unmount
|
||||
*
|
||||
* Purpose: Resets the 'mounted' flag for a group
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5G_unmount(H5G_t *grp)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_unmount);
|
||||
|
||||
/* Check args */
|
||||
HDassert(grp && grp->shared);
|
||||
HDassert(grp->shared->mounted == TRUE);
|
||||
|
||||
/* Reset the 'mounted' flag */
|
||||
grp->shared->mounted = FALSE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||||
} /* end H5G_unmount() */
|
||||
|
||||
|
@ -47,10 +47,11 @@ typedef struct H5G_node_t {
|
||||
} H5G_node_t;
|
||||
|
||||
/*
|
||||
* Reference count shared between all instances of an open group
|
||||
* Shared information for all open group objects
|
||||
*/
|
||||
struct H5G_shared_t {
|
||||
int fo_count; /* open file object count */
|
||||
hbool_t mounted; /* Group is mount point */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -167,6 +167,8 @@ H5_DLL herr_t H5G_replace_name(H5G_obj_t type, H5G_entry_t *loc,
|
||||
H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op);
|
||||
H5_DLL herr_t H5G_free_grp_name(H5G_t *grp);
|
||||
H5_DLL herr_t H5G_get_shared_count(H5G_t *grp);
|
||||
H5_DLL herr_t H5G_mount(H5G_t *grp);
|
||||
H5_DLL herr_t H5G_unmount(H5G_t *grp);
|
||||
|
||||
/*
|
||||
* These functions operate on symbol table nodes.
|
||||
|
51
src/H5I.c
51
src/H5I.c
@ -125,7 +125,6 @@ H5FL_DEFINE_STATIC(H5I_id_info_t);
|
||||
/*--------------------- Local function prototypes ---------------------------*/
|
||||
static H5I_id_info_t *H5I_find_id(hid_t id);
|
||||
static hid_t H5I_get_file_id(hid_t obj_id);
|
||||
static int H5I_get_ref(hid_t id);
|
||||
#ifdef H5I_DEBUG_OUTPUT
|
||||
static herr_t H5I_debug(H5I_type_t type);
|
||||
#endif /* H5I_DEBUG_OUTPUT */
|
||||
@ -483,9 +482,6 @@ int
|
||||
H5I_nmembers(H5I_type_t type)
|
||||
{
|
||||
H5I_id_type_t *type_ptr = NULL;
|
||||
H5I_id_info_t *cur=NULL;
|
||||
int n=0;
|
||||
unsigned i;
|
||||
int ret_value;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5I_nmembers, FAIL);
|
||||
@ -495,12 +491,8 @@ H5I_nmembers(H5I_type_t type)
|
||||
if (NULL==(type_ptr=H5I_id_type_list_g[type]) || type_ptr->count<=0)
|
||||
HGOTO_DONE(0);
|
||||
|
||||
for (i=0; i<type_ptr->hash_size; i++)
|
||||
for (cur=type_ptr->id_list[i]; cur; cur=cur->next)
|
||||
n++;
|
||||
|
||||
/* Set return value */
|
||||
ret_value=n;
|
||||
H5_ASSIGN_OVERFLOW(ret_value, type_ptr->ids, unsigned, int);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
@ -971,18 +963,14 @@ void *H5Iobject_verify(hid_t id, H5I_type_t id_type)
|
||||
FUNC_ENTER_API(H5Iobject_verify, NULL);
|
||||
|
||||
if( H5I_IS_LIB_TYPE( id_type ) )
|
||||
{
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
|
||||
}
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
|
||||
|
||||
if(id_type < 1 || id_type >= H5I_next_type)
|
||||
{
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type");
|
||||
}
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type")
|
||||
|
||||
ret_value = H5I_object_verify(id, id_type);
|
||||
|
||||
done:
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value);
|
||||
}
|
||||
|
||||
@ -1127,9 +1115,7 @@ void *H5Iremove_verify(hid_t id, H5I_type_t id_type)
|
||||
FUNC_ENTER_API(H5Iremove_verify, NULL);
|
||||
|
||||
if( H5I_IS_LIB_TYPE( id_type ) )
|
||||
{
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
|
||||
}
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
|
||||
|
||||
/* Remove the id */
|
||||
ret_value = H5I_remove_verify(id, id_type);
|
||||
@ -1516,7 +1502,7 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
int
|
||||
H5I_get_ref(hid_t id)
|
||||
{
|
||||
H5I_type_t type; /*type the object is in*/
|
||||
@ -1906,20 +1892,23 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
|
||||
if (type_ptr == NULL || type_ptr->count <= 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
|
||||
|
||||
/* Start at the beginning of the array */
|
||||
for (i=0; i<type_ptr->hash_size; i++) {
|
||||
id_ptr = type_ptr->id_list[i];
|
||||
while (id_ptr) {
|
||||
next_id= id_ptr->next; /* Protect against ID being deleted in callback */
|
||||
if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
|
||||
HGOTO_DONE(id_ptr->obj_ptr); /*found the item*/
|
||||
id_ptr = next_id;
|
||||
}
|
||||
}
|
||||
/* Only iterate through hash table if there are IDs in group */
|
||||
if(type_ptr->ids > 0) {
|
||||
/* Start at the beginning of the array */
|
||||
for (i=0; i<type_ptr->hash_size; i++) {
|
||||
id_ptr = type_ptr->id_list[i];
|
||||
while (id_ptr) {
|
||||
next_id= id_ptr->next; /* Protect against ID being deleted in callback */
|
||||
if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
|
||||
HGOTO_DONE(id_ptr->obj_ptr); /*found the item*/
|
||||
id_ptr = next_id;
|
||||
} /* end while */
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
}
|
||||
} /* end H5I_search() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -60,6 +60,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id);
|
||||
H5_DLL void *H5I_remove(hid_t id);
|
||||
H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
|
||||
H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key);
|
||||
H5_DLL int H5I_get_ref(hid_t id);
|
||||
H5_DLL int H5I_inc_ref(hid_t id);
|
||||
H5_DLL int H5I_dec_ref(hid_t id);
|
||||
H5_DLL int H5I_inc_type_ref(H5I_type_t type);
|
||||
|
@ -36,7 +36,6 @@ typedef enum H5I_type_t {
|
||||
H5I_UNINIT = (-2), /*uninitialized type */
|
||||
H5I_BADID = (-1), /*invalid Type */
|
||||
H5I_FILE = 1, /*type ID for File objects */
|
||||
H5I_FILE_CLOSING, /*files pending close due to open objhdrs */
|
||||
H5I_GROUP, /*type ID for Group objects */
|
||||
H5I_DATATYPE, /*type ID for Datatype objects */
|
||||
H5I_DATASPACE, /*type ID for Dataspace objects */
|
||||
|
34
src/H5O.c
34
src/H5O.c
@ -412,7 +412,7 @@ H5O_close(H5G_entry_t *obj_ent)
|
||||
|
||||
#ifdef H5O_DEBUG
|
||||
if (H5DEBUG(O)) {
|
||||
if (obj_ent->file->closing && 1==obj_ent->file->shared->nrefs) {
|
||||
if (obj_ent->file->file_id < 0 && 1==obj_ent->file->shared->nrefs) {
|
||||
HDfprintf(H5DEBUG(O), "< %a auto %lu remaining\n",
|
||||
obj_ent->header,
|
||||
(unsigned long)(obj_ent->file->nopen_objs));
|
||||
@ -423,28 +423,13 @@ H5O_close(H5G_entry_t *obj_ent)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the file open-lock count has reached the number of open mount points
|
||||
* (each of which has a group open in the file) and the file has a close
|
||||
* pending then close the file and remove it from the H5I_FILE_CLOSING ID
|
||||
* group.
|
||||
* If the file open object count has reached the number of open mount points
|
||||
* (each of which has a group open in the file) attempt to close the file.
|
||||
*/
|
||||
/* Check for just mount points holding file open */
|
||||
if(obj_ent->file->mtab.nmounts == obj_ent->file->nopen_objs && obj_ent->file->closing) {
|
||||
unsigned u; /* Local index variable */
|
||||
hbool_t really_close; /* Whether to delay the file close by going to a "closing" state */
|
||||
|
||||
/* Check for open groups on mount points */
|
||||
really_close = TRUE;
|
||||
for(u = 0; u < obj_ent->file->mtab.nmounts; u++) {
|
||||
if(H5G_get_shared_count(obj_ent->file->mtab.child[u].group) > 1) {
|
||||
really_close = FALSE;
|
||||
break;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
|
||||
/* If we really want to close this file now */
|
||||
if(really_close)
|
||||
H5I_dec_ref(obj_ent->file->closing);
|
||||
if(obj_ent->file->nopen_objs == obj_ent->file->mtab.nmounts) {
|
||||
/* Attempt to close down the file hierarchy */
|
||||
if(H5F_try_close(obj_ent->file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
|
||||
} /* end if */
|
||||
|
||||
/* Free the ID to name buffers */
|
||||
@ -452,7 +437,7 @@ H5O_close(H5G_entry_t *obj_ent)
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
}
|
||||
} /* end H5O_close() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1920,7 +1905,7 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found");
|
||||
} /* end if */
|
||||
|
||||
/* Check for creating new message */
|
||||
/* Check for creating new message */
|
||||
if (overwrite < 0) {
|
||||
/* Create a new message */
|
||||
if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id,&oh_flags))==UFAIL)
|
||||
@ -2265,7 +2250,6 @@ H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
|
||||
unsigned * oh_flags_ptr)
|
||||
{
|
||||
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
|
||||
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5O_write_mesg);
|
||||
|
@ -34,7 +34,7 @@ TEST_PROG=testhdf5 lheap ohdr stab gheap cache b+tree btree2 blocktrack sheap \
|
||||
dtypes dsets cmpd_dset extend external links unlink big mtime \
|
||||
fillval mount flush1 flush2 enum \
|
||||
set_extent ttsafe stream_test \
|
||||
getname vfd ntypes dangle dtransform filename reserved
|
||||
getname vfd ntypes dangle dtransform reserved
|
||||
|
||||
# List programs to be built when testing here. error_test and err_compat are
|
||||
# built at the same time as the other tests, but executed by testerror.sh.
|
||||
|
@ -29,7 +29,7 @@
|
||||
#
|
||||
# HDF5 Library Test Makefile(.in)
|
||||
#
|
||||
SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c filename.c fillval.c flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
|
||||
SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fillval.c flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
@ -81,7 +81,7 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
|
||||
flush2$(EXEEXT) enum$(EXEEXT) set_extent$(EXEEXT) \
|
||||
ttsafe$(EXEEXT) stream_test$(EXEEXT) getname$(EXEEXT) \
|
||||
vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \
|
||||
dtransform$(EXEEXT) filename$(EXEEXT) reserved$(EXEEXT)
|
||||
dtransform$(EXEEXT) reserved$(EXEEXT)
|
||||
b_tree_SOURCES = b+tree.c
|
||||
b_tree_OBJECTS = b+tree.$(OBJEXT)
|
||||
b_tree_LDADD = $(LDADD)
|
||||
@ -150,10 +150,6 @@ external_SOURCES = external.c
|
||||
external_OBJECTS = external.$(OBJEXT)
|
||||
external_LDADD = $(LDADD)
|
||||
external_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
|
||||
filename_SOURCES = filename.c
|
||||
filename_OBJECTS = filename.$(OBJEXT)
|
||||
filename_LDADD = $(LDADD)
|
||||
filename_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
|
||||
fillval_SOURCES = fillval.c
|
||||
fillval_OBJECTS = fillval.$(OBJEXT)
|
||||
fillval_LDADD = $(LDADD)
|
||||
@ -273,19 +269,19 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c \
|
||||
blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c \
|
||||
dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
|
||||
error_test.c extend.c external.c filename.c fillval.c flush1.c \
|
||||
flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c \
|
||||
links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c \
|
||||
set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) \
|
||||
testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
|
||||
error_test.c extend.c external.c fillval.c flush1.c flush2.c \
|
||||
getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
|
||||
mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c \
|
||||
stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c \
|
||||
$(ttsafe_SOURCES) unlink.c vfd.c
|
||||
DIST_SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c \
|
||||
blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c \
|
||||
dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
|
||||
error_test.c extend.c external.c filename.c fillval.c flush1.c \
|
||||
flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c \
|
||||
links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c \
|
||||
set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) \
|
||||
testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
|
||||
error_test.c extend.c external.c fillval.c flush1.c flush2.c \
|
||||
getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
|
||||
mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c \
|
||||
stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c \
|
||||
$(ttsafe_SOURCES) unlink.c vfd.c
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -532,7 +528,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache b+tree btree2 blocktrack sheap
|
||||
dtypes dsets cmpd_dset extend external links unlink big mtime \
|
||||
fillval mount flush1 flush2 enum \
|
||||
set_extent ttsafe stream_test \
|
||||
getname vfd ntypes dangle dtransform filename reserved
|
||||
getname vfd ntypes dangle dtransform reserved
|
||||
|
||||
|
||||
# The libh5test.a library provides common support code for the tests.
|
||||
@ -677,9 +673,6 @@ extend$(EXEEXT): $(extend_OBJECTS) $(extend_DEPENDENCIES)
|
||||
external$(EXEEXT): $(external_OBJECTS) $(external_DEPENDENCIES)
|
||||
@rm -f external$(EXEEXT)
|
||||
$(LINK) $(external_LDFLAGS) $(external_OBJECTS) $(external_LDADD) $(LIBS)
|
||||
filename$(EXEEXT): $(filename_OBJECTS) $(filename_DEPENDENCIES)
|
||||
@rm -f filename$(EXEEXT)
|
||||
$(LINK) $(filename_LDFLAGS) $(filename_OBJECTS) $(filename_LDADD) $(LIBS)
|
||||
fillval$(EXEEXT): $(fillval_OBJECTS) $(fillval_DEPENDENCIES)
|
||||
@rm -f fillval$(EXEEXT)
|
||||
$(LINK) $(fillval_LDFLAGS) $(fillval_OBJECTS) $(fillval_LDADD) $(LIBS)
|
||||
@ -776,7 +769,6 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error_test.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extend.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/external.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filename.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillval.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush2.Po@am__quote@
|
||||
|
154
test/filename.c
154
test/filename.c
@ -1,154 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
|
||||
* June 29, 2004
|
||||
*
|
||||
* Purpose: Tests the "H5Fget_name" functionality
|
||||
*/
|
||||
|
||||
#include "testhdf5.h"
|
||||
|
||||
#define FILENAME "get_file_name"
|
||||
#define GROUPNAME "group"
|
||||
#define DSETNAME "dataset"
|
||||
#define ATTRNAME "attribute"
|
||||
#define DTYPENAME "compound"
|
||||
#define NAME_BUF_SIZE 64
|
||||
|
||||
#define RANK 2
|
||||
#define NX 4
|
||||
#define NY 5
|
||||
|
||||
/* Compound datatype */
|
||||
typedef struct s1_t {
|
||||
unsigned int a;
|
||||
float b;
|
||||
} s1_t;
|
||||
|
||||
/* Used to make certain a return name _is_ the file name */
|
||||
#define VERIFY_NAME(x, val, where) do { \
|
||||
if (GetTestVerbosity()>=VERBO_HI) { \
|
||||
print_func(" Call to routine: %15s at line %4d in %s had value " \
|
||||
"%ld \n", (where), (int)__LINE__, __FILE__, (long)(x)); \
|
||||
} \
|
||||
if (strcmp(x, val)) { \
|
||||
TestErrPrintf("*** UNEXPECTED VALUE from %s should be %s, but is %s at line %4d " \
|
||||
"in %s\n", where, val, x, (int)__LINE__, __FILE__); \
|
||||
H5Eprint_stack(H5E_DEFAULT, stdout); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
int main( void )
|
||||
{
|
||||
char filename[NAME_BUF_SIZE];
|
||||
hid_t fapl;
|
||||
hid_t file_id;
|
||||
hid_t group_id;
|
||||
hid_t dataset_id;
|
||||
hid_t space_id;
|
||||
hid_t type_id;
|
||||
hid_t attr_id;
|
||||
hsize_t dims[RANK] = {NX, NY};
|
||||
char name[NAME_BUF_SIZE];
|
||||
ssize_t name_len;
|
||||
herr_t ret;
|
||||
|
||||
TESTING("H5Fget_name");
|
||||
|
||||
/* Reset the library and get the file access property list */
|
||||
h5_reset();
|
||||
fapl = h5_fileaccess();
|
||||
|
||||
/* Initialize the file names */
|
||||
h5_fixname(FILENAME, fapl, filename, sizeof filename);
|
||||
|
||||
/* Create a new file_id using default properties. */
|
||||
file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl );
|
||||
CHECK(file_id, FAIL, "H5Fcreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(file_id, name, NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_NAME(name, filename, "H5Fget_name");
|
||||
|
||||
/* Create a group in the root group */
|
||||
group_id = H5Gcreate(file_id, GROUPNAME, 0);
|
||||
CHECK(group_id, FAIL, "H5Gcreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(group_id, name, NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_NAME(name, filename, "H5Fget_name");
|
||||
|
||||
/* Create the data space */
|
||||
space_id = H5Screate_simple(RANK, dims, NULL);
|
||||
CHECK(space_id, FAIL, "H5Screate_simple");
|
||||
|
||||
/* Try get file name from data space. Supposed to fail because
|
||||
* it's illegal operation. */
|
||||
H5E_BEGIN_TRY {
|
||||
name_len = H5Fget_name(space_id, name, NAME_BUF_SIZE);
|
||||
} H5E_END_TRY;
|
||||
VERIFY(name_len, FAIL, "H5Fget_name");
|
||||
|
||||
/* Create a new dataset */
|
||||
dataset_id = H5Dcreate(file_id, DSETNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT);
|
||||
CHECK(dataset_id, FAIL, "H5Dcreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(dataset_id, name, NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_NAME(name, filename, "H5Fget_name");
|
||||
|
||||
/* Create an attribute for the dataset */
|
||||
attr_id = H5Acreate(dataset_id,ATTRNAME,H5T_NATIVE_INT,space_id,H5P_DEFAULT);
|
||||
CHECK(attr_id, FAIL, "H5Acreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(attr_id, name, NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_NAME(name, filename, "H5Fget_name");
|
||||
|
||||
/* Create a compound datatype */
|
||||
type_id = H5Tcreate(H5T_COMPOUND, sizeof(s1_t));
|
||||
CHECK(type_id, FAIL, "H5Tcreate");
|
||||
|
||||
/* Insert fields */
|
||||
ret = H5Tinsert (type_id, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT);
|
||||
CHECK(ret, FAIL, "H5Tinsert");
|
||||
|
||||
ret = H5Tinsert (type_id, "b", HOFFSET(s1_t,b), H5T_NATIVE_FLOAT);
|
||||
CHECK(ret, FAIL, "H5Tinsert");
|
||||
|
||||
/* Save it on file */
|
||||
ret = H5Tcommit(file_id, DTYPENAME, type_id);
|
||||
CHECK(ret, FAIL, "H5Tcommit");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(type_id, name, NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_NAME(name, filename, "H5Fget_name");
|
||||
|
||||
H5Tclose(type_id);
|
||||
H5Aclose(attr_id);
|
||||
H5Dclose(dataset_id);
|
||||
H5Sclose(space_id);
|
||||
H5Gclose(group_id);
|
||||
H5Fclose(file_id);
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
}
|
719
test/mount.c
719
test/mount.c
@ -124,15 +124,21 @@ test_basic(hid_t fapl)
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
|
||||
|
||||
if ((file1=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0 ||
|
||||
(file2=H5Fopen(filename2, H5F_ACC_RDONLY, fapl))<0)
|
||||
goto error;
|
||||
if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
|
||||
if ((grp=H5Gopen(file1, "/mnt1/file2"))<0) goto error;
|
||||
if (H5Gclose(grp)<0) goto error;
|
||||
if (H5Funmount(file1, "/mnt1")<0) goto error;
|
||||
if (H5Fclose(file1)<0) goto error;
|
||||
if (H5Fclose(file2)<0) goto error;
|
||||
if ((file1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0 ||
|
||||
(file2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0)
|
||||
TEST_ERROR
|
||||
if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR
|
||||
if ((grp = H5Gopen(file1, "/mnt1/file2")) < 0)
|
||||
TEST_ERROR
|
||||
if (H5Gclose(grp) < 0)
|
||||
TEST_ERROR
|
||||
if (H5Funmount(file1, "/mnt1") < 0)
|
||||
TEST_ERROR
|
||||
if (H5Fclose(file1) < 0)
|
||||
TEST_ERROR
|
||||
if (H5Fclose(file2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
@ -972,7 +978,6 @@ test_close(hid_t fapl)
|
||||
{
|
||||
hid_t file1=-1, file2=-1;
|
||||
char filename1[1024], filename2[1024];
|
||||
herr_t status;
|
||||
|
||||
TESTING("file handle close");
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
@ -985,21 +990,21 @@ test_close(hid_t fapl)
|
||||
if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
|
||||
|
||||
/*
|
||||
* Close file1 unmounting it from the virtual file. Objects in file2 are
|
||||
* still accessible through the file2 handle, but nothing in file1 is
|
||||
* accessible.
|
||||
* Close file1 unmounting it from the virtual file. Objects in file1 are
|
||||
* still accessible through the file2 handle.
|
||||
*/
|
||||
if (H5Fclose(file1)<0) goto error;
|
||||
H5E_BEGIN_TRY {
|
||||
status = H5Gget_objinfo(file2, "/mnt1", TRUE, NULL);
|
||||
} H5E_END_TRY;
|
||||
if (status>=0) {
|
||||
if(H5Gget_objinfo(file2, "/mnt1", TRUE, NULL) < 0) {
|
||||
H5_FAILED();
|
||||
puts(" File1 contents are still accessible!");
|
||||
puts(" File1 contents are not accessible!");
|
||||
goto error;
|
||||
}
|
||||
if (H5Fclose(file2)<0) goto error;
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Build the virtual file again */
|
||||
if ((file1=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0 ||
|
||||
(file2=H5Fopen(filename2, H5F_ACC_RDWR, fapl))<0)
|
||||
@ -1013,6 +1018,10 @@ test_close(hid_t fapl)
|
||||
if (H5Gget_objinfo(file1, "/mnt1/file2", TRUE, NULL)<0) goto error;
|
||||
if (H5Fclose(file1)<0) goto error;
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Shut down */
|
||||
PASSED();
|
||||
return 0;
|
||||
@ -1657,10 +1666,6 @@ test_missing_unmount(hid_t fapl)
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all "file closing" IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE_CLOSING) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
@ -1795,10 +1800,6 @@ test_hold_open_file(hid_t fapl)
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all "file closing" IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE_CLOSING) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
@ -1835,7 +1836,7 @@ static int
|
||||
test_hold_open_group(hid_t fapl)
|
||||
{
|
||||
hid_t fid1 = -1, fid2 = -1; /* File IDs */
|
||||
hid_t gidA = -1, gidM = -1, gidAM = -1, gidAM2 = -1; /* Group IDs */
|
||||
hid_t gid = -1, gidA = -1, gidM = -1, gidAM = -1, gidAM2 = -1; /* Group IDs */
|
||||
char filename1[1024],
|
||||
filename2[1024]; /* Name of files to mount */
|
||||
|
||||
@ -1916,23 +1917,44 @@ test_hold_open_group(hid_t fapl)
|
||||
if((gidAM2 = H5Gopen(fid1, "/A/M")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #1 */
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Get ID of file #2 */
|
||||
if((fid2 = H5Iget_file_id(gidAM2)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in mounted file */
|
||||
if(H5Gclose(gidAM2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #1 */
|
||||
/* (should unmount file #2 also) */
|
||||
if(H5Fclose(fid1) < 0)
|
||||
/* Attempt to open group in mounted file */
|
||||
/* (Should work because file is still mounted) */
|
||||
if((gidAM2 = H5Gopen(fid2, "/A/M")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #2 */
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Attempt to open group in parent file */
|
||||
/* (Should work because files should be mounted together) */
|
||||
if((gid = H5Gopen(gidAM2, "/")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in mounted file */
|
||||
if(H5Gclose(gidAM2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in parent file */
|
||||
if(H5Gclose(gid) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all "file closing" IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE_CLOSING) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
@ -1942,12 +1964,637 @@ error:
|
||||
H5Gclose(gidAM);
|
||||
H5Gclose(gidAM2);
|
||||
H5Gclose(gidA);
|
||||
H5Gclose(gid);
|
||||
H5Fclose(fid2);
|
||||
H5Fclose(fid1);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_hold_open_group() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_fcdegree_same
|
||||
*
|
||||
* Purpose: Test that the library will only allow files with same file
|
||||
* close degree to be mounted together.
|
||||
*
|
||||
* Return: Success: 0
|
||||
*
|
||||
* Failure: number of errors
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_fcdegree_same(hid_t fapl)
|
||||
{
|
||||
hid_t fid1 = -1, fid2 = -1; /* File IDs */
|
||||
hid_t gidA = -1, gidM = -1, gidAM = -1; /* Group IDs */
|
||||
hid_t fapl_id = -1; /* FAPL IDs */
|
||||
herr_t ret; /* Generic return value */
|
||||
char filename1[1024],
|
||||
filename2[1024]; /* Name of files to mount */
|
||||
|
||||
TESTING("file close degrees must be same");
|
||||
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
|
||||
|
||||
/* Create file #1 */
|
||||
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Create file #2 */
|
||||
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Re-open files and mount file #2 in file #1 */
|
||||
if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gopen(fid1, "A")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Create FAPL & set file close degree for file #2 to be different */
|
||||
if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Set file close mode to H5F_CLOSE_STRONG */
|
||||
if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Try mounting file with different file close degree (should fail) */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Fmount(gidA, ".", fid2, H5P_DEFAULT);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Set file close mode to H5F_CLOSE_WEAK */
|
||||
if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #2 & re-open with same file close degree as file #1 */
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Try mounting files again (should work now) */
|
||||
if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Verify opening group in mounted file */
|
||||
if((gidAM = H5Gopen(fid1, "A/M")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in mounted file */
|
||||
if(H5Gclose(gidAM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in parent file */
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #2 */
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #1 */
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close FAPL ID */
|
||||
if(H5Pclose(fapl_id) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Pclose(fapl_id);
|
||||
H5Gclose(gidM);
|
||||
H5Gclose(gidAM);
|
||||
H5Gclose(gidA);
|
||||
H5Fclose(fid2);
|
||||
H5Fclose(fid1);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_fcdegree_same() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_fcdegree_semi
|
||||
*
|
||||
* Purpose: Test that the library perform correct actions when using
|
||||
* "semi" file close degree on mounted files
|
||||
*
|
||||
* Return: Success: 0
|
||||
*
|
||||
* Failure: number of errors
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_fcdegree_semi(hid_t fapl)
|
||||
{
|
||||
hid_t fid1 = -1, fid2 = -1; /* File IDs */
|
||||
hid_t gidA = -1, gidM = -1, gidAM = -1; /* Group IDs */
|
||||
hid_t fapl_id = -1; /* FAPL IDs */
|
||||
herr_t ret; /* Generic return value */
|
||||
char filename1[1024],
|
||||
filename2[1024]; /* Name of files to mount */
|
||||
|
||||
TESTING("'semi' file close degree");
|
||||
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
|
||||
|
||||
/* Create file #1 */
|
||||
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Create file #2 */
|
||||
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Create FAPL & set file close degree to be "semi" */
|
||||
if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Set file close mode to H5F_CLOSE_SEMI */
|
||||
if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Re-open files and mount file #2 in file #1 */
|
||||
if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl_id)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gopen(fid1, "A")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Mount files together */
|
||||
if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Verify opening group in mounted file */
|
||||
if((gidAM = H5Gopen(fid1, "A/M")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #1 (should succeed, since file #2 is open still) */
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Try closing file #2 (should fail, since there are still objects open) */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Fclose(fid2);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in parent file */
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Try closing file #2 (should still fail, since there are still objects open in child file) */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Fclose(fid2);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in mounted file */
|
||||
if(H5Gclose(gidAM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #2 (should succeed now) */
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close FAPL ID */
|
||||
if(H5Pclose(fapl_id) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Pclose(fapl_id);
|
||||
H5Gclose(gidM);
|
||||
H5Gclose(gidAM);
|
||||
H5Gclose(gidA);
|
||||
H5Fclose(fid2);
|
||||
H5Fclose(fid1);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_fcdegree_semi() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_fcdegree_strong
|
||||
*
|
||||
* Purpose: Test that the library perform correct actions when using
|
||||
* "strong" file close degree on mounted files
|
||||
*
|
||||
* Return: Success: 0
|
||||
*
|
||||
* Failure: number of errors
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_fcdegree_strong(hid_t fapl)
|
||||
{
|
||||
hid_t fid1 = -1, fid2 = -1; /* File IDs */
|
||||
hid_t gidA = -1, gidM = -1, gidAM = -1; /* Group IDs */
|
||||
hid_t fapl_id = -1; /* FAPL IDs */
|
||||
herr_t ret; /* Generic return value */
|
||||
char filename1[1024],
|
||||
filename2[1024]; /* Name of files to mount */
|
||||
|
||||
TESTING("'strong' file close degree");
|
||||
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
|
||||
|
||||
/* Create file #1 */
|
||||
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Create file #2 */
|
||||
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Create FAPL & set file close degree to be "strong" */
|
||||
if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Set file close mode to H5F_CLOSE_STRONG */
|
||||
if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Re-open files and mount file #2 in file #1 */
|
||||
if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl_id)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gopen(fid1, "A")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Mount files together */
|
||||
if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Open group in mounted file */
|
||||
if((gidAM = H5Gopen(fid1, "A/M")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #1 */
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that objects are still open */
|
||||
if (H5Gget_objinfo(gidA, ".", TRUE, NULL) < 0)
|
||||
TEST_ERROR
|
||||
if (H5Gget_objinfo(gidAM, ".", TRUE, NULL) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #2 (should close open objects also) */
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that objects are closed */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Gget_objinfo(gidA, ".", TRUE, NULL);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Gget_objinfo(gidAM, ".", TRUE, NULL);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close FAPL ID */
|
||||
if(H5Pclose(fapl_id) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Pclose(fapl_id);
|
||||
H5Gclose(gidM);
|
||||
H5Gclose(gidAM);
|
||||
H5Gclose(gidA);
|
||||
H5Fclose(fid2);
|
||||
H5Fclose(fid1);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_fcdegree_strong() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_acc_perm
|
||||
*
|
||||
* Purpose: Test that the library correctly segregates operations in
|
||||
* parts of mounted file hierarchy with files that have different
|
||||
* R/W access permissions.
|
||||
*
|
||||
*
|
||||
* Return: Success: 0
|
||||
*
|
||||
* Failure: number of errors
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, July 19, 2005
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_acc_perm(hid_t fapl)
|
||||
{
|
||||
hid_t fid1 = -1, fid2 = -1, fid3 = -1; /* File IDs */
|
||||
hid_t gidA = -1, gidB = -1, gidC = -1, gidM = -1, gidAM = -1, gidAMZ = -1; /* Group IDs */
|
||||
hid_t bad_id = -1; /* Bad ID from object create */
|
||||
char name[NAME_BUF_SIZE]; /* Buffer for filename retrieved */
|
||||
ssize_t name_len; /* Filename length */
|
||||
char filename1[1024],
|
||||
filename2[1024],
|
||||
filename3[1024]; /* Name of files to mount */
|
||||
|
||||
TESTING("access permissions");
|
||||
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
|
||||
h5_fixname(FILENAME[2], fapl, filename3, sizeof filename3);
|
||||
|
||||
/* Create file #1 */
|
||||
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Create file #2 */
|
||||
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Gclose(gidM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Re-open files and mount file #2 in file #1 */
|
||||
if((fid1 = H5Fopen(filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((gidA = H5Gopen(fid1, "A")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Get and verify file name */
|
||||
if((name_len = H5Fget_name(gidA, name, NAME_BUF_SIZE)) < 0)
|
||||
TEST_ERROR
|
||||
if(HDstrcmp(name, filename1) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Get and verify file name */
|
||||
if((name_len = H5Fget_name(fid2, name, NAME_BUF_SIZE)) < 0)
|
||||
TEST_ERROR
|
||||
if(HDstrcmp(name, filename2) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Mount files together */
|
||||
if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Get and verify file name */
|
||||
if((name_len = H5Fget_name(fid2, name, NAME_BUF_SIZE)) < 0)
|
||||
TEST_ERROR
|
||||
if(HDstrcmp(name, filename2) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Open group in mounted file */
|
||||
if((gidAM = H5Gopen(fid1, "A/M")) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Get and verify file name */
|
||||
if((name_len = H5Fget_name(gidAM, name, NAME_BUF_SIZE)) < 0)
|
||||
TEST_ERROR
|
||||
if(HDstrcmp(name, filename2) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Attempt to create objects in read only file (should fail) */
|
||||
H5E_BEGIN_TRY {
|
||||
bad_id = H5Gcreate(gidAM, "Z", (size_t)0);
|
||||
} H5E_END_TRY;
|
||||
if(bad_id >= 0)
|
||||
TEST_ERROR
|
||||
H5E_BEGIN_TRY {
|
||||
bad_id = H5Gcreate(fid1, "/A/L", (size_t)0);
|
||||
} H5E_END_TRY;
|
||||
if(bad_id >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Attempt to create objects in read/write file (should succeed) */
|
||||
if((gidB = H5Gcreate(fid2, "/B", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
if(H5Gclose(gidB) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* (Note that this object should get created in the "hidden" group for "A" in parent file) */
|
||||
if((gidC = H5Gcreate(gidA, "C", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
if(H5Gclose(gidC) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Create file #3 (it will have R/W permissions) */
|
||||
if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Mount file #3 on file #2 */
|
||||
if(H5Fmount(gidAM, ".", fid3, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Attempt to create objects in read/write file (should succeed) */
|
||||
if((gidAMZ = H5Gcreate(fid1, "/A/M/Z", (size_t)0)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Get and verify file name */
|
||||
if((name_len = H5Fget_name(gidAMZ, name, NAME_BUF_SIZE)) < 0)
|
||||
TEST_ERROR
|
||||
if(HDstrcmp(name, filename3) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close object in file #3 */
|
||||
if(H5Gclose(gidAMZ) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Attempt to create objects in read only file again (should fail) */
|
||||
H5E_BEGIN_TRY {
|
||||
bad_id = H5Gcreate(fid1, "/A/L", (size_t)0);
|
||||
} H5E_END_TRY;
|
||||
if(bad_id >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in mounted file */
|
||||
if(H5Gclose(gidAM) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close group in parent file */
|
||||
if(H5Gclose(gidA) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #3 */
|
||||
if(H5Fclose(fid3) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #2 */
|
||||
if(H5Fclose(fid2) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close file #1 */
|
||||
if(H5Fclose(fid1) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Gclose(gidM);
|
||||
H5Gclose(gidAMZ);
|
||||
H5Gclose(gidAM);
|
||||
H5Gclose(gidC);
|
||||
H5Gclose(gidB);
|
||||
H5Gclose(gidA);
|
||||
H5Fclose(fid3);
|
||||
H5Fclose(fid2);
|
||||
H5Fclose(fid1);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_acc_perm() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
@ -1993,6 +2640,10 @@ main(void)
|
||||
nerrors += test_missing_unmount(fapl);
|
||||
nerrors += test_hold_open_file(fapl);
|
||||
nerrors += test_hold_open_group(fapl);
|
||||
nerrors += test_fcdegree_same(fapl);
|
||||
nerrors += test_fcdegree_semi(fapl);
|
||||
nerrors += test_fcdegree_strong(fapl);
|
||||
nerrors += test_acc_perm(fapl);
|
||||
|
||||
if (nerrors) goto error;
|
||||
puts("All mount tests passed.");
|
||||
|
@ -80,6 +80,19 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Used to make certain a string return value _is_ a value */
|
||||
#define VERIFY_STR(x, val, where) do { \
|
||||
if (GetTestVerbosity()>=VERBO_HI) { \
|
||||
print_func(" Call to routine: %15s at line %4d in %s had value " \
|
||||
"%s \n", (where), (int)__LINE__, __FILE__, x); \
|
||||
} \
|
||||
if (HDstrcmp(x, val)) { \
|
||||
TestErrPrintf("*** UNEXPECTED VALUE from %s should be %s, but is %s at line %4d " \
|
||||
"in %s\n", where, val, x, (int)__LINE__, __FILE__); \
|
||||
H5Eprint_stack(H5E_DEFAULT, stdout); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Used to document process through a test and to check for errors */
|
||||
#define RESULT(ret,func) do { \
|
||||
if (GetTestVerbosity()>VERBO_MED) { \
|
||||
|
155
test/tfile.c
155
test/tfile.c
@ -69,6 +69,15 @@
|
||||
#define DSET1 "Dataset1"
|
||||
#define DSET2 "/Group1/Dataset2"
|
||||
|
||||
#define TESTA_GROUPNAME "group"
|
||||
#define TESTA_DSETNAME "dataset"
|
||||
#define TESTA_ATTRNAME "attribute"
|
||||
#define TESTA_DTYPENAME "compound"
|
||||
#define TESTA_NAME_BUF_SIZE 64
|
||||
#define TESTA_RANK 2
|
||||
#define TESTA_NX 4
|
||||
#define TESTA_NY 5
|
||||
|
||||
static void
|
||||
create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *);
|
||||
static void
|
||||
@ -1447,62 +1456,179 @@ test_file_open_overlap(void)
|
||||
|
||||
/* Create file */
|
||||
fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
||||
assert(fid1 > 0);
|
||||
CHECK(fid1, FAIL, "H5Fcreate");
|
||||
|
||||
/* Open file also */
|
||||
fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
|
||||
assert(fid2 > 0);
|
||||
CHECK(fid2, FAIL, "H5Fopen");
|
||||
|
||||
/* Create a group in file */
|
||||
gid = H5Gcreate(fid1, GROUP1, (size_t)0);
|
||||
assert(gid > 0);
|
||||
CHECK(gid, FAIL, "H5Gcreate");
|
||||
|
||||
/* Create dataspace for dataset */
|
||||
sid = H5Screate(H5S_SCALAR);
|
||||
assert(sid > 0);
|
||||
CHECK(sid, FAIL, "H5Screate");
|
||||
|
||||
/* Create dataset in group w/first file ID */
|
||||
did1 = H5Dcreate(gid, DSET1, H5T_NATIVE_INT, sid, H5P_DEFAULT);
|
||||
assert(did1 > 0);
|
||||
CHECK(did1, FAIL, "H5Dcreate");
|
||||
|
||||
/* Check number of objects opened in first file */
|
||||
nobjs = H5Fget_obj_count(fid1, H5F_OBJ_LOCAL|H5F_OBJ_ALL);
|
||||
assert(nobjs == 3); /* 3 == file, dataset & group */
|
||||
VERIFY(nobjs, 3, "H5Fget_obj_count"); /* 3 == file, dataset & group */
|
||||
|
||||
/* Close dataset */
|
||||
ret = H5Dclose(did1);
|
||||
assert(ret >= 0);
|
||||
CHECK(ret, FAIL, "H5Dclose");
|
||||
|
||||
/* Close group */
|
||||
ret = H5Gclose(gid);
|
||||
assert(ret >= 0);
|
||||
CHECK(ret, FAIL, "H5Gclose");
|
||||
|
||||
/* Close first file ID */
|
||||
ret = H5Fclose(fid1);
|
||||
assert(ret >= 0);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
|
||||
|
||||
/* Create dataset with second file ID */
|
||||
did2 = H5Dcreate(fid2, DSET2, H5T_NATIVE_INT, sid, H5P_DEFAULT);
|
||||
assert(did2 > 0);
|
||||
CHECK(did2, FAIL, "H5Dcreate");
|
||||
|
||||
/* Check number of objects opened in first file */
|
||||
nobjs = H5Fget_obj_count(fid2, H5F_OBJ_ALL);
|
||||
assert(nobjs == 2); /* 2 == file & dataset */
|
||||
VERIFY(nobjs, 2, "H5Fget_obj_count"); /* 3 == file & dataset */
|
||||
|
||||
/* Close dataspace */
|
||||
ret = H5Sclose(sid);
|
||||
assert(ret >= 0);
|
||||
CHECK(ret, FAIL, "H5Sclose");
|
||||
|
||||
/* Close second dataset */
|
||||
ret = H5Dclose(did2);
|
||||
assert(ret >= 0);
|
||||
CHECK(ret, FAIL, "H5Dclose");
|
||||
|
||||
/* Close second file */
|
||||
ret = H5Fclose(fid2);
|
||||
assert(ret >= 0);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
} /* end test_file_open_overlap() */
|
||||
|
||||
/****************************************************************
|
||||
**
|
||||
** test_file_getname(): low-level file test routine.
|
||||
** This test checks whether H5Fget_name works correctly.
|
||||
**
|
||||
*****************************************************************/
|
||||
static void
|
||||
test_file_getname(void)
|
||||
{
|
||||
/* Compound datatype */
|
||||
typedef struct s1_t {
|
||||
unsigned int a;
|
||||
float b;
|
||||
} s1_t;
|
||||
|
||||
hid_t file_id;
|
||||
hid_t group_id;
|
||||
hid_t dataset_id;
|
||||
hid_t space_id;
|
||||
hid_t type_id;
|
||||
hid_t attr_id;
|
||||
hsize_t dims[TESTA_RANK] = {TESTA_NX, TESTA_NY};
|
||||
char name[TESTA_NAME_BUF_SIZE];
|
||||
ssize_t name_len;
|
||||
herr_t ret; /* Generic return value */
|
||||
|
||||
/* Output message about test being performed */
|
||||
MESSAGE(5, ("Testing H5Fget_name() functionality\n"));
|
||||
|
||||
/* Create a new file_id using default properties. */
|
||||
file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
|
||||
CHECK(file_id, FAIL, "H5Fcreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(file_id, name, TESTA_NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_STR(name, FILE1, "H5Fget_name");
|
||||
|
||||
/* Create a group in the root group */
|
||||
group_id = H5Gcreate(file_id, TESTA_GROUPNAME, 0);
|
||||
CHECK(group_id, FAIL, "H5Gcreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(group_id, name, TESTA_NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_STR(name, FILE1, "H5Fget_name");
|
||||
|
||||
/* Create the data space */
|
||||
space_id = H5Screate_simple(TESTA_RANK, dims, NULL);
|
||||
CHECK(space_id, FAIL, "H5Screate_simple");
|
||||
|
||||
/* Try get file name from data space. Supposed to fail because
|
||||
* it's illegal operation. */
|
||||
H5E_BEGIN_TRY {
|
||||
name_len = H5Fget_name(space_id, name, TESTA_NAME_BUF_SIZE);
|
||||
} H5E_END_TRY;
|
||||
VERIFY(name_len, FAIL, "H5Fget_name");
|
||||
|
||||
/* Create a new dataset */
|
||||
dataset_id = H5Dcreate(file_id, TESTA_DSETNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT);
|
||||
CHECK(dataset_id, FAIL, "H5Dcreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(dataset_id, name, TESTA_NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_STR(name, FILE1, "H5Fget_name");
|
||||
|
||||
/* Create an attribute for the dataset */
|
||||
attr_id = H5Acreate(dataset_id,TESTA_ATTRNAME,H5T_NATIVE_INT,space_id,H5P_DEFAULT);
|
||||
CHECK(attr_id, FAIL, "H5Acreate");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(attr_id, name, TESTA_NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_STR(name, FILE1, "H5Fget_name");
|
||||
|
||||
/* Create a compound datatype */
|
||||
type_id = H5Tcreate(H5T_COMPOUND, sizeof(s1_t));
|
||||
CHECK(type_id, FAIL, "H5Tcreate");
|
||||
|
||||
/* Insert fields */
|
||||
ret = H5Tinsert (type_id, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT);
|
||||
CHECK(ret, FAIL, "H5Tinsert");
|
||||
|
||||
ret = H5Tinsert (type_id, "b", HOFFSET(s1_t,b), H5T_NATIVE_FLOAT);
|
||||
CHECK(ret, FAIL, "H5Tinsert");
|
||||
|
||||
/* Save it on file */
|
||||
ret = H5Tcommit(file_id, TESTA_DTYPENAME, type_id);
|
||||
CHECK(ret, FAIL, "H5Tcommit");
|
||||
|
||||
/* Get and verify file name */
|
||||
name_len = H5Fget_name(type_id, name, TESTA_NAME_BUF_SIZE);
|
||||
CHECK(name_len, FAIL, "H5Fget_name");
|
||||
VERIFY_STR(name, FILE1, "H5Fget_name");
|
||||
|
||||
/* Close things down */
|
||||
ret = H5Tclose(type_id);
|
||||
CHECK(ret, FAIL, "H5Tclose");
|
||||
|
||||
ret = H5Aclose(attr_id);
|
||||
CHECK(ret, FAIL, "H5Aclose");
|
||||
|
||||
ret = H5Dclose(dataset_id);
|
||||
CHECK(ret, FAIL, "H5Dclose");
|
||||
|
||||
ret = H5Sclose(space_id);
|
||||
CHECK(ret, FAIL, "H5Sclose");
|
||||
|
||||
ret = H5Gclose(group_id);
|
||||
CHECK(ret, FAIL, "H5Gclose");
|
||||
|
||||
ret = H5Fclose(file_id);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
|
||||
} /* end test_file_getname() */
|
||||
|
||||
/****************************************************************
|
||||
**
|
||||
** test_file(): Main low-level file I/O test routine.
|
||||
@ -1525,6 +1651,7 @@ test_file(void)
|
||||
test_file_ishdf5(); /* Test detecting HDF5 files correctly */
|
||||
test_file_open_dot(); /* Test opening objects with "." for a name */
|
||||
test_file_open_overlap(); /* Test opening files in an overlapping manner */
|
||||
test_file_getname(); /* Test basic H5Fget_name() functionality */
|
||||
} /* test_file() */
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user