summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-10-16 15:40:37 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-10-16 15:40:37 (GMT)
commit80f20333264434b449ba014161899a6d7b522b98 (patch)
tree0188b179ec625f3aeea1ee349e7dc53b1598c283
parent194c45d07d5fd876e6ada1e27148035f223a0e29 (diff)
downloadhdf5-80f20333264434b449ba014161899a6d7b522b98.zip
hdf5-80f20333264434b449ba014161899a6d7b522b98.tar.gz
hdf5-80f20333264434b449ba014161899a6d7b522b98.tar.bz2
[svn-r764] Changes since 19981014
---------------------- ./bin/trace ./src/H5.c ./src/H5F.c ./src/H5Fprivate.h ./src/H5Fpublic.h Added a `scope' argument to H5Fflush() which should be either H5F_SCOPE_LOCAL or H5F_SCOPE_GLOBAL and determines which files are flushed (just the specified file or the entire virtual file). ./src/H5F.c Added reference counts to the H5F_t struct so we get the correct behavior between H5Funmount() and H5Fclose(). ./src/H5O.c Fixed a memory leak that happens during error handling. ./test/cmpd_dset.c ./test/unlink.c Fixed a memory leak. ./test/mount.c Enabled the H5Fclose() test.
-rwxr-xr-xbin/trace1
-rw-r--r--src/.distdep264
-rw-r--r--src/H5.c24
-rw-r--r--src/H5F.c109
-rw-r--r--src/H5Fprivate.h9
-rw-r--r--src/H5Fpublic.h8
-rw-r--r--src/H5O.c3
-rw-r--r--test/.distdep154
-rw-r--r--test/cmpd_dset.c1
-rw-r--r--test/mount.c29
-rw-r--r--test/unlink.c1
11 files changed, 369 insertions, 234 deletions
diff --git a/bin/trace b/bin/trace
index d8f6454..67ca384 100755
--- a/bin/trace
+++ b/bin/trace
@@ -22,6 +22,7 @@ $Source = "";
"H5E_direction_t" => "Ed",
"H5E_error_t*" => "Ee",
"H5F_driver_t" => "Fd",
+ "H5F_scope_t" => "Fs",
"H5G_link_t" => "Gl",
"H5G_stat_t*" => "Gs",
"hsize_t" => "h",
diff --git a/src/.distdep b/src/.distdep
index d76c013..6571d93 100644
--- a/src/.distdep
+++ b/src/.distdep
@@ -93,6 +93,44 @@ H5B.o: \
H5MFprivate.h \
H5MFpublic.h \
H5MMprivate.h
+H5D.o: \
+ H5D.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5ACprivate.h \
+ H5ACpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Dpublic.h \
+ H5Dprivate.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5HLprivate.h \
+ H5HLpublic.h \
+ H5MFprivate.h \
+ H5MFpublic.h \
+ H5MMprivate.h \
+ H5MMpublic.h \
+ H5Pprivate.h \
+ H5Ppublic.h \
+ H5TBprivate.h
H5E.o: \
H5E.c \
H5private.h \
@@ -101,6 +139,39 @@ H5E.o: \
H5Iprivate.h \
H5Ipublic.h \
H5Eprivate.h
+H5F.o: \
+ H5F.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5Aprivate.h \
+ H5Apublic.h \
+ H5Ipublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Dpublic.h \
+ H5Dprivate.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Iprivate.h \
+ H5ACprivate.h \
+ H5ACpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5MMprivate.h \
+ H5MMpublic.h
H5Farray.o: \
H5Farray.c \
H5private.h \
@@ -253,6 +324,39 @@ H5Fstdio.o: \
H5Dpublic.h \
H5MMprivate.h \
H5MMpublic.h
+H5G.o: \
+ H5G.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5Aprivate.h \
+ H5Apublic.h \
+ H5Ipublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Dpublic.h \
+ H5Dprivate.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Gpkg.h \
+ H5ACprivate.h \
+ H5ACpublic.h \
+ H5HLprivate.h \
+ H5HLpublic.h
H5Gent.o: \
H5Gent.c \
H5private.h \
@@ -753,6 +857,34 @@ H5P.o: \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h
+H5R.o: \
+ H5R.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Rprivate.h
H5RA.o: \
H5RA.c \
H5RAprivate.h \
@@ -1079,135 +1211,3 @@ H5Z.o: \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h
-H5D.o: \
- H5D.c \
- H5private.h \
- H5public.h \
- H5config.h \
- H5Iprivate.h \
- H5Ipublic.h \
- H5ACprivate.h \
- H5ACpublic.h \
- H5Fprivate.h \
- H5Fpublic.h \
- H5Dpublic.h \
- H5Dprivate.h \
- H5Gprivate.h \
- H5Gpublic.h \
- H5Bprivate.h \
- H5Bpublic.h \
- H5Oprivate.h \
- H5Opublic.h \
- H5HGprivate.h \
- H5HGpublic.h \
- H5Tprivate.h \
- H5Tpublic.h \
- H5Sprivate.h \
- H5Spublic.h \
- H5Zprivate.h \
- H5Zpublic.h \
- H5Eprivate.h \
- H5Epublic.h \
- H5HLprivate.h \
- H5HLpublic.h \
- H5MFprivate.h \
- H5MFpublic.h \
- H5MMprivate.h \
- H5MMpublic.h \
- H5Pprivate.h \
- H5Ppublic.h \
- H5TBprivate.h
-H5R.o: \
- H5R.c \
- H5private.h \
- H5public.h \
- H5config.h \
- H5Iprivate.h \
- H5Ipublic.h \
- H5Dprivate.h \
- H5Dpublic.h \
- H5Fprivate.h \
- H5Fpublic.h \
- H5Gprivate.h \
- H5Gpublic.h \
- H5Bprivate.h \
- H5Bpublic.h \
- H5Oprivate.h \
- H5Opublic.h \
- H5HGprivate.h \
- H5HGpublic.h \
- H5Tprivate.h \
- H5Tpublic.h \
- H5Sprivate.h \
- H5Spublic.h \
- H5Zprivate.h \
- H5Zpublic.h \
- H5Eprivate.h \
- H5Epublic.h \
- H5Rprivate.h
-H5F.o: \
- H5F.c \
- H5private.h \
- H5public.h \
- H5config.h \
- H5Aprivate.h \
- H5Apublic.h \
- H5Ipublic.h \
- H5Gprivate.h \
- H5Gpublic.h \
- H5Bprivate.h \
- H5Bpublic.h \
- H5Fprivate.h \
- H5Fpublic.h \
- H5Dpublic.h \
- H5Dprivate.h \
- H5Oprivate.h \
- H5Opublic.h \
- H5HGprivate.h \
- H5HGpublic.h \
- H5Tprivate.h \
- H5Tpublic.h \
- H5Sprivate.h \
- H5Spublic.h \
- H5Zprivate.h \
- H5Zpublic.h \
- H5Iprivate.h \
- H5ACprivate.h \
- H5ACpublic.h \
- H5Eprivate.h \
- H5Epublic.h \
- H5MMprivate.h \
- H5MMpublic.h
-H5G.o: \
- H5G.c \
- H5private.h \
- H5public.h \
- H5config.h \
- H5Aprivate.h \
- H5Apublic.h \
- H5Ipublic.h \
- H5Gprivate.h \
- H5Gpublic.h \
- H5Bprivate.h \
- H5Bpublic.h \
- H5Fprivate.h \
- H5Fpublic.h \
- H5Dpublic.h \
- H5Dprivate.h \
- H5Oprivate.h \
- H5Opublic.h \
- H5HGprivate.h \
- H5HGpublic.h \
- H5Tprivate.h \
- H5Tpublic.h \
- H5Sprivate.h \
- H5Spublic.h \
- H5Zprivate.h \
- H5Zpublic.h \
- H5Eprivate.h \
- H5Epublic.h \
- H5Gpkg.h \
- H5ACprivate.h \
- H5ACpublic.h \
- H5HLprivate.h \
- H5HLpublic.h
diff --git a/src/H5.c b/src/H5.c
index 3fc25d7..f0de26e 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -1404,6 +1404,30 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...)
}
break;
+ case 's':
+ if (ptr) {
+ if (vp) {
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ } else {
+ fprintf(out, "NULL");
+ }
+ } else {
+ H5F_scope_t scope = va_arg(ap, H5F_scope_t);
+ switch (scope) {
+ case H5F_SCOPE_LOCAL:
+ fprintf(out, "H5F_SCOPE_LOCAL");
+ break;
+ case H5F_SCOPE_GLOBAL:
+ fprintf(out, "H5F_SCOPE_GLOBAL");
+ break;
+ case H5F_SCOPE_DOWN:
+ fprintf(out, "H5F_SCOPE_DOWN "
+ "/*FOR INTERNAL USE ONLY!*/");
+ break;
+ }
+ }
+ break;
+
default:
fprintf(out, "BADTYPE(F%c)", type[1]);
goto error;
diff --git a/src/H5F.c b/src/H5F.c
index ac5d2fd..b50614d 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -110,7 +110,7 @@ static void H5F_term_interface(void);
static H5F_t *H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl,
const H5F_access_t *fapl);
static herr_t H5F_dest(H5F_t *f);
-static herr_t H5F_flush(H5F_t *f, hbool_t invalidate);
+static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate);
static herr_t H5F_locate_signature(H5F_low_t *f_handle,
const H5F_access_t *access_parms,
haddr_t *addr/*out*/);
@@ -583,6 +583,7 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl)
H5F_istore_init (f);
}
f->shared->nrefs++;
+ f->nrefs = 1;
ret_value = f;
done:
@@ -613,6 +614,10 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl)
*
* Modifications:
*
+ * Robb Matzke, 1998-10-14
+ * Nothing happens unless the reference count for the H5F_t goes to
+ * zero. The reference counts are decremented here.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -622,8 +627,8 @@ H5F_dest(H5F_t *f)
FUNC_ENTER(H5F_dest, FAIL);
- if (f) {
- if (0 == --(f->shared->nrefs)) {
+ if (f && 0 == --f->nrefs) {
+ if (0 == --f->shared->nrefs) {
/*
* Do not close the root group since we didn't count it, but free
* the memory associated with it.
@@ -644,6 +649,8 @@ H5F_dest(H5F_t *f)
f->shared = H5MM_xfree(f->shared);
}
f->name = H5MM_xfree(f->name);
+ f->mtab.child = H5MM_xfree(f->mtab.child);
+ f->mtab.nalloc = 0;
H5MM_xfree(f);
}
FUNC_LEAVE(ret_value);
@@ -935,7 +942,7 @@ H5F_open(const char *name, uintn flags,
f->shared->base_addr = f->shared->boot_addr;
f->shared->consist_flags = 0x03;
- if (H5F_flush(f, FALSE) < 0) {
+ if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE) < 0) {
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL,
"unable to write file boot block");
}
@@ -1133,8 +1140,9 @@ H5F_open(const char *name, uintn flags,
* Modifications:
*
* Robb Matzke, 18 Jul 1997
- * File struct creation and destruction is through H5F_new() H5F_dest().
- * Writing the root symbol table entry is done with H5G_encode().
+ * File struct creation and destruction is through H5F_new() and
+ * H5F_dest(). Writing the root symbol table entry is done with
+ * H5G_encode().
*
* Robb Matzke, 29 Aug 1997
* Moved creation of the boot block to H5F_flush().
@@ -1251,8 +1259,9 @@ H5Fcreate(const char *filename, unsigned flags, hid_t create_id,
* Modifications:
*
* Robb Matzke, 18 Jul 1997
- * File struct creation and destruction is through H5F_new() H5F_dest().
- * Reading the root symbol table entry is done with H5G_decode().
+ * File struct creation and destruction is through H5F_new() and
+ * H5F_dest(). Reading the root symbol table entry is done with
+ * H5G_decode().
*
* Robb Matzke, 23 Sep 1997
* Most of the work is now done by H5F_open() since H5Fcreate() and
@@ -1331,10 +1340,13 @@ H5Fopen(const char *filename, unsigned flags, hid_t access_id)
*
* Modifications:
*
+ * Robb Matzke, 1998-10-16
+ * Added the `scope' argument.
+ *
*-------------------------------------------------------------------------
*/
herr_t
-H5Fflush(hid_t object_id)
+H5Fflush(hid_t object_id, H5F_scope_t scope)
{
H5F_t *f = NULL;
H5G_t *grp = NULL;
@@ -1344,7 +1356,7 @@ H5Fflush(hid_t object_id)
H5G_entry_t *ent = NULL;
FUNC_ENTER(H5Fflush, FAIL);
- H5TRACE1("e","i",object_id);
+ H5TRACE2("e","iFs",object_id,scope);
switch (H5I_get_type(object_id)) {
case H5I_FILE:
@@ -1404,7 +1416,7 @@ H5Fflush(hid_t object_id)
}
/* Flush the file */
- if (H5F_flush(f, FALSE)<0) {
+ if (H5F_flush(f, scope, FALSE)<0) {
HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
"flush failed");
}
@@ -1435,16 +1447,25 @@ H5Fflush(hid_t object_id)
* Modifications:
* rky 980828 Only p0 writes metadata to disk.
*
+ * Robb Matzke, 1998-10-16
+ * Added the `scope' argument to indicate what should be
+ * flushed. If the value is H5F_SCOPE_GLOBAL then the entire
+ * virtual file is flushed; a value of H5F_SCOPE_LOCAL means
+ * that only the specified file is flushed. A value of
+ * H5F_SCOPE_DOWN means flush the specified file and all
+ * children.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_flush(H5F_t *f, hbool_t invalidate)
+H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate)
{
uint8 buf[2048], *p = buf;
haddr_t reserved_addr;
+ uintn nerrors=0, i;
FUNC_ENTER(H5F_flush, FAIL);
-
+
/*
* Nothing to do if the file is read only. This determination is made at
* the shared open(2) flags level, implying that opening a file twice,
@@ -1455,6 +1476,19 @@ H5F_flush(H5F_t *f, hbool_t invalidate)
HRETURN(SUCCEED);
}
+ /* Flush other stuff depending on scope */
+ if (H5F_SCOPE_GLOBAL==scope) {
+ while (f->mtab.parent) f = f->mtab.parent;
+ scope = H5F_SCOPE_DOWN;
+ }
+ if (H5F_SCOPE_DOWN==scope) {
+ for (i=0; i<f->mtab.nmounts; i++) {
+ if (H5F_flush(f->mtab.child[i].file, scope, invalidate)<0) {
+ nerrors++;
+ }
+ }
+ }
+
/* flush the entire raw data cache */
if (H5F_istore_flush (f, invalidate)<0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
@@ -1512,6 +1546,9 @@ H5F_flush(H5F_t *f, hbool_t invalidate)
if (H5F_low_flush(f->shared->lf, f->shared->access_parms) < 0) {
HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed");
}
+
+ /* Check flush errors for children - errors are already on the stack */
+ if (nerrors) HRETURN(FAIL);
FUNC_LEAVE(SUCCEED);
}
@@ -1519,7 +1556,9 @@ H5F_flush(H5F_t *f, hbool_t invalidate)
/*-------------------------------------------------------------------------
* Function: H5F_close
*
- * Purpose: Closes an open HDF5 file.
+ * Purpose: Closes an open HDF5 file. From the API this function gets
+ * called when a file hid_t reference count gets to zero as a
+ * result of calling H5Fclose().
*
* Return: Success: SUCCEED
*
@@ -1530,6 +1569,11 @@ H5F_flush(H5F_t *f, hbool_t invalidate)
*
* Modifications:
*
+ * Robb Matzke, 1998-10-14
+ * Nothing happens unless the H5F_t reference count is one (the
+ * file is flushed anyway). The reference count is decremented by
+ * H5F_dest().
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1540,13 +1584,25 @@ H5F_close(H5F_t *f)
FUNC_ENTER(H5F_close, FAIL);
/*
- * Find the root of the virtual file. Then unmount and close each child
- * before closing the current file.
+ * If the reference count is positive then just decrement the count and
+ * flush the file.
*/
- while (f->mtab.parent) f = f->mtab.parent;
+ if (f->nrefs>1) {
+ if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE)<0) {
+ HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
+ "unable to flush cache");
+ }
+ H5F_dest(f); /*decrement reference counts*/
+ HRETURN(SUCCEED);
+ }
+
+ /*
+ * Unmount and close each child before closing the current file.
+ */
+ assert(NULL==f->mtab.parent);
for (i=0; i<f->mtab.nmounts; i++) {
- H5G_close(f->mtab.child[i].group);
f->mtab.child[i].file->mtab.parent = NULL;
+ H5G_close(f->mtab.child[i].group);
H5F_close(f->mtab.child[i].file);
}
f->mtab.nmounts = 0;
@@ -1558,7 +1614,7 @@ H5F_close(H5F_t *f)
* problem.
*/
if (f->nopen_objs>0) {
- if (H5F_flush(f, FALSE)<0) {
+ if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE)<0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush cache");
}
@@ -1586,9 +1642,9 @@ H5F_close(H5F_t *f)
* If this is the last reference to the shared part of the file then
* close it also.
*/
- if (1==f->shared->nrefs) {
+ if (1==f->nrefs && 1==f->shared->nrefs) {
/* Flush and destroy all caches */
- if (H5F_flush (f, TRUE)<0) {
+ if (H5F_flush (f, H5F_SCOPE_LOCAL, TRUE)<0) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush cache");
}
@@ -1605,7 +1661,7 @@ H5F_close(H5F_t *f)
* this file are closed the flush isn't really necessary, but lets
* just be safe.
*/
- if (H5F_flush(f, TRUE)<0) {
+ if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE)<0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush cache");
}
@@ -1697,6 +1753,9 @@ H5Fclose(hid_t file_id)
*
* Modifications:
*
+ * Robb Matzke, 1998-10-14
+ * The reference count for the mounted H5F_t is incremented.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1781,6 +1840,7 @@ 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++;
ret_value = SUCCEED;
done:
@@ -1811,6 +1871,9 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
*
* Modifications:
*
+ * Robb Matzke, 1998-10-14
+ * The ref count for the child is decremented by calling H5F_close().
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1854,6 +1917,7 @@ H5F_unmount(H5G_entry_t *loc, const char *name)
parent->mtab.nmounts -= 1;
H5G_close(parent->mtab.child[i].group);
child->mtab.parent = NULL;
+ H5F_close(child);
HDmemmove(parent->mtab.child+i,
parent->mtab.child+i+1,
((parent->mtab.nmounts-i)*
@@ -1890,6 +1954,7 @@ H5F_unmount(H5G_entry_t *loc, const char *name)
parent->mtab.nmounts -= 1;
H5G_close(parent->mtab.child[md].group);
parent->mtab.child[md].file->mtab.parent = NULL;
+ H5F_close(parent->mtab.child[md].file);
HDmemmove(parent->mtab.child+md,
parent->mtab.child+md+1,
(parent->mtab.nmounts-md)*sizeof(parent->mtab.child[0]));
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 004c411..4b42665 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -476,6 +476,7 @@ typedef struct H5F_file_t {
* pointers to shared H5F_file_t structs.
*/
typedef struct H5F_t {
+ uintn nrefs; /* Reference count */
uintn intent; /* The flags passed to H5F_open()*/
char *name; /* Name used to open file */
H5F_file_t *shared; /* The shared file info */
@@ -490,9 +491,11 @@ typedef struct H5F_t {
: H5F_SIZEOF_ADDR(f)==2 ? UINT16ENCODE(p,o) \
: H5FPencode_unusual_offset(f,&(p),(uint8 *)&(o)))
#else /* NOT_YET */
-#define H5F_ENCODE_OFFSET(f,p,o) switch(H5F_SIZEOF_ADDR(f)) { case 4: UINT32ENCODE(p,o); break;\
- case 8: UINT64ENCODE(p,o); break;\
- case 2: UINT16ENCODE(p,o); break;}
+#define H5F_ENCODE_OFFSET(f,p,o) switch(H5F_SIZEOF_ADDR(f)) { \
+ case 4: UINT32ENCODE(p,o); break; \
+ case 8: UINT64ENCODE(p,o); break; \
+ case 2: UINT16ENCODE(p,o); break; \
+}
#endif /* NOT_YET */
#define H5F_DECODE_OFFSET(f,p,o) \
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 319eeeb..6a81d52 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -69,6 +69,12 @@ typedef enum H5F_driver_t {
H5F_LOW_FAMILY = 5 /*split addr space over many files */
} H5F_driver_t;
+typedef enum H5F_scope_t {
+ H5F_SCOPE_LOCAL = 0, /*specified file handle only */
+ H5F_SCOPE_GLOBAL = 1, /*entire virtual file */
+ H5F_SCOPE_DOWN = 2 /*for internal use only */
+} H5F_scope_t;
+
/* Unlimited file size for H5Pset_external() */
#define H5F_UNLIMITED ((hsize_t)(-1L))
@@ -81,7 +87,7 @@ hbool_t H5Fis_hdf5 (const char *filename);
hid_t H5Fcreate (const char *filename, unsigned flags, hid_t create_plist,
hid_t access_plist);
hid_t H5Fopen (const char *filename, unsigned flags, hid_t access_plist);
-herr_t H5Fflush(hid_t object_id);
+herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
herr_t H5Fclose (hid_t file_id);
hid_t H5Fget_create_plist (hid_t file_id);
hid_t H5Fget_access_plist (hid_t file_id);
diff --git a/src/H5O.c b/src/H5O.c
index 4386962..0902b1c 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -1189,7 +1189,6 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
*/
H5E_clear ();
flags &= ~H5O_FLAG_SHARED;
- H5MM_xfree (sh_mesg);
} else if (sh_mesg->in_gh) {
/*
* The shared message is stored in the global heap.
@@ -1245,6 +1244,7 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
/* Copy the native value into the object header */
if (flags & H5O_FLAG_SHARED) {
oh->mesg[idx].native = sh_mesg;
+ sh_mesg = NULL;
} else {
if (oh->mesg[idx].native) {
H5O_reset (oh->mesg[idx].type, oh->mesg[idx].native);
@@ -1265,6 +1265,7 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
ret_value = sequence;
done:
+ H5MM_xfree(sh_mesg);
if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, &(ent->header), oh) < 0) {
HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL,
"unable to release object header");
diff --git a/test/.distdep b/test/.distdep
index 915513d..25cfd63 100644
--- a/test/.distdep
+++ b/test/.distdep
@@ -103,6 +103,32 @@ tohdr.o: \
../src/H5Tprivate.h \
../src/H5Tpublic.h \
../src/H5Sprivate.h
+trefer.o: \
+ trefer.c \
+ testhdf5.h \
+ ../src/H5private.h \
+ ../src/H5public.h \
+ ../src/H5config.h \
+ ../src/H5Eprivate.h \
+ ../src/H5Epublic.h \
+ ../src/H5Ipublic.h \
+ ../src/hdf5.h \
+ ../src/H5Apublic.h \
+ ../src/H5ACpublic.h \
+ ../src/H5Bpublic.h \
+ ../src/H5Dpublic.h \
+ ../src/H5Fpublic.h \
+ ../src/H5Gpublic.h \
+ ../src/H5HGpublic.h \
+ ../src/H5HLpublic.h \
+ ../src/H5MFpublic.h \
+ ../src/H5MMpublic.h \
+ ../src/H5Opublic.h \
+ ../src/H5Ppublic.h \
+ ../src/H5Zpublic.h \
+ ../src/H5Rpublic.h \
+ ../src/H5RApublic.h \
+ ../src/H5Spublic.h
tselect.o: \
tselect.c \
testhdf5.h \
@@ -129,6 +155,35 @@ tselect.o: \
../src/H5Rpublic.h \
../src/H5RApublic.h \
../src/H5Spublic.h
+tstab.o: \
+ tstab.c \
+ testhdf5.h \
+ ../src/H5private.h \
+ ../src/H5public.h \
+ ../src/H5config.h \
+ ../src/H5Eprivate.h \
+ ../src/H5Epublic.h \
+ ../src/H5Ipublic.h \
+ ../src/H5Iprivate.h \
+ ../src/H5ACprivate.h \
+ ../src/H5ACpublic.h \
+ ../src/H5Fprivate.h \
+ ../src/H5Fpublic.h \
+ ../src/H5Dpublic.h \
+ ../src/H5Pprivate.h \
+ ../src/H5Ppublic.h \
+ ../src/H5Zpublic.h \
+ ../src/H5Gprivate.h \
+ ../src/H5Gpublic.h \
+ ../src/H5Bprivate.h \
+ ../src/H5Bpublic.h \
+ ../src/H5Oprivate.h \
+ ../src/H5Opublic.h \
+ ../src/H5HGprivate.h \
+ ../src/H5HGpublic.h \
+ ../src/H5Tprivate.h \
+ ../src/H5Tpublic.h \
+ ../src/H5Sprivate.h
th5s.o: \
th5s.c \
testhdf5.h \
@@ -191,6 +246,34 @@ hyperslab.o: \
../src/H5config.h \
../src/H5MMprivate.h \
../src/H5MMpublic.h
+istore.o: \
+ istore.c \
+ ../src/H5private.h \
+ ../src/H5public.h \
+ ../src/H5config.h \
+ ../src/H5Dprivate.h \
+ ../src/H5Dpublic.h \
+ ../src/H5Ipublic.h \
+ ../src/H5Fprivate.h \
+ ../src/H5Fpublic.h \
+ ../src/H5Gprivate.h \
+ ../src/H5Gpublic.h \
+ ../src/H5Bprivate.h \
+ ../src/H5Bpublic.h \
+ ../src/H5Oprivate.h \
+ ../src/H5Opublic.h \
+ ../src/H5HGprivate.h \
+ ../src/H5HGpublic.h \
+ ../src/H5Tprivate.h \
+ ../src/H5Tpublic.h \
+ ../src/H5Sprivate.h \
+ ../src/H5Spublic.h \
+ ../src/H5Zprivate.h \
+ ../src/H5Zpublic.h \
+ ../src/H5Iprivate.h \
+ ../src/H5Pprivate.h \
+ ../src/H5Ppublic.h \
+ ../src/H5MMprivate.h
dsets.o: \
dsets.c \
../src/hdf5.h \
@@ -563,77 +646,17 @@ fillval.o: \
../src/H5RApublic.h \
../src/H5Spublic.h \
../src/H5Tpublic.h
-tstab.o: \
- tstab.c \
- testhdf5.h \
- ../src/H5private.h \
- ../src/H5public.h \
- ../src/H5config.h \
- ../src/H5Eprivate.h \
- ../src/H5Epublic.h \
- ../src/H5Ipublic.h \
- ../src/H5Iprivate.h \
- ../src/H5ACprivate.h \
- ../src/H5ACpublic.h \
- ../src/H5Fprivate.h \
- ../src/H5Fpublic.h \
- ../src/H5Dpublic.h \
- ../src/H5Pprivate.h \
- ../src/H5Ppublic.h \
- ../src/H5Zpublic.h \
- ../src/H5Gprivate.h \
- ../src/H5Gpublic.h \
- ../src/H5Bprivate.h \
- ../src/H5Bpublic.h \
- ../src/H5Oprivate.h \
- ../src/H5Opublic.h \
- ../src/H5HGprivate.h \
- ../src/H5HGpublic.h \
- ../src/H5Tprivate.h \
- ../src/H5Tpublic.h \
- ../src/H5Sprivate.h
-istore.o: \
- istore.c \
- ../src/H5private.h \
- ../src/H5public.h \
- ../src/H5config.h \
- ../src/H5Dprivate.h \
- ../src/H5Dpublic.h \
- ../src/H5Ipublic.h \
- ../src/H5Fprivate.h \
- ../src/H5Fpublic.h \
- ../src/H5Gprivate.h \
- ../src/H5Gpublic.h \
- ../src/H5Bprivate.h \
- ../src/H5Bpublic.h \
- ../src/H5Oprivate.h \
- ../src/H5Opublic.h \
- ../src/H5HGprivate.h \
- ../src/H5HGpublic.h \
- ../src/H5Tprivate.h \
- ../src/H5Tpublic.h \
- ../src/H5Sprivate.h \
- ../src/H5Spublic.h \
- ../src/H5Zprivate.h \
- ../src/H5Zpublic.h \
- ../src/H5Iprivate.h \
- ../src/H5Pprivate.h \
- ../src/H5Ppublic.h \
- ../src/H5MMprivate.h
-trefer.o: \
- trefer.c \
- testhdf5.h \
- ../src/H5private.h \
+mount.o: \
+ mount.c \
+ ../src/hdf5.h \
../src/H5public.h \
../src/H5config.h \
- ../src/H5Eprivate.h \
- ../src/H5Epublic.h \
../src/H5Ipublic.h \
- ../src/hdf5.h \
../src/H5Apublic.h \
../src/H5ACpublic.h \
../src/H5Bpublic.h \
../src/H5Dpublic.h \
+ ../src/H5Epublic.h \
../src/H5Fpublic.h \
../src/H5Gpublic.h \
../src/H5HGpublic.h \
@@ -644,5 +667,4 @@ trefer.o: \
../src/H5Ppublic.h \
../src/H5Zpublic.h \
../src/H5Rpublic.h \
- ../src/H5RApublic.h \
- ../src/H5Spublic.h
+ ../src/H5RApublic.h
diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c
index 94255a4..534f3d6 100644
--- a/test/cmpd_dset.c
+++ b/test/cmpd_dset.c
@@ -742,7 +742,6 @@ main (void)
}
}
}
- free(s11);
puts(" PASSED");
diff --git a/test/mount.c b/test/mount.c
index 516eba8..e5d37ad 100644
--- a/test/mount.c
+++ b/test/mount.c
@@ -986,11 +986,6 @@ test_close(void)
printf("%-70s", "Testing file handle close");
fflush(stdout);
-#if 1
- puts(" SKIP");
- puts(" Skipped for now (until H5F_t refcounts are implemented)...");
- return 0;
-#endif
/* Build the virtual file */
if ((file1=H5Fopen(FILE_NAME_1, H5F_ACC_RDWR, H5P_DEFAULT))<0 ||
@@ -998,16 +993,34 @@ test_close(void)
goto error;
if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
- /* Close by file1 */
+ /*
+ * Close file1 unmounting it from the virtual file. Objects in file2 are
+ * still accessible through the file2 handle, but nothing in file1 is
+ * accessible.
+ */
if (H5Fclose(file1)<0) goto error;
H5E_BEGIN_TRY {
- status = H5Fclose(file2);
+ status = H5Gget_objinfo(file2, "/mnt1", TRUE, NULL);
} H5E_END_TRY;
if (status>=0) {
puts("*FAILED*");
- puts(" File close should have closed all virtual file members!");
+ puts(" File1 contents are still accessible!");
goto error;
}
+ if (H5Fclose(file2)<0) goto error;
+
+ /* Build the virtual file again */
+ if ((file1=H5Fopen(FILE_NAME_1, H5F_ACC_RDWR, H5P_DEFAULT))<0 ||
+ (file2=H5Fopen(FILE_NAME_2, H5F_ACC_RDWR, H5P_DEFAULT))<0)
+ goto error;
+ if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
+
+ /*
+ * Close file2. It is not actually closed because it's a child of file1.
+ */
+ if (H5Fclose(file2)<0) goto error;
+ if (H5Gget_objinfo(file1, "/mnt1/file2", TRUE, NULL)<0) goto error;
+ if (H5Fclose(file1)<0) goto error;
/* Shut down */
puts(" PASSED");
diff --git a/test/unlink.c b/test/unlink.c
index 2340777..a3ec4a2 100644
--- a/test/unlink.c
+++ b/test/unlink.c
@@ -165,6 +165,7 @@ test_many(hid_t file)
/* Create a test group */
if ((work=H5Gcreate(file, "/test_many", 0))<0) goto error;
if ((grp = H5Gcreate(work, "/test_many_foo", 0))<0) goto error;
+ if (H5Gclose(grp)<0) goto error;
/* Create a bunch of names and unlink them in order */
printf("%-70s", "Testing forward unlink");