diff options
-rw-r--r-- | release_docs/RELEASE.txt | 7 | ||||
-rw-r--r-- | src/H5F.c | 94 | ||||
-rw-r--r-- | src/H5Fpublic.h | 13 | ||||
-rw-r--r-- | src/H5G.c | 5 | ||||
-rw-r--r-- | test/mount.c | 34 | ||||
-rw-r--r-- | test/tfile.c | 106 |
6 files changed, 172 insertions, 87 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index aae113a..43a9b72 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -90,6 +90,10 @@ New Features Library: -------- + - Added H5F_OBJ_LOCAL flag to H5Fget_obj_count() & H5Fget_obj_ids(), to + allow querying for objects in file that were opened with a particular + file ID, instead of all objects opened in file with any file ID. + QAK - 2005/06/01 - Added H5T_CSET_UTF8 character set to mark datatypes that use the UTF-8 Unicode character encoding. Added tests to ensure that library handles UTF-8 object names, attributes, etc. -JL 2005/05/13 @@ -286,6 +290,9 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - "SEMI" and "STRONG" file close degree settings now apply only to the + particular file ID being closed, instead of operating on all open + file IDs for a given file. QAK - 2005/06/01 - For family driver, the library didn't save member size in file. When file is reopened, the size of 1st member file determine the member size. Now member size is saved in file and is used to @@ -49,7 +49,13 @@ typedef struct H5F_olist_t { H5I_type_t obj_type; /* Type of object to look for */ hid_t *obj_id_list; /* Pointer to the list of open IDs to return */ unsigned *obj_id_count; /* Number of open IDs */ - H5F_file_t *shared; /* Pointer to file to look inside */ + struct { + hbool_t local; /* Set flag for "local" file searches */ + union { + H5F_file_t *shared; /* Pointer to shared file to look inside */ + const H5F_t *file; /* Pointer to file to look inside */ + } ptr; + } file_info; unsigned list_index; /* Current index in open ID array */ int max_index; /* Maximum # of IDs to put into array */ } H5F_olist_t; @@ -1014,12 +1020,16 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis olist.obj_id_count = &obj_id_count; olist.list_index = 0; olist.max_index = max_index; - /* Shared file structure is used to verify if file IDs refer to the same - * file. */ - if(f != NULL) - olist.shared = f->shared; - else - olist.shared = NULL; + + /* Determine if we are searching for local or global objects */ + if(types&H5F_OBJ_LOCAL) { + olist.file_info.local = TRUE; + olist.file_info.ptr.file = f; + } /* end if */ + else { + olist.file_info.local = FALSE; + olist.file_info.ptr.shared = f ? f->shared : NULL; + } /* end else */ /* Search through file IDs to count the number, and put their * IDs on the object list */ @@ -1093,7 +1103,10 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) /* Count file IDs */ if(olist->obj_type == H5I_FILE) { - if( !olist->shared || (olist->shared && ((H5F_t*)obj_ptr)->shared == olist->shared) ) { + if((olist->file_info.local && + (!olist->file_info.ptr.file || (olist->file_info.ptr.file && (H5F_t*)obj_ptr == olist->file_info.ptr.file) )) + || (!olist->file_info.local && + ( !olist->file_info.ptr.shared || (olist->file_info.ptr.shared && ((H5F_t*)obj_ptr)->shared == olist->file_info.ptr.shared) ))) { /* Add the object's ID to the ID list, if appropriate */ if(olist->obj_id_list) { olist->obj_id_list[olist->list_index] = obj_id; @@ -1131,9 +1144,14 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object") } - if( (!olist->shared && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE) - || (!olist->shared && olist->obj_type!=H5I_DATATYPE) - || (ent && ent->file && ent->file->shared == olist->shared) ) { + if((olist->file_info.local && + ( (!olist->file_info.ptr.file && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE) + || (!olist->file_info.ptr.file && olist->obj_type!=H5I_DATATYPE) + || (ent && ent->file == olist->file_info.ptr.file) )) + || (!olist->file_info.local && + ((!olist->file_info.ptr.shared && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE) + || (!olist->file_info.ptr.shared && olist->obj_type!=H5I_DATATYPE) + || (ent && ent->file && ent->file->shared == olist->file_info.ptr.shared) ))) { /* Add the object's ID to the ID list, if appropriate */ if(olist->obj_id_list) { olist->obj_id_list[olist->list_index] = obj_id; @@ -3112,8 +3130,6 @@ done: static herr_t H5F_close(H5F_t *f) { - H5F_close_degree_t fc_degree; /* What action to take when closing the last file ID for a file */ - unsigned closing=0; /* Indicate that the file will be closed */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3135,12 +3151,9 @@ H5F_close(H5F_t *f) /* Double-check that this file should be closed */ assert(1==f->nrefs); - /* Get the close degree from the file */ - fc_degree = f->shared->fc_degree; - /* 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(fc_degree==H5F_CLOSE_SEMI && f->nopen_objs>0 && f->shared->nrefs==1) + 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") /* @@ -3166,7 +3179,7 @@ H5F_close(H5F_t *f) * H5F_CLOSE_STRONG: if there are still objects open, close them * first, then close file. */ - switch(fc_degree) { + switch(f->shared->fc_degree) { case H5F_CLOSE_WEAK: /* * If object headers are still open then delay deletion of @@ -3203,39 +3216,11 @@ H5F_close(H5F_t *f) fprintf(H5DEBUG(F), "H5F: H5F_close: operation completing\n"); #endif } /* end if */ - - /* Indicate that the file will be closing */ - closing=1; } /* end else */ break; case H5F_CLOSE_SEMI: - 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 - /* 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; - - HGOTO_DONE(SUCCEED) - } else { - if (!f->closing && f->shared->nrefs>1) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open") - - /* Indicate that the file will be closing */ - closing=1; - } /* end else */ + /* 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: @@ -3246,7 +3231,7 @@ H5F_close(H5F_t *f) int i; /* Local index variable */ /* Get the list of IDs of open dataset objects */ - while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_DATASET, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) { + 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++) @@ -3255,7 +3240,7 @@ H5F_close(H5F_t *f) } /* end while */ /* Get the list of IDs of open group objects */ - while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_GROUP, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) { + 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++) @@ -3264,7 +3249,7 @@ H5F_close(H5F_t *f) } /* end while */ /* Get the list of IDs of open named datatype objects */ - while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) { + 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++) @@ -3273,7 +3258,7 @@ H5F_close(H5F_t *f) } /* end while */ /* Get the list of IDs of open attribute objects */ - while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) { + 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++) @@ -3281,9 +3266,6 @@ H5F_close(H5F_t *f) HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") } /* end while */ } /* end while */ - - /* Indicate that the file will be closing */ - closing=1; break; default: @@ -3293,8 +3275,8 @@ H5F_close(H5F_t *f) /* Invalidate file ID */ f->file_id = -1; - /* Only flush at this point if the file will be closed */ - assert(closing); + /* Flush at this point since the file will be closed */ + /* Dump debugging info */ #if H5AC_DUMP_STATS_ON_CLOSE H5AC_stats(f); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 91edaa2..a829b97 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -52,12 +52,15 @@ #define H5F_ACC_DEBUG (H5CHECK 0x0008u) /*print debug info */ #define H5F_ACC_CREAT (H5CHECK 0x0010u) /*create non-existing files */ -#define H5F_OBJ_FILE (0x0001u) -#define H5F_OBJ_DATASET (0x0002u) -#define H5F_OBJ_GROUP (0x0004u) -#define H5F_OBJ_DATATYPE (0x0008u) -#define H5F_OBJ_ATTR (0x0010u) +/* Flags for H5Fget_obj_count() & H5Fget_obj_ids() calls */ +#define H5F_OBJ_FILE (0x0001u) /* File objects */ +#define H5F_OBJ_DATASET (0x0002u) /* Dataset objects */ +#define H5F_OBJ_GROUP (0x0004u) /* Group objects */ +#define H5F_OBJ_DATATYPE (0x0008u) /* Named datatype objects */ +#define H5F_OBJ_ATTR (0x0010u) /* Attribute objects */ #define H5F_OBJ_ALL (H5F_OBJ_FILE|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR) +#define H5F_OBJ_LOCAL (0x0020u) /* Restrict search to objects opened through current file ID */ + /* (as opposed to objects opened through any file ID accessing this file) */ #define H5F_FAMILY_DEFAULT 0 @@ -2386,6 +2386,11 @@ H5G_loc (hid_t loc_id) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid file ID"); if (NULL==(ret_value=H5G_entof(H5G_rootof(f)))) 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 */ + /* (but only for non-mounted files) */ + if(!f->mtab.parent) + ret_value->file = f; break; case H5I_GENPROP_CLS: diff --git a/test/mount.c b/test/mount.c index ac8212e..7a42790 100644 --- a/test/mount.c +++ b/test/mount.c @@ -712,7 +712,7 @@ test_unlink(hid_t fapl) } H5E_END_TRY; if (status>=0) { H5_FAILED(); - puts(" Unmount by name should not have been allowed!"); + printf(" %d: Unmount by name should not have been allowed!\n",__LINE__); goto error; } H5E_BEGIN_TRY { @@ -720,7 +720,7 @@ test_unlink(hid_t fapl) } H5E_END_TRY; if (status>=0) { H5_FAILED(); - puts(" Unmount by name should not have been allowed!"); + printf(" %d: Unmount by name should not have been allowed!\n",__LINE__); goto error; } if (H5Funmount(mnt, ".")<0) goto error; @@ -916,27 +916,27 @@ test_uniformity(hid_t fapl) /* Build the virtual file */ if ((file1=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0 || (file2=H5Fopen(filename2, H5F_ACC_RDWR, fapl))<0) - goto error; - if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error; + TEST_ERROR; + if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) TEST_ERROR; /* Access some things from the file1 handle */ - if (H5Gget_objinfo(file1, "/", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file1, "/mnt1", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file1, "mnt1", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file1, "/mnt1/file2", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file1, "mnt1/file2", TRUE, NULL)<0) goto error; + if (H5Gget_objinfo(file1, "/", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file1, "/mnt1", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file1, "mnt1", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file1, "/mnt1/file2", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file1, "mnt1/file2", TRUE, NULL)<0) TEST_ERROR; /* Access the same things from the file2 handle */ - if (H5Gget_objinfo(file2, "/", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file2, "/mnt1", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file2, "mnt1", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file2, "/mnt1/file2", TRUE, NULL)<0) goto error; - if (H5Gget_objinfo(file2, "mnt1/file2", TRUE, NULL)<0) goto error; + if (H5Gget_objinfo(file2, "/", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file2, "/mnt1", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file2, "mnt1", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file2, "/mnt1/file2", TRUE, NULL)<0) TEST_ERROR; + if (H5Gget_objinfo(file2, "mnt1/file2", TRUE, NULL)<0) TEST_ERROR; /* Shut down */ - if (H5Funmount(file1, "/mnt1")<0) goto error; - if (H5Fclose(file1)<0) goto error; - if (H5Fclose(file2)<0) goto error; + if (H5Funmount(file1, "/mnt1")<0) TEST_ERROR; + if (H5Fclose(file1)<0) TEST_ERROR; + if (H5Fclose(file2)<0) TEST_ERROR; PASSED(); return 0; diff --git a/test/tfile.c b/test/tfile.c index 5955562..0e1e7ec 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -65,6 +65,10 @@ #define OBJ_ID_COUNT_6 6 #define OBJ_ID_COUNT_8 8 +#define GROUP1 "Group1" +#define DSET1 "Dataset1" +#define DSET2 "/Group1/Dataset2" + static void create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *); static void @@ -176,7 +180,7 @@ test_file_create(void) ret = H5Pset_userblock(tmpl1, F2_USERBLOCK_SIZE); CHECK(ret, FAIL, "H5Pset_userblock"); - ret = H5Pset_sizes(tmpl1, F2_OFFSET_SIZE, F2_LENGTH_SIZE); + ret = H5Pset_sizes(tmpl1, (size_t)F2_OFFSET_SIZE, (size_t)F2_LENGTH_SIZE); CHECK(ret, FAIL, "H5Pset_sizes"); ret = H5Pset_sym_k(tmpl1, F2_SYM_INTERN_K, F2_SYM_LEAF_K); @@ -535,9 +539,10 @@ test_file_close(void) /* Create a dataset and a group in each file open respectively */ create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3); - /* Close first open */ + /* Close first open, should fail since it is SEMI and objects are + * still open. */ ret = H5Fclose(fid1); - CHECK(ret, FAIL, "H5Fclose"); + VERIFY(ret, FAIL, "H5Fclose"); /* Close second open, should fail since it is SEMI and objects are * still open. */ @@ -547,6 +552,10 @@ test_file_close(void) ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); + /* Close first open */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Gclose(group_id1); CHECK(ret, FAIL, "H5Gclose"); @@ -774,7 +783,7 @@ create_objects(hid_t fid1, hid_t fid2, hid_t *ret_did, hid_t *ret_gid1, /* Create a group in the second file open */ { hid_t gid1, gid2, gid3; - gid1 = H5Gcreate(fid2, "/group", 0); + gid1 = H5Gcreate(fid2, "/group", (size_t)0); CHECK(gid1, FAIL, "H5Gcreate"); if(ret_gid1 != NULL) *ret_gid1 = gid1; @@ -837,7 +846,7 @@ test_get_file_id(void) /* Create a group in the file. Make a duplicated file ID from the group. * And close this duplicated ID */ - group_id = H5Gcreate(fid, GRP_NAME, 0); + group_id = H5Gcreate(fid, GRP_NAME, (size_t)0); CHECK(group_id, FAIL, "H5Gcreate"); /* Test H5Iget_file_id() */ @@ -1280,7 +1289,7 @@ test_file_ishdf5(void) buf[u]=(unsigned char)u; /* Write some information */ - nbytes = HDwrite(fd, buf, 1024); + nbytes = HDwrite(fd, buf, (size_t)1024); VERIFY(nbytes, 1024, "HDwrite"); /* Close the file */ @@ -1318,7 +1327,7 @@ test_file_open_dot(void) CHECK(fid, FAIL, "H5Fcreate"); /* Create a group in the HDF5 file */ - gid = H5Gcreate(fid, GRP_NAME, 0); + gid = H5Gcreate(fid, GRP_NAME, (size_t)0); CHECK(gid, FAIL, "H5Gcreate"); /* Create a dataspace for creating datasets */ @@ -1379,13 +1388,13 @@ test_file_open_dot(void) /* Create a group with no name using the file ID */ H5E_BEGIN_TRY { - gid2 = H5Gcreate(fid, ".", 0); + gid2 = H5Gcreate(fid, ".", (size_t)0); } H5E_END_TRY; VERIFY(gid2, FAIL, "H5Gcreate"); /* Create a group with no name using the group ID */ H5E_BEGIN_TRY { - gid2 = H5Gcreate(gid, ".", 0); + gid2 = H5Gcreate(gid, ".", (size_t)0); } H5E_END_TRY; VERIFY(gid2, FAIL, "H5Gcreate"); @@ -1418,6 +1427,84 @@ test_file_open_dot(void) /**************************************************************** ** +** test_file_open_overlap(): low-level file test routine. +** This test checks whether opening files in an overlapping way +** (as opposed to a nested manner) works correctly. +** +*****************************************************************/ +static void +test_file_open_overlap(void) +{ + hid_t fid1, fid2; + hid_t did1, did2; + hid_t gid; + hid_t sid; + int nobjs; /* # of open objects */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing opening overlapping file opens\n")); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + assert(fid1 > 0); + + /* Open file also */ + fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + assert(fid2 > 0); + + /* Create a group in file */ + gid = H5Gcreate(fid1, GROUP1, (size_t)0); + assert(gid > 0); + + /* Create dataspace for dataset */ + sid = H5Screate(H5S_SCALAR); + assert(sid > 0); + + /* Create dataset in group w/first file ID */ + did1 = H5Dcreate(gid, DSET1, H5T_NATIVE_INT, sid, H5P_DEFAULT); + assert(did1 > 0); + + /* 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 */ + + /* Close dataset */ + ret = H5Dclose(did1); + assert(ret >= 0); + + /* Close group */ + ret = H5Gclose(gid); + assert(ret >= 0); + + /* Close first file ID */ + ret = H5Fclose(fid1); + assert(ret >= 0); + + + /* Create dataset with second file ID */ + did2 = H5Dcreate(fid2, DSET2, H5T_NATIVE_INT, sid, H5P_DEFAULT); + assert(did2 > 0); + + /* Check number of objects opened in first file */ + nobjs = H5Fget_obj_count(fid2, H5F_OBJ_ALL); + assert(nobjs == 2); /* 2 == file & dataset */ + + /* Close dataspace */ + ret = H5Sclose(sid); + assert(ret >= 0); + + /* Close second dataset */ + ret = H5Dclose(did2); + assert(ret >= 0); + + /* Close second file */ + ret = H5Fclose(fid2); + assert(ret >= 0); +} /* end test_file_open_overlap() */ + +/**************************************************************** +** ** test_file(): Main low-level file I/O test routine. ** ****************************************************************/ @@ -1437,6 +1524,7 @@ test_file(void) test_file_freespace(); /* Test file free space information */ 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() */ |