diff options
author | Robb Matzke <matzke@llnl.gov> | 1999-02-20 16:18:51 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1999-02-20 16:18:51 (GMT) |
commit | e2e5476fa5449ec941ff19f07bada9725431688f (patch) | |
tree | 33f6af7c15322663582c4a736dc0e9b087f38530 | |
parent | 35a62b068bc6b124004d331c3e949d571682417a (diff) | |
download | hdf5-e2e5476fa5449ec941ff19f07bada9725431688f.zip hdf5-e2e5476fa5449ec941ff19f07bada9725431688f.tar.gz hdf5-e2e5476fa5449ec941ff19f07bada9725431688f.tar.bz2 |
[svn-r1087] Changes since 19990218
----------------------
./src/H5F.c
./src/H5private.h
./src/H5Ipublic.h
./src/H5O.c
Fixed a rather nasty bug with file closing that caused the
file boot block to be updated incorrectly, effectively
truncating the file. The bug I fixed was triggered by:
1. Create a file, F
2. Open an object, X
3. Close file F
4. Reopen file F for read/write.
5. Create and close some objects
6. Close file F
7. Close library (exit).
Step 3 pended the close because object X is still open, but
the file ID was removed from the H5I_FILE ID group. Step 4
created a new file because it didn't see any matching file on
the H5I_FILE ID group. Step 5 extends the file. Step 6 writes
the new file boot block to disk. Step 7 closes object X and
completes the close from step 3, writing the old boot block
information to disk.
The new behavior is that step 3 moves the file from the
H5I_FILE group to the H5I_FILE_CLOSING group. Step 4 searches
both groups and finds the file. Step 5 extends the file using
the same H5F_file_t struct as step 3. Step 6 closes the H5F_t
struct opened in step 3 but not the H5F_file_t struct shared
by steps 1 and 3. Step 7 closes object X which closes the
H5F_file_t from step 1, flushing the boot block which was
shared by all steps.
./src/H5F.c
Added some bulletproofing to file reference counting and
removed comments which no longer apply. Added H5F_flush_all()
and H5F_close_all() which apply to all files.
./src/H5A.c
./src/H5D.c
./src/H5F.c
./src/H5G.c
./src/H5I.c
./src/H5Iprivate.h
./src/H5R.c
./src/H5RA.c
./src/H5S.c
./src/H5T.c
Added the new H5I_free_t data type to describe the function
type to be passed as the `free_func' argument to
H5I_init_group().
./src/H5I.c
Bulletproofed the object removal functions. Removed comments
which no longer apply. Changed global variable names so they
don't violate the naming scheme. Added H5I_debug() that prints
the contents of an ID group. Removed H5I_inc_ref() because it
isn't used. Reindented a couple of functions.
./src/H5.c
./src/H5G.c
./src/H5Ipublic.h
Changed H5I_MAXID to H5I_NGROUPS to better relect the fact
that it's the total number of valid ID groups.
./src/H5Shyper.c
Changed hyperslab offset arrays to signed quantities to get
rid of warnings on DEC cluster.
./src/H5Flow.c
./src/H5Fprivate.h
Changed the objno argument of H5F_addr_pack() to be unsigned
to get rid of warnings on DEC cluster.
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | src/.distdep | 774 | ||||
-rw-r--r-- | src/H5.c | 10 | ||||
-rw-r--r-- | src/H5A.c | 42 | ||||
-rw-r--r-- | src/H5ACprivate.h | 30 | ||||
-rw-r--r-- | src/H5D.c | 14 | ||||
-rw-r--r-- | src/H5Distore.c | 4 | ||||
-rw-r--r-- | src/H5Dprivate.h | 26 | ||||
-rw-r--r-- | src/H5F.c | 291 | ||||
-rw-r--r-- | src/H5Fistore.c | 4 | ||||
-rw-r--r-- | src/H5Fprivate.h | 64 | ||||
-rw-r--r-- | src/H5G.c | 11 | ||||
-rw-r--r-- | src/H5I.c | 878 | ||||
-rw-r--r-- | src/H5Iprivate.h | 87 | ||||
-rw-r--r-- | src/H5Ipublic.h | 65 | ||||
-rw-r--r-- | src/H5O.c | 8 | ||||
-rw-r--r-- | src/H5P.c | 2 | ||||
-rw-r--r-- | src/H5R.c | 8 | ||||
-rw-r--r-- | src/H5RA.c | 2 | ||||
-rw-r--r-- | src/H5S.c | 2 | ||||
-rw-r--r-- | src/H5T.c | 6 |
21 files changed, 1273 insertions, 1057 deletions
@@ -1,4 +1,4 @@ -This is hdf5-1.1.43 released on Fri Feb 19 04:18:33 CST 1999 +This is hdf5-1.1.43 released on Fri Feb 19 09:30:24 EST 1999 Please refer to the INSTALL file for installation instructions. ------------------------------------------------------------------------------ diff --git a/src/.distdep b/src/.distdep index 975bda6..45195ce 100644 --- a/src/.distdep +++ b/src/.distdep @@ -1,67 +1,3 @@ -H5.o: \ - H5.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5ACprivate.h \ - H5ACpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Ipublic.h \ - H5Dpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Iprivate.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Pprivate.h \ - H5Ppublic.h \ - H5Zpublic.h \ - H5Rpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h -H5A.o: \ - H5A.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Iprivate.h \ - H5Ipublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5Dprivate.h \ - H5Gprivate.h \ - H5Gpublic.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 \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Pprivate.h \ - H5Ppublic.h H5AC.o: \ H5AC.c \ H5private.h \ @@ -91,43 +27,6 @@ H5B.o: \ H5Eprivate.h \ H5Epublic.h \ H5MFprivate.h -H5D.o: \ - H5D.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.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 H5E.o: \ H5E.c \ H5private.h \ @@ -135,38 +34,6 @@ H5E.o: \ H5config.h \ H5api_adpt.h \ H5Iprivate.h -H5F.o: \ - H5F.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.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 H5Farray.o: \ H5Farray.c \ H5private.h \ @@ -218,33 +85,18 @@ H5Ffamily.o: \ H5Fprivate.h \ H5Fpublic.h \ H5Dpublic.h -H5Fistore.o: \ - H5Fistore.c \ +H5Flow.o: \ + H5Flow.c \ H5private.h \ H5public.h \ H5config.h \ H5api_adpt.h \ - H5Dprivate.h \ - H5Dpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ H5Ipublic.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 + H5Dpublic.h H5Fmpio.o: \ H5Fmpio.c \ H5private.h \ @@ -308,43 +160,6 @@ H5Fstdio.o: \ H5Fprivate.h \ H5Fpublic.h \ H5Dpublic.h -H5G.o: \ - H5G.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.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 \ - H5Iprivate.h \ - H5MMprivate.h \ - H5MMpublic.h H5Gent.o: \ H5Gent.c \ H5private.h \ @@ -465,13 +280,6 @@ H5HL.o: \ H5HLprivate.h \ H5HLpublic.h \ H5MFprivate.h -H5I.o: \ - H5I.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Iprivate.h H5MF.o: \ H5MF.c \ H5private.h \ @@ -491,60 +299,6 @@ H5MM.o: \ H5config.h \ H5api_adpt.h \ H5Eprivate.h -H5O.o: \ - H5O.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5ACprivate.h \ - H5ACpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Ipublic.h \ - H5Dpublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MFprivate.h \ - H5MFpublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h -H5Oattr.o: \ - H5Oattr.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Ipublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Zprivate.h H5Ocomp.o: \ H5Ocomp.c \ H5private.h \ @@ -864,73 +618,20 @@ H5Ostab.o: \ H5Sprivate.h \ H5Spublic.h \ H5Zprivate.h -H5P.o: \ - H5P.c \ +H5Sall.o: \ + H5Sall.c \ H5private.h \ H5public.h \ H5config.h \ H5api_adpt.h \ - H5Iprivate.h \ + H5Eprivate.h \ + H5Epublic.h \ H5Ipublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5Dprivate.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ H5Sprivate.h \ H5Spublic.h \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Eprivate.h -H5R.o: \ - H5R.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.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 -H5RA.o: \ - H5RA.c \ - H5RAprivate.h \ - H5RApublic.h \ - H5Ipublic.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Dprivate.h \ H5Dpublic.h \ - H5private.h \ - H5Fprivate.h \ - H5Fpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -941,44 +642,11 @@ H5RA.o: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Iprivate.h \ - H5MMprivate.h \ - H5MMpublic.h -H5S.o: \ - H5S.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Iprivate.h \ - H5Ipublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h -H5Sall.o: \ - H5Sall.c \ + H5Vprivate.h +H5Shyper.o: \ + H5Shyper.c \ H5private.h \ H5public.h \ H5config.h \ @@ -1107,38 +775,6 @@ H5Sselect.o: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h -H5T.o: \ - H5T.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Dprivate.h \ - H5Dpublic.h \ - H5Ipublic.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 \ - H5Iprivate.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Tpkg.h \ - H5Rprivate.h H5Tbit.o: \ H5Tbit.c \ H5private.h \ @@ -1268,42 +904,416 @@ H5Z.o: \ H5Sprivate.h \ H5Spublic.h \ H5Zprivate.h -H5Flow.o: \ - H5Flow.c \ +H5P.o: \ + H5P.c \ H5private.h \ H5public.h \ H5config.h \ H5api_adpt.h \ + H5Iprivate.h \ + H5Ipublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Dpublic.h \ + H5Dprivate.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h +H5T.o: \ + H5T.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Iprivate.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 \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Tpkg.h \ + H5Rprivate.h +H5A.o: \ + H5A.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h \ H5Ipublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h -H5Shyper.o: \ - H5Shyper.c \ + H5Dpublic.h \ + H5Dprivate.h \ + H5Gprivate.h \ + H5Gpublic.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 \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Pprivate.h \ + H5Ppublic.h +H5D.o: \ + H5D.c \ H5private.h \ H5public.h \ H5config.h \ H5api_adpt.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 +H5Fistore.o: \ + H5Fistore.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Dprivate.h \ + H5Dpublic.h \ H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Iprivate.h \ + H5Tprivate.h \ + H5Tpublic.h \ H5Sprivate.h \ H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5MFprivate.h \ + H5MFpublic.h \ + H5MMprivate.h \ + H5MMpublic.h +H5G.o: \ + H5G.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.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 \ + H5Iprivate.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 \ + H5MMprivate.h \ + H5MMpublic.h +H5Oattr.o: \ + H5Oattr.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Dpublic.h \ + H5MMprivate.h \ + H5MMpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ H5HGpublic.h \ + H5Iprivate.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h +H5R.o: \ + H5R.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.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 \ - H5Vprivate.h + H5Eprivate.h +H5RA.o: \ + H5RA.c \ + H5RAprivate.h \ + H5RApublic.h \ + H5Ipublic.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5private.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Iprivate.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5MMprivate.h \ + H5MMpublic.h +H5S.o: \ + H5S.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h \ + H5Ipublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Dpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h +H5.o: \ + H5.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Ipublic.h \ + H5Dpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Iprivate.h \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Pprivate.h \ + H5Ppublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h +H5F.o: \ + H5F.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.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 \ + H5Iprivate.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5Eprivate.h \ + H5Epublic.h +H5I.o: \ + H5I.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h +H5O.o: \ + H5O.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Ipublic.h \ + H5Dpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Iprivate.h \ + H5MFprivate.h \ + H5MFpublic.h \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h @@ -150,9 +150,7 @@ H5_term_library(void) * (because H5F_close() can delay until all object headers are * closed). We handle this cycle by calling H5F_close() for all * files, which flushes the meta data caches and updates the file - * boot block but doesn't actually finalize the close until all - * open objects are closed by the H5*_term_interface() functions - * below. Once that happens we can close the H5F interface. + * boot block. */ H5F_close_all(); @@ -168,7 +166,7 @@ H5_term_library(void) H5S_term_interface(-1); /* */ H5T_native_close(-1); /* D RA */ H5T_term_interface(-1); /* D RA */ - H5P_term_interface(-1); /* D */ + H5P_term_interface(-1); /* D F */ H5F_term_interface(-1); /* A D G S T */ H5I_term_interface(-1); /* A D F G P RA S T TB Z */ /*------------------------- --------------------------------- */ @@ -1804,8 +1802,8 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case H5I_REFERENCE: fprintf (out, "H5I_REFERENCE"); break; - case H5I_MAXID: - fprintf (out, "H5I_MAXID"); + case H5I_NGROUPS: + fprintf (out, "H5I_NGROUPS"); break; default: fprintf (out, "%ld", (long)id_type); @@ -68,7 +68,7 @@ H5A_init_interface(void) * Create attribute group. */ if (H5I_init_group(H5I_ATTR, H5I_ATTRID_HASHSIZE, H5A_RESERVED_ATOMS, - (herr_t (*)(void *)) H5A_close)<0) { + (H5I_free_t)H5A_close)<0) { HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -285,8 +285,7 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, done: if (ret_value < 0) { - if(attr) - H5A_close(attr); + if(attr) H5A_close(attr); } FUNC_LEAVE(ret_value); @@ -522,8 +521,7 @@ H5A_open(H5G_entry_t *ent, unsigned idx) done: if (ret_value < 0) { - if(attr) - H5A_close(attr); + if(attr) H5A_close(attr); } FUNC_LEAVE(ret_value); @@ -928,21 +926,21 @@ H5Aget_type(hid_t attr_id) * reopen the type before returning it to the user. Make the type * read-only. */ - if (NULL==(dst=H5T_copy (attr->dt, H5T_COPY_REOPEN))) { - HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, - "unable to copy datatype"); + if (NULL==(dst=H5T_copy(attr->dt, H5T_COPY_REOPEN))) { + HRETURN_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, + "unable to copy datatype"); } - if (H5T_lock (dst, FALSE)<0) { - H5T_close (dst); - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to lock transient data type"); + if (H5T_lock(dst, FALSE)<0) { + H5T_close(dst); + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to lock transient data type"); } /* Atomize */ - if ((ret_value=H5I_register (H5I_DATATYPE, dst))<0) { - H5T_close (dst); - HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, - "unable to register datatype atom"); + if ((ret_value=H5I_register(H5I_DATATYPE, dst))<0) { + H5T_close(dst); + HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register datatype atom"); } FUNC_LEAVE(ret_value); @@ -1377,16 +1375,12 @@ H5A_close(H5A_t *attr) /* Free dynamicly allocated items */ if(attr->name) H5MM_xfree(attr->name); - if(attr->dt) - H5T_close(attr->dt); - if(attr->ds) - H5S_close(attr->ds); - if(attr->data) - H5MM_xfree(attr->data); + if(attr->dt) H5T_close(attr->dt); + if(attr->ds) H5S_close(attr->ds); + if(attr->data) H5MM_xfree(attr->data); /* Close the object's symbol-table entry */ - if(attr->ent_opened) - H5O_close(&(attr->ent)); + if(attr->ent_opened) H5O_close(&(attr->ent)); #ifndef LATER /* Do something with the shared information? */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 96fc6f9..3a911a7 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -106,23 +106,23 @@ typedef struct H5AC_t { /* * Library prototypes. */ -__DLL__ herr_t H5AC_dest (H5F_t *f); -__DLL__ void *H5AC_find_f (H5F_t *f, const H5AC_class_t *type, +__DLL__ herr_t H5AC_dest(H5F_t *f); +__DLL__ void *H5AC_find_f(H5F_t *f, const H5AC_class_t *type, + const haddr_t *addr, const void *udata1, + void *udata2); +__DLL__ void *H5AC_protect(H5F_t *f, const H5AC_class_t *type, const haddr_t *addr, const void *udata1, void *udata2); -__DLL__ void *H5AC_protect (H5F_t *f, const H5AC_class_t *type, - const haddr_t *addr, const void *udata1, - void *udata2); -__DLL__ herr_t H5AC_unprotect (H5F_t *f, const H5AC_class_t *type, - const haddr_t *addr, void *thing); -__DLL__ herr_t H5AC_flush (H5F_t *f, const H5AC_class_t *type, - const haddr_t *addr, hbool_t destroy); -__DLL__ herr_t H5AC_create (H5F_t *f, intn size_hint); -__DLL__ herr_t H5AC_rename (H5F_t *f, const H5AC_class_t *type, - const haddr_t *old_addr, const haddr_t *new_addr); -__DLL__ herr_t H5AC_set (H5F_t *f, const H5AC_class_t *type, - const haddr_t *addr, void *thing); -__DLL__ herr_t H5AC_debug (H5F_t *f); +__DLL__ herr_t H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, + const haddr_t *addr, void *thing); +__DLL__ herr_t H5AC_flush(H5F_t *f, const H5AC_class_t *type, + const haddr_t *addr, hbool_t destroy); +__DLL__ herr_t H5AC_create(H5F_t *f, intn size_hint); +__DLL__ herr_t H5AC_rename(H5F_t *f, const H5AC_class_t *type, + const haddr_t *old_addr, const haddr_t *new_addr); +__DLL__ herr_t H5AC_set(H5F_t *f, const H5AC_class_t *type, + const haddr_t *addr, void *thing); +__DLL__ herr_t H5AC_debug(H5F_t *f); #define H5AC_find(F,TYPE,ADDR_P,UDATA1,UDATA2) \ (((F)->shared->cache->slot[H5AC_HASH(F,ADDR_P)].type==(TYPE) && \ @@ -117,7 +117,7 @@ H5D_init_interface(void) /* Initialize the atom group for the dataset IDs */ if (H5I_init_group(H5I_DATASET, H5I_DATASETID_HASHSIZE, H5D_RESERVED_ATOMS, - (herr_t (*)(void *)) H5D_close)<0) { + (H5I_free_t)H5D_close)<0) { HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -383,7 +383,7 @@ H5Dget_space(hid_t dset_id) /* Create an atom */ if ((ret_value=H5I_register (H5I_DATASPACE, space))<0) { - H5S_close (space); + H5S_close(space); HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space"); } @@ -1340,7 +1340,7 @@ H5D_open_oid(H5G_entry_t *ent) ret_value = dataset; done: - if (space) H5S_close (space); + if (space) H5S_close(space); if (ret_value==NULL && dataset) { if (H5F_addr_defined(&(dataset->ent.header))) { H5O_close(&(dataset->ent)); @@ -1394,7 +1394,7 @@ H5D_close(H5D_t *dataset) * can do if one of these fails, so we just continue. */ free_failed = (H5T_close(dataset->type) < 0 || - H5P_close (H5P_DATASET_CREATE, dataset->create_parms)); + H5P_close(H5P_DATASET_CREATE, dataset->create_parms)); /* Close the dataset object */ H5O_close(&(dataset->ent)); @@ -1764,7 +1764,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (dst_id >= 0) H5I_dec_ref(dst_id); if (tconv_buf && NULL==xfer_parms->tconv_buf) H5TB_release_buf(tconv_id); if (bkg_buf && NULL==xfer_parms->bkg_buf) H5TB_release_buf (bkg_id); - if (free_this_space) H5S_close (free_this_space); + if (free_this_space) H5S_close(free_this_space); FUNC_LEAVE(ret_value); } @@ -2138,7 +2138,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (dst_id >= 0) H5I_dec_ref(dst_id); if (tconv_buf && NULL==xfer_parms->tconv_buf) H5TB_release_buf(tconv_id); if (bkg_buf && NULL==xfer_parms->bkg_buf) H5TB_release_buf (bkg_id); - if (free_this_space) H5S_close (free_this_space); + if (free_this_space) H5S_close(free_this_space); FUNC_LEAVE(ret_value); } @@ -2222,7 +2222,7 @@ H5D_extend (H5D_t *dataset, const hsize_t *size) ret_value = SUCCEED; done: - H5S_close (space); + H5S_close(space); FUNC_LEAVE (ret_value); } diff --git a/src/H5Distore.c b/src/H5Distore.c index bf75f17..7f3fb7f 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -2002,8 +2002,8 @@ H5F_istore_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, *------------------------------------------------------------------------- */ static herr_t -H5F_istore_get_addr (H5F_t *f, const H5O_layout_t *layout, - const hssize_t offset[], void *_udata/*out*/) +H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout, + const hssize_t offset[], void *_udata/*out*/) { H5F_istore_ud1_t *udata = _udata; intn i; diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 89cfba5..7ce4dbc 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -67,21 +67,21 @@ __DLLVAR__ const H5D_create_t H5D_create_dflt; __DLLVAR__ const H5D_xfer_t H5D_xfer_dflt; /* Functions defined in H5D.c */ -__DLL__ H5D_t *H5D_create (H5G_entry_t *loc, const char *name, - const H5T_t *type, const H5S_t *space, - const H5D_create_t *create_parms); -__DLL__ H5D_t *H5D_open (H5G_entry_t *loc, const char *name); -__DLL__ herr_t H5D_close (H5D_t *dataset); +__DLL__ H5D_t *H5D_create(H5G_entry_t *loc, const char *name, + const H5T_t *type, const H5S_t *space, + const H5D_create_t *create_parms); +__DLL__ H5D_t *H5D_open(H5G_entry_t *loc, const char *name); +__DLL__ herr_t H5D_close(H5D_t *dataset); __DLL__ htri_t H5D_isa(H5G_entry_t *ent); -__DLL__ herr_t H5D_read (H5D_t *dataset, const H5T_t *mem_type, +__DLL__ herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type, + const H5S_t *mem_space, const H5S_t *file_space, + const H5D_xfer_t *xfer_parms, void *buf/*out*/); +__DLL__ herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_t *file_space, - const H5D_xfer_t *xfer_parms, void *buf/*out*/); -__DLL__ herr_t H5D_write (H5D_t *dataset, const H5T_t *mem_type, - const H5S_t *mem_space, const H5S_t *file_space, - const H5D_xfer_t *xfer_parms, const void *buf); -__DLL__ herr_t H5D_extend (H5D_t *dataset, const hsize_t *size); -__DLL__ H5G_entry_t *H5D_entof (H5D_t *dataset); -__DLL__ H5T_t *H5D_typeof (H5D_t *dset); + const H5D_xfer_t *xfer_parms, const void *buf); +__DLL__ herr_t H5D_extend(H5D_t *dataset, const hsize_t *size); +__DLL__ H5G_entry_t *H5D_entof(H5D_t *dataset); +__DLL__ H5T_t *H5D_typeof(H5D_t *dset); __DLL__ H5S_t *H5D_get_space(H5D_t *dset); __DLL__ H5D_t * H5D_open_oid(H5G_entry_t *ent); __DLL__ H5F_t * H5D_get_file(const H5D_t *dset); @@ -20,22 +20,6 @@ static char RcsId[] = "@(#)$Revision$"; /* $Id$ */ -/*LINTLIBRARY */ -/* - FILE - hdf5file.c - HDF5 file I/O routines - - EXPORTED ROUTINES - H5Fcreate -- Create an HDF5 file - H5Fclose -- Close an open HDF5 file - - LIBRARY-SCOPED ROUTINES - - LOCAL ROUTINES - H5F_init_interface -- initialize the H5F interface - */ - /* Packages needed by this file... */ #include <H5private.h> /*library functions */ #include <H5Aprivate.h> /*attributes */ @@ -49,17 +33,8 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5Pprivate.h> /*property lists */ #include <H5Tprivate.h> /*data types */ -/* - * Define the following if you want H5F_block_read() and H5F_block_write() to - * keep track of the file position and attempt to minimize calls to the file - * seek method. - */ -/* #define H5F_OPT_SEEK */ - #define PABLO_MASK H5F_mask -/*-------------------- Locally scoped variables -----------------------------*/ - /* * Define the default file creation property list. */ @@ -110,6 +85,7 @@ 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*/); +static intn H5F_flush_all_cb(H5F_t *f, const void *_invalidate); /*------------------------------------------------------------------------- @@ -154,8 +130,11 @@ H5F_init(void) * Changed pablo mask from H5_mask to H5F_mask for the FUNC_LEAVE call. * It was already H5F_mask for the PABLO_TRACE_ON call. * - * rky 980816 + * Kim Yates, 1998-08-16 * Added .disp, .btype, .ftype to H5F_access_t. + * + * Robb Matzke, 1999-02-19 + * Added initialization for the H5I_FILE_CLOSING ID group. *------------------------------------------------------------------------- */ static herr_t @@ -175,9 +154,18 @@ H5F_init_interface(void) } #endif - /* Initialize the atom group for the file IDs */ + /* + * 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. + */ if (H5I_init_group(H5I_FILE, H5I_FILEID_HASHSIZE, 0, - (herr_t (*)(void*))H5F_close)<0) { + (H5I_free_t)H5F_close)<0 || + H5I_init_group(H5I_FILE_CLOSING, H5I_FILEID_HASHSIZE, 0, + (H5I_free_t)H5F_close)<0) { HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -217,39 +205,63 @@ H5F_init_interface(void) } -/*-------------------------------------------------------------------------- - NAME - H5F_term_interface - PURPOSE - Terminate various H5F objects - USAGE - void H5F_term_interface() - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Release the atom group and any other resources allocated. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Can't report errors... - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5F_term_interface + * + * Purpose: Terminate this interface: free all memory and reset global + * variables to their initial values. Release all ID groups + * associated with this interface. + * + * Return: Success: + * + * Failure: + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ void H5F_term_interface(intn status) { if (interface_initialize_g>0) { H5I_destroy_group(H5I_FILE); + H5I_destroy_group(H5I_FILE_CLOSING); } interface_initialize_g = status; } /*------------------------------------------------------------------------- - * Function: H5F_close_all + * Function: H5F_flush_all_cb + * + * Purpose: Callback function for H5F_flush_all(). + * + * Return: Always returns zero. + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static intn +H5F_flush_all_cb(H5F_t *f, const void *_invalidate) +{ + hbool_t invalidate = (hbool_t)_invalidate; + H5F_flush(f, H5F_SCOPE_LOCAL, invalidate); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5F_flush_all * - * Purpose: Closes all open files. If a file has open object headers then - * the underlying file is held open until all object headers are - * closed for the file (see H5O_close()). + * Purpose: Flush all open files. If INVALIDATE is true then also remove + * everything from the cache. * * Return: Success: Non-negative * @@ -263,23 +275,55 @@ H5F_term_interface(intn status) *------------------------------------------------------------------------- */ herr_t +H5F_flush_all(hbool_t invalidate) +{ + FUNC_ENTER(H5F_flush_all, FAIL); + H5I_search(H5I_FILE, (H5I_search_func_t)H5F_flush_all_cb, + (void*)invalidate); + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5F_close_all + * + * Purpose: Close all open files. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5F_close_all(void) { FUNC_ENTER(H5F_close_all, FAIL); /* - * There is no way to call H5F_close() on all items in the group and - * remove the items from the group without destroying the group, so we do - * it in two steps: first destroy the group, then create a new empty - * group. + * Close all normally open files. Any file which has open object headers + * will be moved to the H5I_FILE_CLOSING ID group. */ - H5I_destroy_group(H5I_FILE); - if (H5I_init_group(H5I_FILE, H5I_FILEID_HASHSIZE, 0, - (herr_t (*)(void*))H5F_close)<0) { - HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, - "unable to initialize file group"); + if (H5I_destroy_group(H5I_FILE)<0) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, + "unable to destroy H5I_FILE ID group"); } + /* + * Recreate the H5I_FILE group just in case someone wants to open or + * create another file later. + */ + if (H5I_init_group(H5I_FILE, H5I_FILEID_HASHSIZE, 0, + (H5I_free_t)H5F_close)<0) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, + "unable to recreate H5I_FILE ID group"); + } + FUNC_LEAVE(SUCCEED); } @@ -647,6 +691,7 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) /* Create the chunk cache */ H5F_istore_init (f); } + f->shared->nrefs++; f->nrefs = 1; ret_value = f; @@ -681,6 +726,11 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) * Nothing happens unless the reference count for the H5F_t goes to * zero. The reference counts are decremented here. * + * Robb Matzke, 1999-02-19 + * More careful about decrementing reference counts so they don't go + * negative or wrap around to some huge value. Nothing happens if a + * reference count is already zero. + * *------------------------------------------------------------------------- */ static herr_t @@ -690,8 +740,8 @@ H5F_dest(H5F_t *f) FUNC_ENTER(H5F_dest, FAIL); - if (f && 0 == --f->nrefs) { - if (0 == --f->shared->nrefs) { + 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. @@ -710,12 +760,27 @@ H5F_dest(H5F_t *f) H5P_close (H5P_FILE_CREATE, f->shared->create_parms); H5P_close (H5P_FILE_ACCESS, f->shared->access_parms); f->shared = H5MM_xfree(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; } + + /* 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; H5MM_xfree(f); + } else if (f->nrefs>0) { + /* + * There are other references to this file. Only decrement the + * reference count. + */ + --f->nrefs; } + FUNC_LEAVE(ret_value); } @@ -880,7 +945,8 @@ H5F_open(const char *name, uintn flags, HRETURN_ERROR(H5E_FILE, H5E_WRITEERROR, NULL, "file is not writable"); } - if ((old = H5I_search(H5I_FILE, H5F_compare_files, &search))) { + if ((old = H5I_search(H5I_FILE, H5F_compare_files, &search)) || + (old = H5I_search(H5I_FILE_CLOSING, H5F_compare_files, &search))) { if (flags & H5F_ACC_TRUNC) { HRETURN_ERROR(H5E_FILE, H5E_FILEOPEN, NULL, "file already open - TRUNC failed"); @@ -1615,9 +1681,19 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate) /*------------------------------------------------------------------------- * Function: H5F_close * - * 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(). + * Purpose: Closes a file or causes the close operation to be pended. + * This function is called two ways: from the API it gets called + * by H5Fclose->H5I_dec_ref->H5F_close when H5I_dec_ref() + * decrements the file ID reference count to zero. The file ID + * is removed from the H5I_FILE group by H5I_dec_ref() just + * before H5F_close() is called. If there are open object + * headers then the close is pended by moving the file to the + * H5I_FILE_CLOSING ID group (the f->closing contains the ID + * assigned to file). + * + * This function is also called directly from H5O_close() when + * the last object header is closed for the file and the file + * has a pending close. * * Return: Non-negative on success/Negative on failure * @@ -1639,10 +1715,11 @@ H5F_close(H5F_t *f) uintn i; FUNC_ENTER(H5F_close, FAIL); + assert(f->nrefs>0); /* - * If the reference count is positive then just decrement the count and - * flush the file. + * If this file is referenced more than once then just decrement the + * count, flush the file, and return. */ if (f->nrefs>1) { if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE)<0) { @@ -1668,7 +1745,8 @@ H5F_close(H5F_t *f) * If object headers are still open then delay deletion of resources until * they have all been closed. Flush all caches and update the object * header anyway so that failing to close all objects isn't a major - * problem. + * problem. If the file is on the H5I_FILE list then move it to the + * H5I_FILE_CLOSING list instead. */ if (f->nopen_objs>0) { if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE)<0) { @@ -1685,9 +1763,11 @@ H5F_close(H5F_t *f) 1 == f->nopen_objs?"that header is":"those headers are"); } #endif - f->close_pending = TRUE; + if (!f->closing) { + f->closing = H5I_register(H5I_FILE_CLOSING, f); + } HRETURN(SUCCEED); - } else if (f->close_pending) { + } else if (f->closing) { #ifdef H5F_DEBUG if (H5DEBUG(F)) { fprintf(H5DEBUG(F), "H5F: H5F_close: operation completing\n"); @@ -1699,16 +1779,17 @@ 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->nrefs && 1==f->shared->nrefs) { + assert(1==f->nrefs); + if (1==f->shared->nrefs) { /* Flush and destroy all caches */ - if (H5F_flush (f, H5F_SCOPE_LOCAL, TRUE)<0) { - HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL, - "unable to flush cache"); + if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE)<0) { + HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, + "unable to flush cache"); } /* Dump debugging info */ H5AC_debug(f); - H5F_istore_stats (f, FALSE); + H5F_istore_stats(f, FALSE); /* Close files and release resources */ H5F_low_close(f->shared->lf, f->shared->access_parms); @@ -1723,7 +1804,12 @@ H5F_close(H5F_t *f) "unable to flush cache"); } } - + + /* + * Destroy the H5F_t struct and decrement the reference count for the + * 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)<0) { HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file"); @@ -1732,42 +1818,31 @@ H5F_close(H5F_t *f) } -/*-------------------------------------------------------------------------- - NAME - H5Fclose - - PURPOSE - Close an open HDF5 file. - - USAGE - herr_t H5Fclose(file_id) - int32_t file_id; IN: File ID of file to close - - ERRORS - ARGS BADTYPE Not a file atom. - ATOM BADATOM Can't remove atom. - ATOM BADATOM Can't unatomize file. - CACHE CANTFLUSH Can't flush cache. - - RETURNS - Non-negative on success/Negative on failure - - DESCRIPTION - This function terminates access to an HDF5 file. If this is the last - file ID open for a file and if access IDs are still in use, this function - will fail. - - MODIFICATIONS: - Robb Matzke, 18 Jul 1997 - File struct destruction is through H5F_dest(). - - Robb Matzke, 29 Aug 1997 - The file boot block is flushed to disk since it's contents may have - changed. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Fclose + * + * Purpose: This function closes the file specified by FILE_ID by + * flushing all data to storage, and terminating access to the + * file through FILE_ID. If objects (e.g., datasets, groups, + * etc.) are open in the file then the underlying storage is not + * closed until those objects are closed; however, all data for + * the file and the open objects is flushed. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Saturday, February 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ herr_t H5Fclose(hid_t file_id) { + herr_t ret_value = SUCCEED; FUNC_ENTER(H5Fclose, FAIL); diff --git a/src/H5Fistore.c b/src/H5Fistore.c index bf75f17..7f3fb7f 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -2002,8 +2002,8 @@ H5F_istore_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, *------------------------------------------------------------------------- */ static herr_t -H5F_istore_get_addr (H5F_t *f, const H5O_layout_t *layout, - const hssize_t offset[], void *_udata/*out*/) +H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout, + const hssize_t offset[], void *_udata/*out*/) { H5F_istore_ud1_t *udata = _udata; intn i; diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 2032129..71b6ca4 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -336,6 +336,12 @@ typedef struct H5F_low_class_t { haddr_t *addr/*out*/); } H5F_low_class_t; +/* + * One of these H5F_low_t structs is allocated for each H5F_file_t struct. + * This struct describes how to access the storage for the hdf5 address space, + * whether that storage is file, local memory, shared memory, network + * distributed global memory, etc. + */ typedef struct H5F_low_t { const H5F_low_class_t *type;/* What type of file is this? */ haddr_t eof; /* Address of logical end-of-file */ @@ -427,28 +433,12 @@ typedef struct H5F_rdcc_t { struct H5F_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/ } H5F_rdcc_t; -/* Mount property list */ -typedef struct H5F_mprop_t { - hbool_t local; /* Are absolute symlinks local to file? */ -} H5F_mprop_t; - -/* A record of the mount table */ -typedef struct H5F_mount_t { - struct H5G_t *group; /* Mount point group held open */ - struct H5F_t *file; /* File mounted at that point */ -} H5F_mount_t; - -/* The mount table */ -typedef struct H5F_mtab_t { - struct H5F_t *parent;/* Parent file */ - uintn nmounts;/* Number of children which are mounted */ - uintn nalloc; /* Number of mount slots allocated */ - H5F_mount_t *child; /* An array of mount records */ -} H5F_mtab_t; - /* * Define the structure to store the file information for HDF5 files. One of - * these structures is allocated per file, not per H5Fopen(). + * these structures is allocated per file, not per H5Fopen(). That is, set of + * H5F_t structs can all point to the same H5F_file_t struct. The `nrefs' + * count in this struct indicates the number of H5F_t structs which are + * pointing to this struct. */ typedef struct H5F_file_t { H5F_search_t key; /* The key for looking up files */ @@ -471,10 +461,35 @@ typedef struct H5F_file_t { H5MF_free_t fl_free[H5MF_NFREE]; /*free block array */ } H5F_file_t; +/* Mount property list */ +typedef struct H5F_mprop_t { + hbool_t local; /* Are absolute symlinks local to file? */ +} H5F_mprop_t; + +/* A record of the mount table */ +typedef struct H5F_mount_t { + struct H5G_t *group; /* Mount point group held open */ + struct H5F_t *file; /* File mounted at that point */ +} H5F_mount_t; + +/* + * The mount table describes what files are attached to (mounted on) the file + * to which this table belongs. + */ +typedef struct H5F_mtab_t { + struct H5F_t *parent;/* Parent file */ + uintn nmounts;/* Number of children which are mounted */ + uintn nalloc; /* Number of mount slots allocated */ + H5F_mount_t *child; /* An array of mount records */ +} H5F_mtab_t; + /* * This is the top-level file descriptor. One of these structures is - * allocated every time H5Fopen() is called although they may contain - * pointers to shared H5F_file_t structs. + * allocated every time H5Fopen() is called although they may contain pointers + * to shared H5F_file_t structs. The reference count (nrefs) indicates the + * number of times the file has been opened (the application can only open a + * file once explicitly, but the library can open the file a second time to + * indicate that the file is mounted on some other file). */ typedef struct H5F_t { uintn nrefs; /* Reference count */ @@ -482,7 +497,7 @@ typedef struct H5F_t { char *name; /* Name used to open file */ H5F_file_t *shared; /* The shared file info */ uintn nopen_objs; /* Number of open object headers*/ - hbool_t close_pending; /* File close is pending */ + hid_t closing; /* H5I_FILE_CLOSING ID or zero */ H5F_mtab_t mtab; /* File mount table */ } H5F_t; @@ -545,13 +560,14 @@ __DLLVAR__ hbool_t H5_mpi_1_metawrite_g; /* Private functions, not part of the publicly documented API */ __DLL__ herr_t H5F_init(void); -__DLL__ herr_t H5F_close_all(void); __DLL__ void H5F_encode_length_unusual(const H5F_t *f, uint8_t **p, uint8_t *l); __DLL__ H5F_t *H5F_open(const char *name, uintn flags, const H5F_create_t *create_parms, const H5F_access_t *access_parms); __DLL__ herr_t H5F_close(H5F_t *f); +__DLL__ herr_t H5F_close_all(void); +__DLL__ herr_t H5F_flush_all(hbool_t invalidate); __DLL__ herr_t H5F_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, intn fwidth); __DLL__ herr_t H5F_istore_debug(H5F_t *f, const haddr_t *addr, FILE * stream, @@ -306,7 +306,7 @@ H5Giterate(hid_t loc_id, const char *name, int *idx, HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to open group"); } if ((udata.group_id=H5I_register (H5I_GROUP, udata.group))<0) { - H5G_close (udata.group); + H5G_close(udata.group); HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to register group"); } @@ -682,7 +682,7 @@ H5G_init_interface(void) /* Initialize the atom group for the group IDs */ if (H5I_init_group(H5I_GROUP, H5I_GROUPID_HASHSIZE, H5G_RESERVED_ATOMS, - (herr_t (*)(void *)) H5G_close) < 0) { + (H5I_free_t)H5G_close) < 0) { HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -1189,7 +1189,7 @@ H5G_mkroot (H5F_t *f, H5G_entry_t *ent) "unable to open root group"); } if (NULL==H5O_read (ent, H5O_STAB, 0, &stab)) { - H5O_close (ent); + H5O_close(ent); HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "root object is not a group"); } @@ -1377,7 +1377,7 @@ H5G_open(H5G_entry_t *loc, const char *name) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group"); } if (NULL==H5O_read (&(grp->ent), H5O_STAB, 0, &mesg)) { - H5O_close (&(grp->ent)); + H5O_close(&(grp->ent)); HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL, "not a group"); } grp->nref = 1; @@ -1767,8 +1767,9 @@ H5G_loc (hid_t loc_id) } break; - case H5I_MAXID: + case H5I_NGROUPS: case H5I_BADID: + case H5I_FILE_CLOSING: HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object ID"); } @@ -17,46 +17,23 @@ static char RcsId[] = "@(#)$Revision$"; /* $Id$ */ /* - FILE - H5I.c - Internal storage routines for handling "IDs" - - REMARKS - ID's which allow objects (void *'s currently) to be bundled into "groups" - for more general storage. - - DESIGN - The groups are stored in an array of pointers to store each group in an - element. Each "group" node contains a link to a hash table to manage the IDs - in each group. The allowed "groups" are stored in an enum (called group_t) - in H5Ipublic.h. - - BUGS/LIMITATIONS - Can't interate over the IDs in a group. - - LOCAL ROUTINES - H5I_find_id - Returns a pointer to an HAI_id_info_t from an ID - H5I_get_id_node - Gets an ID node (uses the ID free list) - H5I_release_id_node - Releases an ID node (uses the ID free list) - EXPORTED ROUTINES - ID Functions: - H5I_register - Register an object in a group and get an ID for it - H5I_object - Get the object for an ID - H5I_get_type - Get the group for an ID - H5I_remove - Remove an ID from a group - H5I_search - Search a group for a particular object - ID Group Functions: - H5I_init_group - Initialize a group to store IDs in - H5I_destroy_group - Destroy an ID group - ID Group Cleanup: - H5Ishutdown - Terminate various static buffers. - - AUTHOR - Quincey Koziol - - MODIFICATION HISTORY - 1/3/96 - Starting writing specs & coding prototype - 1/7/96 - Finished coding prototype - 6/10/97 - Moved into HDF5 library + * FILE: H5I.c - Internal storage routines for handling "IDs" + * + * REMARKS: ID's which allow objects (void *'s currently) to be bundled + * into "groups" for more general storage. + * + * DESIGN: The groups are stored in an array of pointers to store each + * group in an element. Each "group" node contains a link to a + * hash table to manage the IDs in each group. The allowed + * "groups" are stored in an enum (called group_t) in + * H5Ipublic.h. + * + * AUTHOR: Quincey Koziol + * + * MODIFICATIONS: + * 1/3/96 - Starting writing specs & coding prototype + * 1/7/96 - Finished coding prototype + * 6/10/97 - Moved into HDF5 library */ #include <H5private.h> #include <H5Iprivate.h> @@ -81,11 +58,11 @@ static herr_t H5I_init_interface(void); /*-------------------- Locally scoped variables -----------------------------*/ #ifdef IDS_ARE_CACHED -# define ID_CACHE_SIZE 4 /*# of previous atoms cached */ +# define ID_CACHE_SIZE 4 /*# of previous atoms cached */ #endif /* - * Number of bits to use for Group ID in each atom. Increase if H5I_MAXID + * Number of bits to use for Group ID in each atom. Increase if H5I_NGROUPS * becomes too large (an assertion would fail in H5I_init_interface). This is * the only number that must be changed since all other bit field sizes and * masks are calculated from GROUP_BITS. @@ -118,37 +95,43 @@ static herr_t H5I_init_interface(void); #endif /* Combine a Group number and an atom index into an atom */ -#define H5I_MAKE(g,i) ((((hid_t)(g)&GROUP_MASK)<<ID_BITS)| \ - ((hid_t)(i)&ID_MASK)) +#define H5I_MAKE(g,i) ((((hid_t)(g)&GROUP_MASK)<<ID_BITS)| \ + ((hid_t)(i)&ID_MASK)) #ifdef IDS_ARE_CACHED /* Array of pointers to ID groups */ -static hid_t H5I_id_cache[ID_CACHE_SIZE] = {-1, -1, -1, -1}; -static void *H5I_obj_cache[ID_CACHE_SIZE]; +static hid_t H5I_id_cache_g[ID_CACHE_SIZE] = {-1, -1, -1, -1}; +static void *H5I_obj_cache_g[ID_CACHE_SIZE]; #endif /* Array of pointers to atomic groups */ -static H5I_id_group_t *id_group_list[H5I_MAXID]; +static H5I_id_group_t *H5I_id_group_list_g[H5I_NGROUPS]; /* Pointer to the atom node free list */ -static H5I_id_info_t *id_free_list = NULL; +static H5I_id_info_t *H5I_id_free_list_g = NULL; /*--------------------- Local function prototypes ---------------------------*/ static H5I_id_info_t *H5I_find_id(hid_t id); static H5I_id_info_t *H5I_get_id_node(void); static herr_t H5I_release_id_node(H5I_id_info_t *id); +static herr_t H5I_debug(H5I_type_t grp); -/*-------------------------------------------------------------------------- -NAME - H5I_init_interface -- Initialize interface-specific information -USAGE - herr_t H5I_init_interface() -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5I_init_interface + * + * Purpose: Initialize interface-specific information. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ static herr_t H5I_init_interface(void) { @@ -159,45 +142,101 @@ H5I_init_interface(void) * Make certain the ID types don't overflow the number of bits allocated * for them in an ID. */ - assert(H5I_MAXID<=(1<<GROUP_BITS)); + assert(H5I_NGROUPS<=(1<<GROUP_BITS)); FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_init_group - Initialize an ID group - - DESCRIPTION - Creates a global ID group to store IDs in. If the group has already - been initialized, this routine just increments the count of # of - initializations and returns without trying to change the size of the hash - table. A specific number of group entries may be reserved to enable - "constant" values to be handed out which are valid IDs in the group, but - which do not map to any data structures and are not allocated dynamicly - later. - - RETURNS - Non-negative on success/Negative on failure - -******************************************************************************/ +/*------------------------------------------------------------------------- + * Function: H5I_term_interface + * + * Purpose: Terminate the H5I interface: release all memory, reset all + * global variables to initial values. + * + * Return: void + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5I_term_interface(intn status) +{ + H5I_id_group_t *grp_ptr; + H5I_id_info_t *curr; + H5I_type_t grp; + + if (interface_initialize_g>0) { + for (grp=0; grp<H5I_NGROUPS; grp++) { + /* + * Destroy each group regardless of reference count. This removes + * any objects which might still be defined in the group. Then + * free the group header struct and zero the global group array. + */ + if ((grp_ptr=H5I_id_group_list_g[grp])) { + grp_ptr->count = 1; + H5I_destroy_group(grp); + H5MM_xfree(grp_ptr); + H5I_id_group_list_g[grp] = NULL; + } + } + + + /* Release the global free list */ + while (H5I_id_free_list_g) { + curr = H5I_id_free_list_g; + H5I_id_free_list_g = H5I_id_free_list_g->next; + H5MM_xfree(curr); + } + } + + /* Indicate interface status */ + interface_initialize_g = status; +} + + +/*------------------------------------------------------------------------- + * Function: H5I_init_group + * + * Purpose: Initialize an ID group whose ID number is specified by GRP, + * If the group has already been initialized, this routine just + * increments the count of number of initializations and returns + * without trying to change the size of the hash table. A + * specific number (RESERVED) of group entries may be reserved + * to enable "constant" values to be handed out which are valid + * IDs in the group, but which do not map to any data structures + * and are not allocated dynamicly later. HASH_SIZE is the + * minimum hash table size to use for the group. FREE_FUNC is + * called with an object pointer when the object is removed from + * the group. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ intn -H5I_init_group(H5I_type_t grp, /* IN: Group to initialize */ - size_t hash_size, /* IN: Minimum hash table size to use for group */ - uintn reserved, /* IN: Number of hash table entries to reserve */ - herr_t (*free_func) (void *) /* IN: Function to call when releasing ref counted objects */ -) +H5I_init_group(H5I_type_t grp, size_t hash_size, uintn reserved, + H5I_free_t free_func) { - H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */ - intn ret_value = SUCCEED; + H5I_id_group_t *grp_ptr = NULL; /*ptr to the atomic group*/ + intn ret_value = SUCCEED; /*return value */ FUNC_ENTER(H5I_init_group, FAIL); - if ((grp <= H5I_BADID || grp >= H5I_MAXID) && hash_size > 0) { + /* Check arguments */ + if ((grp <= H5I_BADID || grp >= H5I_NGROUPS) && hash_size > 0) { HGOTO_DONE(FAIL); } - #ifdef HASH_SIZE_POWER_2 /* * If anyone knows a faster test for a power of two, please change this @@ -217,20 +256,20 @@ H5I_init_group(H5I_type_t grp, /* IN: Group to initialize */ HGOTO_DONE(FAIL); #endif /* HASH_SIZE_POWER_2 */ - if (id_group_list[grp] == NULL) { - /* Allocate the group information */ + if (H5I_id_group_list_g[grp] == NULL) { + /* Allocate the group information for new group */ if (NULL==(grp_ptr = H5MM_calloc(sizeof(H5I_id_group_t)))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - id_group_list[grp] = grp_ptr; + H5I_id_group_list_g[grp] = grp_ptr; } else { /* Get the pointer to the existing group */ - grp_ptr = id_group_list[grp]; + grp_ptr = H5I_id_group_list_g[grp]; } if (grp_ptr->count == 0) { - /* Initialize the ID group structure */ + /* Initialize the ID group structure for new groups */ grp_ptr->hash_size = hash_size; grp_ptr->reserved = reserved; grp_ptr->wrapped = 0; @@ -251,12 +290,11 @@ H5I_init_group(H5I_type_t grp, /* IN: Group to initialize */ if (ret_value<0) { /* Error condition cleanup */ if (grp_ptr != NULL) { - H5MM_xfree (grp_ptr->id_list); - H5MM_xfree (grp_ptr); + H5MM_xfree(grp_ptr->id_list); + H5MM_xfree(grp_ptr); } } - - /* Normal function cleanup */ + FUNC_LEAVE(ret_value); } @@ -267,7 +305,7 @@ H5I_init_group(H5I_type_t grp, /* IN: Group to initialize */ * Purpose: Decrements the reference count on an entire group of IDs. * If the group reference count becomes zero then the group is * destroyed along with all atoms in that group regardless of - * their reference counts. Destroying IDs involves calling + * their reference counts. Destroying IDs involves calling * the free-func for each ID's object and then adding the ID * struct to the ID free list. * @@ -277,7 +315,7 @@ H5I_init_group(H5I_type_t grp, /* IN: Group to initialize */ * * Modifications: * - * Robb Matzke, 25 Feb 1998 + * Robb Matzke, 25 Feb 1998 * IDs are freed when a group is destroyed. * *------------------------------------------------------------------------- @@ -292,52 +330,65 @@ H5I_destroy_group(H5I_type_t grp) FUNC_ENTER(H5I_destroy_group, FAIL); - if (grp <= H5I_BADID || grp >= H5I_MAXID) + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) { HGOTO_DONE(FAIL); - - grp_ptr = id_group_list[grp]; - if (grp_ptr == NULL || grp_ptr->count <= 0) + } + + grp_ptr = H5I_id_group_list_g[grp]; + if (grp_ptr == NULL || grp_ptr->count <= 0) { HGOTO_DONE(FAIL); + } /* * Decrement the number of users of the atomic group. If this is the * last user of the group then release all atoms from the group. The * free function is invoked for each atom being freed. */ - if ((--(grp_ptr->count)) == 0) { - + if (1==grp_ptr->count) { #ifdef IDS_ARE_CACHED /* * Remove atoms from the global atom cache. */ for (i=0; i<ID_CACHE_SIZE; i++) { - if (H5I_GROUP(H5I_id_cache[i]) == grp) { - H5I_id_cache[i] = (-1); - H5I_obj_cache[i] = NULL; + if (H5I_GROUP(H5I_id_cache_g[i]) == grp) { + H5I_id_cache_g[i] = (-1); + H5I_obj_cache_g[i] = NULL; } } #endif /* IDS_ARE_CACHED */ /* - * Free all objects. + * Call free method for all objects in group regardless of there + * reference counts. Ignore the return value from from the free + * method and remove object from group regardless. */ if (grp_ptr->free_func) { for (i=0; i<grp_ptr->hash_size; i++) { - for (cur=grp_ptr->id_list[i]; cur; cur=next) { - /* Free the object */ - (grp_ptr->free_func)(cur->obj_ptr); - - /* Add ID struct to free list */ - next = cur->next; - cur->next = id_free_list; - id_free_list = cur; - } + for (cur=grp_ptr->id_list[i]; cur; cur=next) { + /* Free the object regardless of reference count */ + if ((grp_ptr->free_func)(cur->obj_ptr)<0) { +#if H5I_DEBUG + if (H5DEBUG(I)) { + fprintf(H5DEBUG(I), "H5I: free grp=%d obj=0x%08lx " + "failure ignored\n", (int)grp, + (unsigned long)(cur->obj_ptr)); + } +#endif /*H5I_DEBUG*/ + } + + /* Add ID struct to free list */ + next = cur->next; + cur->next = H5I_id_free_list_g; + H5I_id_free_list_g = cur; + } } } /* Free local cache and reset group */ H5MM_xfree(grp_ptr->id_list); - HDmemset (grp_ptr, 0, sizeof(grp_ptr)); + HDmemset (grp_ptr, 0, sizeof(*grp_ptr)); + } else { + --(grp_ptr->count); } done: @@ -369,9 +420,9 @@ H5I_destroy_group(H5I_type_t grp) hid_t H5I_register(H5I_type_t grp, void *object) { - H5I_id_group_t *grp_ptr=NULL; /*ptr to the group */ + H5I_id_group_t *grp_ptr=NULL; /*ptr to the group */ H5I_id_info_t *id_ptr=NULL; /*ptr to the new ID information */ - hid_t new_id; /*new ID */ + hid_t new_id; /*new ID */ uintn hash_loc; /*new item's hash table location*/ hid_t next_id; /*next ID to check */ hid_t ret_value=SUCCEED; /*return value */ @@ -380,15 +431,17 @@ H5I_register(H5I_type_t grp, void *object) FUNC_ENTER(H5I_register, FAIL); - if (grp <= H5I_BADID || grp >= H5I_MAXID) + /* Check arguments */ + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) { HGOTO_DONE(FAIL); - - grp_ptr = id_group_list[grp]; - if (grp_ptr == NULL || grp_ptr->count <= 0) + } + grp_ptr = H5I_id_group_list_g[grp]; + if (grp_ptr == NULL || grp_ptr->count <= 0) { HGOTO_DONE(FAIL); - - if ((id_ptr = H5I_get_id_node()) == NULL) + } + if ((id_ptr = H5I_get_id_node()) == NULL) { HGOTO_DONE(FAIL); + } /* Create the struct & it's ID */ new_id = H5I_MAKE(grp, grp_ptr->nextid); @@ -399,8 +452,9 @@ H5I_register(H5I_type_t grp, void *object) /* hash bucket already full, prepend to front of chain */ hash_loc = grp_ptr->nextid % (uintn) grp_ptr->hash_size; - if (grp_ptr->id_list[hash_loc] != NULL) + if (grp_ptr->id_list[hash_loc] != NULL) { id_ptr->next = grp_ptr->id_list[hash_loc]; + } /* Insert into the group */ grp_ptr->id_list[hash_loc] = id_ptr; @@ -422,7 +476,6 @@ H5I_register(H5I_type_t grp, void *object) * handed out. */ if (grp_ptr->wrapped) { - /* * Make sure we check all available ID's. If we're about at the end * of the range then wrap around and check the beginning values. If @@ -430,7 +483,6 @@ H5I_register(H5I_type_t grp, void *object) * we can fail. */ for (i=grp_ptr->reserved; i<ID_MASK; i++) { - /* Handle end of range by wrapping to beginning */ if (grp_ptr->nextid>(uintn)ID_MASK) { grp_ptr->nextid = grp_ptr->reserved; @@ -461,61 +513,31 @@ H5I_register(H5I_type_t grp, void *object) FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_inc_ref - Adds a reference to a reference counted ID. - IN: ID to increment reference count for - DESCRIPTION - Increments the number of references outstanding for an ID. This will - fail if the group is not a reference counted group. - - RETURNS - ID/Negative - -*******************************************************************************/ -hid_t -H5I_inc_ref(hid_t id) -{ - H5I_type_t grp = H5I_GROUP(id); /* object's group */ - H5I_id_group_t *grp_ptr = NULL; /* ptr to the ID group*/ - H5I_id_info_t *id_ptr = NULL; /* ptr to the new ID */ - hid_t ret_value = FAIL; - - FUNC_ENTER(H5I_inc_ref, FAIL); - - grp_ptr = id_group_list[grp]; - if (grp_ptr == NULL || grp_ptr->count <= 0 || grp_ptr->free_func == NULL) { - HRETURN(FAIL); - } - - /* General lookup of the atom */ - if (NULL!=(id_ptr = H5I_find_id(id))) { - id_ptr->count++; - ret_value = id; - } - - FUNC_LEAVE(ret_value); -} - -/****************************************************************************** - NAME - H5I_object - Returns to the object ptr for the ID - - DESCRIPTION - Retrieves the object ptr which is associated with the ID. - - RETURNS - Returns object ptr if successful and NULL otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_object + * + * Purpose: Find an object pointer for the specified ID. + * + * Return: Success: Non-null object pointer associated with the + * specified ID. + * + * Failure: NULL + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ void * H5I_object(hid_t id) { + H5I_id_info_t *id_ptr = NULL; /*ptr to the new atom */ + void *ret_value = NULL; /*return value */ #ifdef IDS_ARE_CACHED - uintn i; /* local counter */ + uintn i; /*local counter */ #endif /* IDS_ARE_CACHED */ - H5I_id_info_t *id_ptr = NULL; /* ptr to the new atom */ - void *ret_value = NULL; FUNC_ENTER(H5I_object, NULL); @@ -524,49 +546,58 @@ H5I_object(hid_t id) * Look for the ID in the cache first. Implement a simple "move * forward" caching scheme by swapping the found cache item with the * previous cache item. This gradually migrates used cache items toward - * the front of the cache and unused items toward the end. For instance, + * the front of the cache and unused items toward the end. For instance, * finding `e' in the cache results in: * * Before: a b c d e f g h i j - * | | | X | | | | | + * | | | X | | | | | * After: a b c e d f g h i j */ for (i=0; i<ID_CACHE_SIZE; i++) - if (H5I_id_cache[i] == id) { - ret_value = H5I_obj_cache[i]; + if (H5I_id_cache_g[i] == id) { + ret_value = H5I_obj_cache_g[i]; if (i > 0) { - hid_t t_id = H5I_id_cache[i-1]; - void *t_obj = H5I_obj_cache[i-1]; - H5I_id_cache[i-1] = H5I_id_cache[i]; - H5I_obj_cache[i-1] = H5I_obj_cache[i]; - H5I_id_cache[i] = t_id; - H5I_obj_cache[i] = t_obj; + hid_t t_id = H5I_id_cache_g[i-1]; + void *t_obj = H5I_obj_cache_g[i-1]; + H5I_id_cache_g[i-1] = H5I_id_cache_g[i]; + H5I_obj_cache_g[i-1] = H5I_obj_cache_g[i]; + H5I_id_cache_g[i] = t_id; + H5I_obj_cache_g[i] = t_obj; } HGOTO_DONE(ret_value); } #endif /* IDS_ARE_CACHED */ /* General lookup of the ID */ - if ((id_ptr = H5I_find_id(id)) == NULL) HGOTO_DONE(NULL); + if (NULL==(id_ptr = H5I_find_id(id))) HGOTO_DONE(NULL); /* Check if we've found the correct ID */ - if (id_ptr != NULL) ret_value = id_ptr->obj_ptr; + if (id_ptr) ret_value = id_ptr->obj_ptr; done: FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_get_type - Returns to the group for the ID - - DESCRIPTION - Retrieves the group which is associated with the ID. - - RETURNS - Returns group if successful and H5I_BADID otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_get_type + * + * Purpose: Given an object ID return the group (type) to which it + * belongs. The ID need not be the ID of an object which + * currently exists because the group number (type) is encoded + * in the object ID. + * + * Return: Success: A valid group number (type) + * + * Failure: H5I_BADID, a negative value. + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ H5I_type_t H5I_get_type(hid_t id) { @@ -575,22 +606,30 @@ H5I_get_type(hid_t id) FUNC_ENTER(H5I_get_type, H5I_BADID); if (id>0) ret_value = H5I_GROUP(id); - assert(ret_value>=H5I_BADID && ret_value<H5I_MAXID); + assert(ret_value>=H5I_BADID && ret_value<H5I_NGROUPS); FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5Iget_type - Returns the type of an ID - - DESCRIPTION - Retrieves the type of an ID. - - RETURNS - Returns group if successful and H5I_BADID otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5Iget_type + * + * Purpose: The public version of H5I_get_type(), obtains a group number + * (type) when given an ID. The ID need not be the ID of an + * object which currently exists because the group number is + * encoded as part of the ID. + * + * Return: Success: Group number (type) + * + * Failure: H5I_BADID, a negative value + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ H5I_type_t H5Iget_type(hid_t id) { @@ -599,48 +638,55 @@ H5Iget_type(hid_t id) FUNC_ENTER(H5Iget_type, H5I_BADID); H5TRACE1("It","i",id); - if (ret_value <= H5I_BADID || ret_value >= H5I_MAXID) - HGOTO_DONE(H5I_BADID); - + if (ret_value <= H5I_BADID || ret_value >= H5I_NGROUPS) { + HGOTO_DONE(H5I_BADID); + } ret_value = H5I_get_type(id); done: FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_remove - Removes an ID from a group - - DESCRIPTION - Removes an ID from a group. - - RETURNS - Returns ID's object if successful and NULL otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_remove + * + * Purpose: Removes the specified ID from its group. + * + * Return: Success: A pointer to the object that was removed, the + * same pointer which would have been found by + * calling H5I_object(). + * + * Failure: NULL + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ void * H5I_remove(hid_t id) { - H5I_id_group_t *grp_ptr = NULL;/* ptr to the atomic group */ - H5I_id_info_t *curr_id, /* ptr to the current atom */ - *last_id; /* ptr to the last atom */ - H5I_type_t grp; /* atom's atomic group */ - uintn hash_loc; /* atom's hash table location */ + H5I_id_group_t *grp_ptr = NULL;/*ptr to the atomic group */ + H5I_id_info_t *curr_id; /*ptr to the current atom */ + H5I_id_info_t *last_id; /*ptr to the last atom */ + H5I_type_t grp; /*atom's atomic group */ + uintn hash_loc; /*atom's hash table location */ #ifdef IDS_ARE_CACHED - uintn i; /* local counting variable */ + uintn i; /*local counting variable */ #endif - void * ret_value = NULL; + void * ret_value = NULL; /*return value */ FUNC_ENTER(H5I_remove, NULL); + /* Check arguments */ grp = H5I_GROUP(id); - if (grp <= H5I_BADID || grp >= H5I_MAXID) HGOTO_DONE(NULL); - - grp_ptr = id_group_list[grp]; + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) HGOTO_DONE(NULL); + grp_ptr = H5I_id_group_list_g[grp]; if (grp_ptr == NULL || grp_ptr->count <= 0) HGOTO_DONE(NULL); - /* Get the location in which the ID is located */ + /* Get the bucket in which the ID is located */ hash_loc = (uintn) H5I_LOC(id, grp_ptr->hash_size); curr_id = grp_ptr->id_list[hash_loc]; if (curr_id == NULL) HGOTO_DONE(NULL); @@ -654,7 +700,7 @@ H5I_remove(hid_t id) if (curr_id != NULL) { if (last_id == NULL) { - /* ID is the first the chain */ + /* ID is the first in the chain */ grp_ptr->id_list[hash_loc] = curr_id->next; } else { last_id->next = curr_id->next; @@ -669,9 +715,9 @@ H5I_remove(hid_t id) #ifdef IDS_ARE_CACHED /* Delete object from cache */ for (i = 0; i < ID_CACHE_SIZE; i++) - if (H5I_id_cache[i] == id) { - H5I_id_cache[i] = (-1); - H5I_obj_cache[i] = NULL; + if (H5I_id_cache_g[i] == id) { + H5I_id_cache_g[i] = (-1); + H5I_obj_cache_g[i] = NULL; break; /* we assume there is only one instance in the cache */ } #endif /* IDS_ARE_CACHED */ @@ -706,90 +752,112 @@ H5I_remove(hid_t id) * zero and no `free' function has been defined. The object is still * removed from the list. * - * Robb Matzke, 30 Dec 1998 + * Robb Matzke, 30 Dec 1998 * Fixed a bug where the return value was always zero instead of the new * reference count. * + * Robb Matzke, 19 Feb 1999 + * If the free method is defined and fails then the object is not + * removed from the group and its reference count is not decremented. + * The group number is now passed to the free method. + * *------------------------------------------------------------------------- */ intn H5I_dec_ref(hid_t id) { - H5I_type_t grp = H5I_GROUP(id); /* Group the object is in */ - H5I_id_group_t *grp_ptr = NULL; /* ptr to the group */ - H5I_id_info_t *id_ptr = NULL; /* ptr to the new ID */ - void * obj; /* object to call 'free' function with */ - intn ret_value = FAIL; + H5I_type_t grp = H5I_GROUP(id); /*group the object is in*/ + H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */ + H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */ + intn ret_value = FAIL; /*return value */ FUNC_ENTER(H5I_dec_ref, FAIL); - grp_ptr = id_group_list[grp]; + /* Check arguments */ + grp_ptr = H5I_id_group_list_g[grp]; if (grp_ptr == NULL || grp_ptr->count <= 0) { HRETURN(FAIL); } /* General lookup of the ID */ - if ((id_ptr = H5I_find_id(id)) != NULL) { - /* Decrement the reference count */ - ret_value = --(id_ptr->count); - - /* If the reference count is zero, remove the object from the group */ - if (0 == id_ptr->count && (obj = H5I_remove(id)) != NULL) { - /* - * call the user's 'free' function for the atom's information, - * otherwise just leak memory. - */ - if (grp_ptr->free_func) { - if ((grp_ptr->free_func)(obj)<0) { - HRETURN_ERROR (H5E_ATOM, H5E_CANTINIT, FAIL, - "unable to free atom"); - } + if ((id_ptr=H5I_find_id(id))) { + /* + * If this is the last reference to the object then invoke the group's + * free method on the object. If the free method is undefined or + * successful then remove the object from the group; otherwise leave + * the object in the group without decrementing the reference + * count. If the reference count is more than one then decrement the + * reference count without calling the free method. + * + * Beware: the free method may call other H5I functions. + */ + if (1==id_ptr->count) { + if (!grp_ptr->free_func || + (grp_ptr->free_func)(id_ptr->obj_ptr)>=0) { + H5I_remove(id); + ret_value = 0; + } else { + ret_value = 1; } + } else { + ret_value = --(id_ptr->count); } } FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_search - Search for an object in a group and get it's pointer. - - DESCRIPTION - Searchs for an object in a group and returns the pointer to it. - This routine calls the function pointer passed in for each object in the - group until it finds a match. Currently there is no way to resume a - search. - - RETURNS - Returns pointer an ID's object if successful and NULL otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_search + * + * Purpose: Apply function FUNC to each member of group GRP and return a + * pointer to the first object for which FUNC returns non-zero. + * The FUNC should take a pointer to the object and the KEY as + * arguments and return non-zero to terminate the search (zero + * to continue). + * + * Limitation: Currently there is no way to start searching from where a + * previous search left off. + * + * Return: Success: The first object in the group for which FUNC + * returns non-zero. NULL if FUNC returned zero + * for every object in the group. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ void * -H5I_search(H5I_type_t grp, /* IN: Group to search for the object in */ - H5I_search_func_t func, /* IN: Ptr to the comparison function */ - const void *key /* IN: pointer to key to compare against */ -) +H5I_search(H5I_type_t grp, H5I_search_func_t func, const void *key) { - H5I_id_group_t *grp_ptr = NULL; /* ptr to the group */ - H5I_id_info_t *id_ptr = NULL; /* ptr to the new ID */ - uintn i; /* local counting variable */ - void * ret_value = NULL; + H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */ + H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */ + uintn i; /*counter */ + void *ret_value = NULL; /*return value */ FUNC_ENTER(H5I_search, NULL); - if (grp <= H5I_BADID || grp >= H5I_MAXID) + /* Check arguments */ + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) { HGOTO_DONE(NULL); - - grp_ptr = id_group_list[grp]; - if (grp_ptr == NULL || grp_ptr->count <= 0) + } + grp_ptr = H5I_id_group_list_g[grp]; + if (grp_ptr == NULL || grp_ptr->count <= 0) { HGOTO_DONE(NULL); + } /* Start at the beginning of the array */ - for (i = 0; i < grp_ptr->hash_size; i++) { + for (i=0; i<grp_ptr->hash_size; i++) { id_ptr = grp_ptr->id_list[i]; - while (id_ptr != NULL) { - if ((*func) (id_ptr->obj_ptr, key)) - HGOTO_DONE(id_ptr->obj_ptr); /* found the item we are looking for */ + while (id_ptr) { + if ((*func)(id_ptr->obj_ptr, key)) { + HGOTO_DONE(id_ptr->obj_ptr); /*found the item*/ + } id_ptr = id_ptr->next; } } @@ -798,79 +866,95 @@ H5I_search(H5I_type_t grp, /* IN: Group to search for the object in */ FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_find_id - Finds a ID in a group - - DESCRIPTION - Retrieves the ID ptr which is associated with the ID. - - RETURNS - Returns ID ptr if successful and NULL otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_find_id + * + * Purpose: Given an object ID find the info struct that describes the + * object. + * + * Return: Success: Ptr to the object's info struct. + * + * Failure: NULL + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ static H5I_id_info_t * H5I_find_id(hid_t id) { - H5I_id_group_t *grp_ptr = NULL; /* ptr to the group */ - H5I_id_info_t *id_ptr = NULL; /* ptr to the new ID */ - H5I_type_t grp; /* ID's group */ - uintn hash_loc; /* ID's hash table location */ - H5I_id_info_t *ret_value = NULL; + H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */ + H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */ + H5I_type_t grp; /*ID's group */ + uintn hash_loc; /*bucket pointer */ + H5I_id_info_t *ret_value = NULL; /*return value */ FUNC_ENTER(H5I_find_id, NULL); + /* Check arguments */ grp = H5I_GROUP(id); - if (grp <= H5I_BADID || grp >= H5I_MAXID) + if (grp <= H5I_BADID || grp >= H5I_NGROUPS) { HGOTO_DONE(NULL); - - grp_ptr = id_group_list[grp]; - if (grp_ptr == NULL || grp_ptr->count <= 0) + } + grp_ptr = H5I_id_group_list_g[grp]; + if (grp_ptr == NULL || grp_ptr->count <= 0) { HGOTO_DONE(NULL); + } - /* Get the location in which the ID is located */ - hash_loc = (uintn) H5I_LOC(id, grp_ptr->hash_size); + /* Get the bucket in which the ID is located */ + hash_loc = (uintn)H5I_LOC(id, grp_ptr->hash_size); id_ptr = grp_ptr->id_list[hash_loc]; - if (id_ptr == NULL) + if (id_ptr == NULL) { HGOTO_DONE(NULL); + } - while (id_ptr != NULL) { + /* Scan the bucket's linked list for a match */ + while (id_ptr) { if (id_ptr->id == id) break; id_ptr = id_ptr->next; } ret_value = id_ptr; #ifdef IDS_ARE_CACHED - H5I_id_cache[ID_CACHE_SIZE-1] = id; - H5I_obj_cache[ID_CACHE_SIZE-1] = id_ptr->obj_ptr; + /* Add id to the end of the cache */ + H5I_id_cache_g[ID_CACHE_SIZE-1] = id; + H5I_obj_cache_g[ID_CACHE_SIZE-1] = id_ptr->obj_ptr; #endif /* IDS_ARE_CACHED */ done: FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_get_idm_node - Gets an ID node - - DESCRIPTION - Either gets an ID node from the free list (if there is one available) - or allocate a node. - - RETURNS - Returns ID ptr if successful and NULL otherwise - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_get_id_node + * + * Purpose: Either gets an ID node from the free list (if there is one + * available) or allocate a node. + * + * Return: Success: ID pointer + * + * Failure: NULL + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ static H5I_id_info_t * H5I_get_id_node(void) { - H5I_id_info_t *ret_value = NULL; + H5I_id_info_t *ret_value = NULL; FUNC_ENTER(H5I_get_id_node, NULL); - if (id_free_list != NULL) { - ret_value = id_free_list; - id_free_list = id_free_list->next; + if (H5I_id_free_list_g != NULL) { + ret_value = H5I_id_free_list_g; + H5I_id_free_list_g = H5I_id_free_list_g->next; } else if (NULL==(ret_value = H5MM_malloc(sizeof(H5I_id_info_t)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); @@ -879,69 +963,95 @@ H5I_get_id_node(void) FUNC_LEAVE(ret_value); } -/****************************************************************************** - NAME - H5I_release_id_node - Releases an ID node - - DESCRIPTION - Puts an ID node into the free list - - RETURNS - Non-negative on success/Negative on failure - -*******************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: H5I_release_id_node + * + * Purpose: Release an ID node and return it to the free list. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ static herr_t H5I_release_id_node(H5I_id_info_t *id) { FUNC_ENTER(H5I_release_id_node, FAIL); /* Insert the ID at the beginning of the free list */ - id->next = id_free_list; - id_free_list = id; + id->next = H5I_id_free_list_g; + H5I_id_free_list_g = id; FUNC_LEAVE(SUCCEED); } -/*-------------------------------------------------------------------------- - NAME - H5I_term_interface - PURPOSE - Terminate various static buffers. - USAGE - intn H5I_term_interface() - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Free various buffers allocated in the H5I routines. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Should only ever be called by the "atexit" function HDFend - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -void -H5I_term_interface(intn status) + +/*------------------------------------------------------------------------- + * Function: H5I_debug + * + * Purpose: Dump the contents of a group to stderr for debugging. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5I_debug(H5I_type_t grp) { - H5I_id_info_t *curr; - intn i; + H5I_id_group_t *grp_ptr; + H5I_id_info_t *cur; + int is, js; + unsigned int iu; - if (interface_initialize_g>0) { - /* Release the free-list */ - while (id_free_list) { - curr = id_free_list; - id_free_list = id_free_list->next; - HDfree(curr); + FUNC_ENTER(H5I_debug, FAIL); + + fprintf(stderr, "Dumping group %d\n", (int)grp); + grp_ptr = H5I_id_group_list_g[grp]; + + /* Header */ + fprintf(stderr, " count = %u\n", grp_ptr->count); + fprintf(stderr, " reserved = %u\n", grp_ptr->reserved); + fprintf(stderr, " wrapped = %u\n", grp_ptr->wrapped); + fprintf(stderr, " hash_size = %lu\n", + (unsigned long)grp_ptr->hash_size); + fprintf(stderr, " ids = %u\n", grp_ptr->ids); + fprintf(stderr, " nextid = %u\n", grp_ptr->nextid); + + /* Cache */ + fprintf(stderr, " Cache:\n"); + for (is=0; is<ID_CACHE_SIZE; is++) { + if (H5I_GROUP(H5I_id_cache_g[is])==grp) { + fprintf(stderr, " Entry-%d, ID=%lu\n", + is, (unsigned long)(H5I_id_cache_g[is])); } + } - /* Release all groups */ - for (i = 0; i < (intn) H5I_MAXID; i++) { - if (id_group_list[i] != NULL) { - HDfree(id_group_list[i]); - id_group_list[i] = NULL; - } + /* List */ + fprintf(stderr, " List:\n"); + for (iu=0; iu<grp_ptr->hash_size; iu++) { + for (js=0, cur=grp_ptr->id_list[iu]; cur; cur=cur->next, js++) { + fprintf(stderr, " #%u.%d\n", iu, js); + fprintf(stderr, " id = %lu\n", + (unsigned long)(cur->id)); + fprintf(stderr, " count = %u\n", cur->count); + fprintf(stderr, " obj = 0x%08lx\n", + (unsigned long)(cur->obj_ptr)); } } - - /* Indicate interface status */ - interface_initialize_g = status; + + FUNC_LEAVE(SUCCEED); } + diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index 4d3e4ef..a41a3d6 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -1,13 +1,13 @@ /**************************************************************************** - * NCSA HDF * - * Software Development Group * - * National Center for Supercomputing Applications * - * University of Illinois at Urbana-Champaign * - * 605 E. Springfield, Champaign IL 61820 * - * * - * For conditions of distribution and use, see the accompanying * - * hdf/COPYING file. * - * * + * NCSA HDF * + * Software Development Group * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * ****************************************************************************/ /*----------------------------------------------------------------------------- @@ -19,51 +19,60 @@ #ifndef _H5Iprivate_H #define _H5Iprivate_H -#include <H5Ipublic.h> /*include Public Definitions */ +#include <H5Ipublic.h> /*include Public Definitions */ /* Private headers needed by this file */ #include <H5private.h> /* Default sizes of the hash-tables for various atom groups */ -#define H5I_ERRSTACK_HASHSIZE 64 -#define H5I_FILEID_HASHSIZE 64 -#define H5I_TEMPID_HASHSIZE 64 -#define H5I_DATATYPEID_HASHSIZE 64 -#define H5I_DATASPACEID_HASHSIZE 64 -#define H5I_DATASETID_HASHSIZE 64 -#define H5I_OID_HASHSIZE 64 -#define H5I_GROUPID_HASHSIZE 64 -#define H5I_ATTRID_HASHSIZE 64 -#define H5I_TEMPBUFID_HASHSIZE 64 -#define H5I_RAGGED_HASHSIZE 64 -#define H5I_REFID_HASHSIZE 64 +#define H5I_ERRSTACK_HASHSIZE 64 +#define H5I_FILEID_HASHSIZE 64 +#define H5I_TEMPID_HASHSIZE 64 +#define H5I_DATATYPEID_HASHSIZE 64 +#define H5I_DATASPACEID_HASHSIZE 64 +#define H5I_DATASETID_HASHSIZE 64 +#define H5I_OID_HASHSIZE 64 +#define H5I_GROUPID_HASHSIZE 64 +#define H5I_ATTRID_HASHSIZE 64 +#define H5I_TEMPBUFID_HASHSIZE 64 +#define H5I_RAGGED_HASHSIZE 64 +#define H5I_REFID_HASHSIZE 64 + +/* + * Function for freeing objects. This function will be called with an object + * ID group number (object type) and a pointer to the object. The function + * should free the object and return non-negative to indicate that the object + * can be removed from the ID group. If the function returns negative + * (failure) then the object will remain in the ID group. + */ +typedef herr_t (*H5I_free_t)(void*); + +/* Type of the function to compare objects & keys */ +typedef intn (*H5I_search_func_t)(void *obj, const void *key); /* Atom information structure used */ typedef struct H5I_id_info_t { - hid_t id; /* ID for this info */ - uintn count; /* ref. count for this atom */ - void *obj_ptr; /* pointer associated with the atom */ - struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/ + hid_t id; /* ID for this info */ + uintn count; /* ref. count for this atom */ + void *obj_ptr; /* pointer associated with the atom */ + struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/ } H5I_id_info_t; /* ID group structure used */ typedef struct { - uintn count; /*# of times this group has been initialized */ - uintn reserved; /*# of IDs to reserve for constant IDs */ - uintn wrapped; /*whether the id count has wrapped around */ - size_t hash_size; /*sizeof the hash table to store the IDs in*/ - uintn ids; /*current number of IDs held */ - uintn nextid; /*ID to use for the next atom */ - herr_t (*free_func)(void*);/*func to call to release object */ - H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */ + uintn count; /*# of times this group has been initialized*/ + uintn reserved; /*# of IDs to reserve for constant IDs */ + uintn wrapped; /*whether the id count has wrapped around */ + size_t hash_size; /*sizeof the hash table to store the IDs in */ + uintn ids; /*current number of IDs held */ + uintn nextid; /*ID to use for the next atom */ + H5I_free_t free_func; /*release object method */ + H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */ } H5I_id_group_t; -/* Type of the function to compare objects & keys */ -typedef intn (*H5I_search_func_t) (void * obj, const void * key); - /* Private Functions in H5I.c */ __DLL__ intn H5I_init_group(H5I_type_t grp, size_t hash_size, uintn reserved, - herr_t (*free_func)(void *)); + H5I_free_t func); __DLL__ herr_t H5I_destroy_group(H5I_type_t grp); __DLL__ hid_t H5I_register(H5I_type_t grp, void *object); __DLL__ void *H5I_object(hid_t id); @@ -72,6 +81,4 @@ __DLL__ void *H5I_remove(hid_t id); __DLL__ void *H5I_search(H5I_type_t grp, H5I_search_func_t func, const void *key); __DLL__ intn H5I_dec_ref(hid_t id); -__DLL__ hid_t H5I_inc_ref(hid_t id); - #endif diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index 03b2717..2ae5640 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -1,13 +1,13 @@ /**************************************************************************** - * NCSA HDF * - * Software Development Group * - * National Center for Supercomputing Applications * - * University of Illinois at Urbana-Champaign * - * 605 E. Springfield, Champaign IL 61820 * - * * - * For conditions of distribution and use, see the accompanying * - * hdf/COPYING file. * - * * + * NCSA HDF * + * Software Development Group * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * ****************************************************************************/ /* @@ -22,32 +22,35 @@ /* * Group values allowed. Start with `1' instead of `0' because it makes the - * tracing output look better when hid_t values are large numbers. + * tracing output look better when hid_t values are large numbers. Change the + * GROUP_BITS in H5I.c if the MAXID gets larger than 32 (an assertion will + * fail otherwise). */ typedef enum { - H5I_BADID = (-1),/*invalid Group */ - H5I_FILE = 1, /*group ID for File objects */ - H5I_TEMPLATE_0, /*group ID for Template objects */ - H5I_TEMPLATE_1, /*group ID for Template objects */ - H5I_TEMPLATE_2, /*group ID for Template objects */ - H5I_TEMPLATE_3, /*group ID for Template objects */ - H5I_TEMPLATE_4, /*group ID for Template objects */ - H5I_TEMPLATE_5, /*group ID for Template objects */ - H5I_TEMPLATE_6, /*group ID for Template objects */ - H5I_TEMPLATE_7, /*group ID for Template objects */ + H5I_BADID = (-1), /*invalid Group */ + H5I_FILE = 1, /*group ID for File objects */ + H5I_FILE_CLOSING, /*files pending close due to open objhdrs */ + H5I_TEMPLATE_0, /*group ID for Template objects */ + H5I_TEMPLATE_1, /*group ID for Template objects */ + H5I_TEMPLATE_2, /*group ID for Template objects */ + H5I_TEMPLATE_3, /*group ID for Template objects */ + H5I_TEMPLATE_4, /*group ID for Template objects */ + H5I_TEMPLATE_5, /*group ID for Template objects */ + H5I_TEMPLATE_6, /*group ID for Template objects */ + H5I_TEMPLATE_7, /*group ID for Template objects */ #ifndef NDEBUG - H5I_TEMPLATE_MAX, /*not really a group ID */ + H5I_TEMPLATE_MAX, /*not really a group ID */ #endif - H5I_GROUP, /*group ID for Group objects */ - H5I_DATATYPE, /*group ID for Datatype objects */ - H5I_DATASPACE, /*group ID for Dataspace objects */ - H5I_DATASET, /*group ID for Dataset objects */ - H5I_ATTR, /*group ID for Attribute objects */ - H5I_TEMPBUF, /*group ID for Temporary buffer objects */ - H5I_RAGGED, /*group ID for Ragged array objects */ - H5I_REFERENCE, /*group ID for Reference objects */ - H5I_MAXID /*highest group in group_t (Invalid as true group)*/ - /* Change the GROUP_BITS in H5I.c if the MAXID gets larger than 32 */ + H5I_GROUP, /*group ID for Group objects */ + H5I_DATATYPE, /*group ID for Datatype objects */ + H5I_DATASPACE, /*group ID for Dataspace objects */ + H5I_DATASET, /*group ID for Dataset objects */ + H5I_ATTR, /*group ID for Attribute objects */ + H5I_TEMPBUF, /*group ID for Temporary buffer objects */ + H5I_RAGGED, /*group ID for Ragged array objects */ + H5I_REFERENCE, /*group ID for Reference objects */ + + H5I_NGROUPS /*number of valid groups, MUST BE LAST! */ } H5I_type_t; /* Type of atoms to return to users */ @@ -18,6 +18,7 @@ #include <H5ACprivate.h> #include <H5Eprivate.h> #include <H5Fprivate.h> +#include <H5Iprivate.h> #include <H5MFprivate.h> #include <H5MMprivate.h> #include <H5Oprivate.h> @@ -274,10 +275,11 @@ H5O_close(H5G_entry_t *obj_ent) /* * If the file open-lock count has reached zero and the file has a close - * pending then close the file. + * pending then close the file and remove it from the H5I_FILE_CLOSING ID + * group. */ - if (0 == obj_ent->file->nopen_objs && obj_ent->file->close_pending) { - H5F_close(obj_ent->file); + if (0==obj_ent->file->nopen_objs && obj_ent->file->closing) { + H5I_dec_ref(obj_ent->file->closing); } #ifdef H5O_DEBUG if (H5DEBUG(O)) { @@ -295,7 +295,7 @@ H5Pclose(hid_t plist_id) *------------------------------------------------------------------------- */ herr_t -H5P_close (H5P_class_t type, void *plist) +H5P_close(H5P_class_t type, void *plist) { H5F_access_t *fa_list = (H5F_access_t*)plist; H5D_create_t *dc_list = (H5D_create_t*)plist; @@ -59,7 +59,7 @@ H5R_init_interface(void) /* Initialize the atom group for the file IDs */ if (H5I_init_group(H5I_REFERENCE, H5I_REFID_HASHSIZE, H5R_RESERVED_ATOMS, - (herr_t (*)(void *)) NULL)<0) { + (H5I_free_t)NULL)<0) { HRETURN_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -370,9 +370,9 @@ H5R_dereference(H5D_t *dset, H5R_type_t ref_type, void *_ref) INT32DECODE(p,hobjid.idx); /* Get the dataset region from the heap (allocate inside routine) */ -printf("%s: hobjid.addr=",FUNC); -H5F_addr_print(stdout,&hobjid.addr); -printf(", hobjid.idx=%d\n", hobjid.idx); + printf("%s: hobjid.addr=",FUNC); + H5F_addr_print(stdout,&hobjid.addr); + printf(", hobjid.idx=%d\n", hobjid.idx); if((buf=H5HG_read(ent.file,&hobjid,NULL))==NULL) HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information"); @@ -79,7 +79,7 @@ H5RA_init_interface(void) /* The atom group */ if (H5I_init_group(H5I_RAGGED, H5I_RAGGED_HASHSIZE, 0, - (herr_t(*)(void*))H5RA_close)<0) { + (H5I_free_t)H5RA_close)<0) { HRETURN_ERROR (H5E_RAGGED, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -64,7 +64,7 @@ H5S_init_interface(void) /* Initialize the atom group for the file IDs */ if (H5I_init_group(H5I_DATASPACE, H5I_DATASPACEID_HASHSIZE, - H5S_RESERVED_ATOMS, (herr_t (*)(void *))H5S_close)<0) { + H5S_RESERVED_ATOMS, (H5I_free_t)H5S_close)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -183,7 +183,7 @@ H5T_init_interface(void) /* Initialize the atom group for the file IDs */ if (H5I_init_group(H5I_DATATYPE, H5I_DATATYPEID_HASHSIZE, - H5T_RESERVED_ATOMS, (herr_t (*)(void *))H5T_close)<0) { + H5T_RESERVED_ATOMS, (H5I_free_t)H5T_close)<0) { HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface"); } @@ -4222,7 +4222,7 @@ H5T_open (H5G_entry_t *loc, const char *name) "unable to open named data type"); } if (NULL==(dt=H5O_read (&ent, H5O_DTYPE, 0, NULL))) { - H5O_close (&ent); + H5O_close(&ent); HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to load type message from object header"); } @@ -4443,7 +4443,7 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type) done: if (ret_value<0) { if (H5F_addr_defined (&(type->ent.header))) { - H5O_close (&(type->ent)); + H5O_close(&(type->ent)); H5F_addr_undef (&(type->ent.header)); } } |