From 80f20333264434b449ba014161899a6d7b522b98 Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Fri, 16 Oct 1998 10:40:37 -0500 Subject: [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. --- bin/trace | 1 + src/.distdep | 264 +++++++++++++++++++++++++++---------------------------- src/H5.c | 24 +++++ src/H5F.c | 109 ++++++++++++++++++----- src/H5Fprivate.h | 9 +- src/H5Fpublic.h | 8 +- src/H5O.c | 3 +- test/.distdep | 154 ++++++++++++++++++-------------- test/cmpd_dset.c | 1 - test/mount.c | 29 ++++-- test/unlink.c | 1 + 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; imtab.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; imtab.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"); -- cgit v0.12