summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-03-30 11:38:34 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-03-30 11:38:34 (GMT)
commitf003dead4d1701aedd7833354ede73c6eb93a971 (patch)
treee64999eb9d666aedd808f1c91f4a2be8676d6881
parent804fae33ced79c63a2c7fa2adc8537c80597fb33 (diff)
downloadhdf5-f003dead4d1701aedd7833354ede73c6eb93a971.zip
hdf5-f003dead4d1701aedd7833354ede73c6eb93a971.tar.gz
hdf5-f003dead4d1701aedd7833354ede73c6eb93a971.tar.bz2
[svn-r1169] ./configure.in
./configure [REGENERATED] ./src/H5D.c ./src/H5O.c Removed H5AC, H5B, and H5T from the default list of packages to debug (because they're pretty expensive debugging), and added H5O. Also fixed a bug for undefined variable in H5D when H5S debugging is turned on but H5T debugging is turned off. ./config/conclude.in Fixed installation of header files for building in a directory other than the source directory. This fixes a bug where H5config.h wasn't being installed. ./src/H5.c ./src/H5A.c ./src/H5D.c ./src/H5F.c ./src/H5G.c ./src/H5I.c ./src/H5Iprivate.h ./src/H5P.c ./src/H5R.c ./src/H5RA.c ./src/H5S.c ./src/H5T.c ./src/H5TB.c ./src/H5Tprivate.h ./src/H5Z.c ./src/H5detect.c ./src/H5private.h Changed the way the library shuts down again. Now it handles cycles between packages and isn't so sensitive to dependencies between packages. A package might shut down only to be restarted to process a request from some other package being shut down. Loops are detected after 100 iteractions and the shutdown is aborted with a message on standard error. This also makes it a lot easier to debug. ./src/H5A.c Fixed H5A_write() and H5A_read() so they pass a non-null background buffer to the conversion functions. This is necessary when an attribute has a compound data type. ./src/H5Flow.c ./src/H5Fprivate.h ./src/H5Fsec2.c Reindented new Win32 stuff. ./src/H5Odtype.c Fixed a bug when enumeration types are used in a compound data type. The byte pointer wasn't incremented after the type information was written. ./tools/h5ls.c Compound data types display their total size because it's not always obvious from looking at the members. Scalar attributes show their space as `scalar' instead of `{}'. The index value is not printed for attributes that have only a few values. Instead the word `Data:' is printed on the first line of attribute data. Named types display their data type only if verbose output was requested.
-rw-r--r--config/conclude.in9
-rw-r--r--src/H5.c87
-rw-r--r--src/H5A.c42
-rw-r--r--src/H5D.c27
-rw-r--r--src/H5F.c65
-rw-r--r--src/H5Flow.c68
-rw-r--r--src/H5Fprivate.h2
-rw-r--r--src/H5Fsec2.c63
-rw-r--r--src/H5G.c38
-rw-r--r--src/H5I.c220
-rw-r--r--src/H5Iprivate.h2
-rw-r--r--src/H5O.c17
-rw-r--r--src/H5Odtype.c2
-rw-r--r--src/H5P.c26
-rw-r--r--src/H5R.c19
-rw-r--r--src/H5RA.c28
-rw-r--r--src/H5S.c184
-rw-r--r--src/H5T.c88
-rw-r--r--src/H5TB.c47
-rw-r--r--src/H5Tprivate.h2
-rw-r--r--src/H5Z.c14
-rw-r--r--src/H5detect.c11
-rw-r--r--src/H5private.h33
-rw-r--r--tools/h5ls.c37
24 files changed, 650 insertions, 481 deletions
diff --git a/config/conclude.in b/config/conclude.in
index 3b82c06..28dfc36 100644
--- a/config/conclude.in
+++ b/config/conclude.in
@@ -55,8 +55,13 @@ install: $(LIB) $(PUB_HDR) $(PROGS)
@test -d $(includedir) || mkdir $(includedir)
@for f in X $(PUB_HDR); do \
if test $$f != X; then \
- (set -x; $(INSTALL_DATA) $$f $(includedir)/. || exit 1); \
- fi \
+ if test -f $$f; then \
+ (set -x; $(INSTALL_DATA) $$f $(includedir)/. || exit 1); \
+ else \
+ (set -x; $(INSTALL_DATA) $(srcdir)/$$f $(includedir)/. || \
+ exit 1); \
+ fi; \
+ fi; \
done
@test -d $(bindir) || mkdir $(bindir)
@for f in X $(PROGS); do \
diff --git a/src/H5.c b/src/H5.c
index 5df4d4a..ea6b476 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -130,65 +130,46 @@ H5_init_library(void)
void
H5_term_library(void)
{
+ intn pending, ntries=0, n;
+ uintn at=0;
+ char loop[1024];
+
/* Don't do anything if the library is already closed */
if (!H5_libinit_g) return;
/*
- * Close interfaces in a well-defined order based on dependencies. The
- * goal is that closing one interface doesn't reopen another that was
- * just closed. In order to help us track down dependencies that we
- * didn't know about, we close the interfaces in a two step process. The
- * first step does the real work and makes the interface unusable. The
- * second step doesn't do any work but makes it possible to reopen the
- * interface later.
- */
-
- /*
- * Cycles: The H5F layer participates in quite a few dependency cycles
- * because it's cache depends on almost all other meta object
- * packages and those packages depend on H5O which depends on H5F
- * (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.
- */
- H5F_close_all();
-
- /* Function What depends on it? */
- /*------------------------- ------------------------------- */
- H5D_term_interface(-1); /* */
- H5TB_term_interface(-1); /* */
- H5Z_term_interface(-1); /* */
- H5A_term_interface(-1); /* */
- H5RA_term_interface(-1); /* */
- H5G_term_interface(-1); /* */
- H5R_term_interface(-1); /* */
- H5S_term_interface(-1); /* */
- H5T_native_close(-1); /* D RA */
- H5T_term_interface(-1); /* D RA */
- 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 */
- /*------------------------- --------------------------------- */
-
- /*
- * Finalize the closing by calling all the functions again but with an
- * argument of zero. This allows the interface to be reopened later.
+ * Terminate each interface. The termination functions return a positive
+ * value if they do something that might affect some other interface in a
+ * way that would necessitate some cleanup work in the other interface.
*/
- H5A_term_interface(0);
- H5D_term_interface(0);
- H5F_term_interface(0);
- H5G_term_interface(0);
- H5I_term_interface(0);
- H5P_term_interface(0);
- H5RA_term_interface(0);
- H5R_term_interface(0);
- H5S_term_interface(0);
- H5TB_term_interface(0);
- H5T_native_close(0);
- H5T_term_interface(0);
- H5Z_term_interface(0);
+#define DOWN(F) \
+ (((n=H5##F##_term_interface()) && at+5<sizeof loop)? \
+ (sprintf(loop+at, "%s%s", at?",":"", #F), \
+ at += strlen(loop+at), \
+ n):0)
+
+ do {
+ pending = 0;
+ pending += DOWN(F);
+ pending += DOWN(D);
+ pending += DOWN(TB);
+ pending += DOWN(Z);
+ pending += DOWN(RA);
+ pending += DOWN(G);
+ pending += DOWN(R);
+ pending += DOWN(S);
+ pending += DOWN(TN);
+ pending += DOWN(T);
+ pending += DOWN(A);
+ pending += DOWN(P);
+ pending += DOWN(I);
+ } while (pending && ntries++<100);
+ if (pending) {
+ fprintf(stderr, "HDF5: infinite loop closing library\n");
+ fprintf(stderr, " %s\n", loop);
+ }
+
/* Mark library as closed */
H5_libinit_g = FALSE;
}
diff --git a/src/H5A.c b/src/H5A.c
index d7cb783..68b9173 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -93,13 +93,21 @@ H5A_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void
-H5A_term_interface(intn status)
+intn
+H5A_term_interface(void)
{
- if (interface_initialize_g>0) {
- H5I_destroy_group(H5I_ATTR);
+ intn n=0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_ATTR))) {
+ H5I_clear_group(H5I_ATTR);
+ } else {
+ H5I_destroy_group(H5I_ATTR);
+ interface_initialize_g = 0;
+ n = 1;
+ }
}
- interface_initialize_g = status;
+ return n;
}
@@ -602,6 +610,7 @@ static herr_t
H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf)
{
uint8_t *tconv_buf = NULL; /* data type conv buffer */
+ uint8_t *bkg_buf = NULL; /* temp conversion buffer */
size_t nelmts; /* elements in attribute */
H5T_path_t *tpath = NULL; /* conversion information*/
hid_t src_id = -1, dst_id = -1;/* temporary type atoms */
@@ -626,7 +635,8 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf)
/* Get the maximum buffer size needed and allocate it */
buf_size = nelmts*MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5MM_malloc (buf_size))) {
+ if (NULL==(tconv_buf = H5MM_malloc (buf_size)) ||
+ NULL==(bkg_buf = H5MM_malloc(buf_size))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -650,7 +660,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf)
}
/* Perform data type conversion */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, tconv_buf, NULL)<0) {
+ if (H5T_convert(tpath, src_id, dst_id, nelmts, tconv_buf, bkg_buf)<0) {
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL,
"data type conversion failed");
}
@@ -683,6 +693,8 @@ done:
H5I_dec_ref(dst_id);
if (tconv_buf)
H5MM_xfree(tconv_buf);
+ if (bkg_buf)
+ H5MM_xfree(bkg_buf);
FUNC_LEAVE(ret_value);
} /* H5A_write() */
@@ -761,6 +773,7 @@ static herr_t
H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf)
{
uint8_t *tconv_buf = NULL; /* data type conv buffer*/
+ uint8_t *bkg_buf = NULL; /* background buffer */
size_t nelmts; /* elements in attribute*/
H5T_path_t *tpath = NULL; /* type conversion info */
hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/
@@ -789,7 +802,8 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf)
else { /* Attribute exists and has a value */
/* Get the maximum buffer size needed and allocate it */
buf_size = nelmts*MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5MM_malloc (buf_size))) {
+ if (NULL==(tconv_buf = H5MM_malloc (buf_size)) ||
+ NULL==(bkg_buf = H5MM_malloc(buf_size))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -812,11 +826,11 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf)
}
}
- /* Perform data type conversion. */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, tconv_buf, NULL)<0) {
- HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL,
- "data type conversion failed");
- }
+ /* Perform data type conversion. */
+ if (H5T_convert(tpath, src_id, dst_id, nelmts, tconv_buf, bkg_buf)<0) {
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL,
+ "data type conversion failed");
+ }
/* Copy the converted data into the user's buffer */
HDmemcpy(buf,tconv_buf,dst_type_size*nelmts);
@@ -832,6 +846,8 @@ done:
H5I_dec_ref(dst_id);
if (tconv_buf)
H5MM_xfree(tconv_buf);
+ if (bkg_buf)
+ H5MM_xfree(bkg_buf);
FUNC_LEAVE(ret_value);
} /* H5A_read() */
diff --git a/src/H5D.c b/src/H5D.c
index 6f55154..623d57a 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -129,7 +129,10 @@ H5D_init_interface(void)
*
* Purpose: Terminate this interface.
*
- * Return: void
+ * Return: Success: Positive if anything was done that might
+ * affect other interfaces; zero otherwise.
+ *
+ * Failure: Negative.
*
* Programmer: Robb Matzke
* Friday, November 20, 1998
@@ -138,13 +141,21 @@ H5D_init_interface(void)
*
*-------------------------------------------------------------------------
*/
-void
-H5D_term_interface(intn status)
+intn
+H5D_term_interface(void)
{
- if (interface_initialize_g>0) {
- H5I_destroy_group(H5I_DATASET);
+ int n=0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_DATASET))) {
+ H5I_clear_group(H5I_DATASET);
+ } else {
+ H5I_destroy_group(H5I_DATASET);
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ }
}
- interface_initialize_g = status;
+ return n;
}
@@ -1465,7 +1476,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5T_bkg_t need_bkg; /*type of background buf*/
H5S_t *free_this_space=NULL; /*data space to free */
hbool_t must_convert; /*have to xfer the slow way */
-#ifdef H5T_DEBUG
+#if defined(H5S_DEBUG) || defined(H5T_DEBUG)
H5_timer_t timer;
#endif
@@ -1815,7 +1826,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5T_bkg_t need_bkg; /*type of background buf*/
H5S_t *free_this_space=NULL; /*data space to free */
hbool_t must_convert; /*have to xfer the slow way*/
-#ifdef H5T_DEBUG
+#if defined(H5S_DEBUG) || defined(H5T_DEBUG)
H5_timer_t timer;
#endif
diff --git a/src/H5F.c b/src/H5F.c
index 57b4162..67d229c 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -212,9 +212,11 @@ H5F_init_interface(void)
* variables to their initial values. Release all ID groups
* associated with this interface.
*
- * Return: Success:
+ * Return: Success: Positive if anything was done that might
+ * have affected other interfaces; zero
+ * otherwise.
*
- * Failure:
+ * Failure: Never fails.
*
* Programmer: Robb Matzke
* Friday, February 19, 1999
@@ -223,14 +225,22 @@ H5F_init_interface(void)
*
*-------------------------------------------------------------------------
*/
-void
-H5F_term_interface(intn status)
+intn
+H5F_term_interface(void)
{
- if (interface_initialize_g>0) {
- H5I_destroy_group(H5I_FILE);
- H5I_destroy_group(H5I_FILE_CLOSING);
+ intn n = 0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_FILE))) {
+ H5F_close_all();
+ } else if (0==(n=H5I_nmembers(H5I_FILE_CLOSING))) {
+ H5I_destroy_group(H5I_FILE);
+ H5I_destroy_group(H5I_FILE_CLOSING);
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ }
}
- interface_initialize_g = status;
+ return n;
}
@@ -287,7 +297,9 @@ H5F_flush_all(hbool_t invalidate)
/*-------------------------------------------------------------------------
* Function: H5F_close_all
*
- * Purpose: Close all open files.
+ * Purpose: Close all open files. Any file which has open object headers
+ * will be moved from the H5I_FILE group to the H5I_FILE_CLOSING
+ * group.
*
* Return: Success: Non-negative
*
@@ -304,26 +316,7 @@ herr_t
H5F_close_all(void)
{
FUNC_ENTER(H5F_close_all, FAIL);
-
- /*
- * Close all normally open files. Any file which has open object headers
- * will be moved to the H5I_FILE_CLOSING ID 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");
- }
-
+ H5I_clear_group(H5I_FILE);
FUNC_LEAVE(SUCCEED);
}
@@ -788,7 +781,6 @@ H5F_dest(H5F_t *f)
*/
--f->nrefs;
}
-
FUNC_LEAVE(ret_value);
}
@@ -954,7 +946,6 @@ 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)) ||
(old = H5I_search(H5I_FILE_CLOSING, H5F_compare_files, &search))) {
if (flags & H5F_ACC_TRUNC) {
@@ -975,9 +966,7 @@ H5F_open(const char *name, uintn flags,
}
f = H5F_new(old->shared, NULL, NULL);
- }
-
- else if (flags & H5F_ACC_TRUNC) {
+ } else if (flags & H5F_ACC_TRUNC) {
/* Truncate existing file */
if (0 == (flags & H5F_ACC_RDWR)) {
HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL,
@@ -1817,12 +1806,12 @@ H5F_close(H5F_t *f)
}
}
#ifdef WIN32
- /*free up the memory for path*/
+ /*free up the memory for path*/
- free(f->shared->key.path);
+ free(f->shared->key.path);
#endif
-
- /*
+
+ /*
* 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.
diff --git a/src/H5Flow.c b/src/H5Flow.c
index c1b426d..2570930 100644
--- a/src/H5Flow.c
+++ b/src/H5Flow.c
@@ -492,47 +492,43 @@ H5F_low_access(const H5F_low_class_t *type, const char *name,
if (key) {
#ifdef WIN32
-
-/*
- some windows specific types. the LPSTR is just a char*
-*/
- LPSTR pathbuf = NULL;
- LPSTR *namebuf = NULL;
- int bufsize = 0;
-
-
+ /*
+ * Some windows specific types. the LPSTR is just a char*
+ */
+ LPSTR pathbuf = NULL;
+ LPSTR *namebuf = NULL;
+ int bufsize = 0;
+
+
+ /*
+ * Gets the full path of the file name. the if statement below
+ * is to try to distinguish if we have the ablosute path already
+ */
+ if ((*(name+1) != ':') && (*(name+2)!= '\\')){
/*
- gets the full path of the file name. the if statement below is to try
- to distinguish if we have the ablosute path already
- */
-
- if ((*(name+1) != ':') && (*(name+2)!= '\\')){
- /*
- if the size of the buffer is too small it will return
- the appropriate size of the buffer not including the null
- */
- bufsize = GetFullPathName(name,bufsize,pathbuf,namebuf);
- if (bufsize != 0){
- pathbuf = malloc(sizeof(char) * (bufsize + 1));
- namebuf = malloc(sizeof(char) * (bufsize + 1));
- bufsize++;
- GetFullPathName(name,bufsize,pathbuf,namebuf);
- }
- else {
- pathbuf = NULL;
- }
- }
- else {
- pathbuf = malloc(strlen(name));
- strcpy(pathbuf,name);
+ * if the size of the buffer is too small it will return
+ * the appropriate size of the buffer not including the null
+ */
+ bufsize = GetFullPathName(name,bufsize,pathbuf,namebuf);
+ if (bufsize != 0){
+ pathbuf = malloc(sizeof(char) * (bufsize + 1));
+ namebuf = malloc(sizeof(char) * (bufsize + 1));
+ bufsize++;
+ GetFullPathName(name,bufsize,pathbuf,namebuf);
+ } else {
+ pathbuf = NULL;
}
+ } else {
+ pathbuf = malloc(strlen(name));
+ strcpy(pathbuf,name);
+ }
- key->path = pathbuf;
- key->dev = 0;
- key->ino = 0;
+ key->path = pathbuf;
+ key->dev = 0;
+ key->ino = 0;
#else
HDstat(name, &sb);
- key->path = NULL;
+ key->path = NULL;
key->dev = sb.st_dev;
key->ino = sb.st_ino;
#endif
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 92f5ead..55048b3 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -302,7 +302,7 @@ typedef struct H5F_access_t {
typedef struct H5F_search_t {
dev_t dev; /* Device number containing file */
ino_t ino; /* Unique file number on device */
- char* path;
+ char *path; /* File name used only in Win32 */
} H5F_search_t;
/* For determining what the last file operation was */
diff --git a/src/H5Fsec2.c b/src/H5Fsec2.c
index 27dfa51..e71f793 100644
--- a/src/H5Fsec2.c
+++ b/src/H5Fsec2.c
@@ -99,41 +99,36 @@ H5F_sec2_open(const char *name, const H5F_access_t __unused__ *access_parms,
if (key) {
#if WIN32
-/*
- some windows specific types. the LPSTR is just a char*
-*/
- LPSTR pathbuf = NULL;
- LPSTR *namebuf = NULL;
- int bufsize = 0;
-
-
- /*
- gets the full path of the file name. the if statement below is to try
- to distinguish if we have the ablosute path already
- */
+ /*
+ * some windows specific types. the LPSTR is just a char*
+ */
+ LPSTR pathbuf = NULL;
+ LPSTR *namebuf = NULL;
+ int bufsize = 0;
- if ((*(name+1) != ':') && (*(name+2)!= '\\')){
- /*
- if the size of the buffer is too small it will return
- the appropriate size of the buffer not including the null
- */
- bufsize = GetFullPathName(name,bufsize,pathbuf,namebuf);
- if (bufsize != 0){
- pathbuf = malloc(sizeof(char) * (bufsize + 1));
- namebuf = malloc(sizeof(char) * (bufsize + 1));
- bufsize++;
- GetFullPathName(name,bufsize,pathbuf,namebuf);
- }
- else {
- pathbuf = NULL;
- }
- }
- else {
- pathbuf = malloc(strlen(name));
- strcpy(pathbuf,name);
- }
-
- key->path = pathbuf;
+ /*
+ * gets the full path of the file name. the if statement below is to
+ * try to distinguish if we have the ablosute path already
+ */
+ if ((*(name+1) != ':') && (*(name+2)!= '\\')){
+ /*
+ * if the size of the buffer is too small it will return
+ * the appropriate size of the buffer not including the null
+ */
+ bufsize = GetFullPathName(name,bufsize,pathbuf,namebuf);
+ if (bufsize != 0){
+ pathbuf = malloc(sizeof(char) * (bufsize + 1));
+ namebuf = malloc(sizeof(char) * (bufsize + 1));
+ bufsize++;
+ GetFullPathName(name,bufsize,pathbuf,namebuf);
+ } else {
+ pathbuf = NULL;
+ }
+ } else {
+ pathbuf = malloc(strlen(name));
+ strcpy(pathbuf,name);
+ }
+ key->path = pathbuf;
#else
key->path = NULL;
#endif
diff --git a/src/H5G.c b/src/H5G.c
index ad87ccb..7b76e41 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -706,7 +706,10 @@ H5G_init_interface(void)
*
* Purpose: Terminates the H5G interface
*
- * Return: void
+ * Return: Success: Positive if anything is done that might
+ * affect other interfaces; zero otherwise.
+ *
+ * Failure: Negative.
*
* Programmer: Robb Matzke
* Monday, January 5, 1998
@@ -715,24 +718,33 @@ H5G_init_interface(void)
*
*-------------------------------------------------------------------------
*/
-void
-H5G_term_interface(intn status)
+intn
+H5G_term_interface(void)
{
size_t i;
+ intn n=0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_GROUP))) {
+ H5I_clear_group(H5I_GROUP);
+ } else {
+ /* Empty the object type table */
+ for (i=0; i<H5G_ntypes_g; i++) {
+ H5MM_xfree(H5G_type_g[i].desc);
+ }
+ H5G_ntypes_g = H5G_atypes_g = 0;
+ H5G_type_g = H5MM_xfree(H5G_type_g);
+
+ /* Destroy the group object id group */
+ H5I_destroy_group(H5I_GROUP);
- if (interface_initialize_g>0) {
- /* Empty the object type table */
- for (i=0; i<H5G_ntypes_g; i++) {
- H5MM_xfree(H5G_type_g[i].desc);
+ /* Mark closed */
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
}
- H5G_ntypes_g = H5G_atypes_g = 0;
- H5G_type_g = H5MM_xfree(H5G_type_g);
-
- /* Destroy the group object id group */
- H5I_destroy_group(H5I_GROUP);
}
- interface_initialize_g = status;
+ return n;
}
diff --git a/src/H5I.c b/src/H5I.c
index a9bf18f..75bb5c9 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -152,9 +152,13 @@ H5I_init_interface(void)
* Function: H5I_term_interface
*
* Purpose: Terminate the H5I interface: release all memory, reset all
- * global variables to initial values.
+ * global variables to initial values. This only happens if all
+ * groups have been destroyed from other interfaces.
*
- * Return: void
+ * Return: Success: Positive if any action was taken that might
+ * affect some other interface; zero otherwise.
+ *
+ * Failure: Negative.
*
* Programmer:
*
@@ -162,39 +166,43 @@ H5I_init_interface(void)
*
*-------------------------------------------------------------------------
*/
-void
-H5I_term_interface(intn status)
+intn
+H5I_term_interface(void)
{
H5I_id_group_t *grp_ptr;
H5I_id_info_t *curr;
H5I_type_t grp;
+ intn n=0;
- if (interface_initialize_g>0) {
+ if (interface_initialize_g) {
+
+ /* How many groups are still being used? */
for (grp=(H5I_type_t)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);
+ if ((grp_ptr=H5I_id_group_list_g[grp]) && grp_ptr->id_list) {
+ n++;
+ }
+ }
+
+ /* If no groups are used then clean up */
+ if (0==n) {
+ for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; grp++) {
+ grp_ptr = H5I_id_group_list_g[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);
+ /* 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);
+ }
}
+
+ /* Mark interface closed */
+ interface_initialize_g = 0;
}
-
- /* Indicate interface status */
- interface_initialize_g = status;
+ return n;
}
@@ -300,6 +308,129 @@ H5I_init_group(H5I_type_t grp, size_t hash_size, uintn reserved,
/*-------------------------------------------------------------------------
+ * Function: H5I_nmembers
+ *
+ * Purpose: Returns the number of members in a group.
+ *
+ * Return: Success: Number of members; zero if the group is empty
+ * or has been deleted.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, March 24, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+intn
+H5I_nmembers(H5I_type_t grp)
+{
+ H5I_id_group_t *grp_ptr = NULL;
+ H5I_id_info_t *cur=NULL;
+ intn n=0;
+ uintn i;
+
+ FUNC_ENTER(H5I_nmembers, FAIL);
+
+ if (grp<=H5I_BADID || grp>=H5I_NGROUPS) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
+ }
+ if (NULL==(grp_ptr=H5I_id_group_list_g[grp]) || grp_ptr->count<=0) {
+ HRETURN(0);
+ }
+
+ for (i=0; i<grp_ptr->hash_size; i++) {
+ for (cur=grp_ptr->id_list[i]; cur; cur=cur->next) {
+ n++;
+ }
+ }
+ FUNC_LEAVE(n);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_clear_group
+ *
+ * Purpose: Removes all objects from the group, calling the free
+ * function for each object regardless of the reference count.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, March 24, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5I_clear_group(H5I_type_t grp)
+{
+ H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ H5I_id_info_t *cur=NULL, *next=NULL;
+ intn ret_value = SUCCEED;
+ uintn i;
+
+ FUNC_ENTER(H5I_clear_group, FAIL);
+
+ if (grp <= H5I_BADID || grp >= H5I_NGROUPS) {
+ HGOTO_DONE(FAIL);
+ }
+
+ grp_ptr = H5I_id_group_list_g[grp];
+ if (grp_ptr == NULL || grp_ptr->count <= 0) {
+ HGOTO_DONE(FAIL);
+ }
+
+#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_g[i]) == grp) {
+ H5I_id_cache_g[i] = (-1);
+ H5I_obj_cache_g[i] = NULL;
+ }
+ }
+#endif /* IDS_ARE_CACHED */
+
+ /*
+ * Call free method for all objects in group regardless of their 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 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;
+ H5I_release_id_node(cur);
+ }
+ grp_ptr->id_list[i]=NULL;
+ }
+ }
+
+ done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5I_destroy_group
*
* Purpose: Decrements the reference count on an entire group of IDs.
@@ -324,9 +455,7 @@ herr_t
H5I_destroy_group(H5I_type_t grp)
{
H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- H5I_id_info_t *cur=NULL, *next=NULL;
intn ret_value = SUCCEED;
- uintn i;
FUNC_ENTER(H5I_destroy_group, FAIL);
@@ -345,46 +474,7 @@ H5I_destroy_group(H5I_type_t grp)
* free function is invoked for each atom being freed.
*/
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_g[i]) == grp) {
- H5I_id_cache_g[i] = (-1);
- H5I_obj_cache_g[i] = NULL;
- }
- }
-#endif /* IDS_ARE_CACHED */
-
- /*
- * 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 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 */
+ H5I_clear_group(grp);
H5MM_xfree(grp_ptr->id_list);
HDmemset (grp_ptr, 0, sizeof(*grp_ptr));
} else {
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index a41a3d6..99b6628 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -73,6 +73,8 @@ typedef struct {
/* Private Functions in H5I.c */
__DLL__ intn H5I_init_group(H5I_type_t grp, size_t hash_size, uintn reserved,
H5I_free_t func);
+__DLL__ intn H5I_nmembers(H5I_type_t grp);
+__DLL__ herr_t H5I_clear_group(H5I_type_t grp);
__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);
diff --git a/src/H5O.c b/src/H5O.c
index b55de7c..ff90661 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -273,6 +273,18 @@ H5O_close(H5G_entry_t *obj_ent)
/* Decrement open-lock counters */
--obj_ent->file->nopen_objs;
+#ifdef H5O_DEBUG
+ if (H5DEBUG(O)) {
+ if (obj_ent->file->closing && 1==obj_ent->file->shared->nrefs) {
+ HDfprintf(H5DEBUG(O), "< %a auto %lu remaining\n",
+ &(obj_ent->header),
+ (unsigned long)(obj_ent->file->nopen_objs));
+ } else {
+ HDfprintf(H5DEBUG(O), "< %a\n", &(obj_ent->header));
+ }
+ }
+#endif
+
/*
* If the file open-lock count has reached zero and the file has a close
* pending then close the file and remove it from the H5I_FILE_CLOSING ID
@@ -281,11 +293,6 @@ H5O_close(H5G_entry_t *obj_ent)
if (0==obj_ent->file->nopen_objs && obj_ent->file->closing) {
H5I_dec_ref(obj_ent->file->closing);
}
-#ifdef H5O_DEBUG
- if (H5DEBUG(O)) {
- HDfprintf(H5DEBUG(O), "< %a\n", &(obj_ent->header));
- }
-#endif
FUNC_LEAVE(SUCCEED);
}
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 662d2d4..9f45a6c 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -248,6 +248,7 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
/* Values */
HDmemcpy(dt->u.enumer.value, *pp,
dt->u.enumer.nmembs * dt->parent->size);
+ *pp += dt->u.enumer.nmembs * dt->parent->size;
break;
case H5T_REFERENCE:
@@ -269,6 +270,7 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
FUNC_LEAVE(SUCCEED);
}
+
/*-------------------------------------------------------------------------
* Function: H5O_dtype_encode_helper
diff --git a/src/H5P.c b/src/H5P.c
index 230e81a..dff20bb 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -100,18 +100,28 @@ H5P_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void
-H5P_term_interface(intn status)
+intn
+H5P_term_interface(void)
{
- intn i;
+ intn i, n=0;
- if (interface_initialize_g>0) {
- for (i = 0; i < H5P_NCLASSES; i++) {
- H5I_destroy_group((H5I_type_t)(H5I_TEMPLATE_0 + i));
+ if (interface_initialize_g) {
+ for (i=0; i<H5P_NCLASSES; i++) {
+ n += H5I_nmembers((H5I_type_t)(H5I_TEMPLATE_0+i));
+ }
+ if (n) {
+ for (i=0; i<H5P_NCLASSES; i++) {
+ H5I_clear_group((H5I_type_t)(H5I_TEMPLATE_0+i));
+ }
+ } else {
+ for (i=0; i<H5P_NCLASSES; i++) {
+ H5I_destroy_group((H5I_type_t)(H5I_TEMPLATE_0 + i));
+ n++; /*H5I*/
+ }
+ interface_initialize_g = 0;
}
}
-
- interface_initialize_g = status;
+ return n;
}
/*--------------------------------------------------------------------------
diff --git a/src/H5R.c b/src/H5R.c
index 2fa4fd2..0ba7898 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -87,15 +87,22 @@ H5R_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void
-H5R_term_interface(intn status)
+intn
+H5R_term_interface(void)
{
- if (interface_initialize_g>0) {
- /* Free ID group */
- H5I_destroy_group(H5I_REFERENCE);
+ intn n=0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_REFERENCE))) {
+ H5I_clear_group(H5I_REFERENCE);
+ } else {
+ H5I_destroy_group(H5I_REFERENCE);
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ }
}
- interface_initialize_g = status;
+ return n;
}
diff --git a/src/H5RA.c b/src/H5RA.c
index 76455b5..bf0f5ef 100644
--- a/src/H5RA.c
+++ b/src/H5RA.c
@@ -106,7 +106,10 @@ H5RA_init_interface(void)
*
* Purpose: Terminate the ragged array interface.
*
- * Return: void
+ * Return: Success: Positive if anything was done that might
+ * affect some other interface. Zero otherwise.
+ *
+ * Failure: Negaitive
*
* Programmer: Robb Matzke
* Tuesday, August 25, 1998
@@ -115,16 +118,23 @@ H5RA_init_interface(void)
*
*-------------------------------------------------------------------------
*/
-void
-H5RA_term_interface(intn status)
+intn
+H5RA_term_interface(void)
{
- if (interface_initialize_g>0) {
- H5I_destroy_group(H5I_RAGGED);
- H5T_close(H5RA_meta_type_g);
- H5RA_meta_type_g = NULL;
+ intn n=0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_RAGGED))) {
+ H5I_clear_group(H5I_RAGGED);
+ } else {
+ H5T_close(H5RA_meta_type_g);
+ H5RA_meta_type_g = NULL;
+ H5I_destroy_group(H5I_RAGGED);
+ interface_initialize_g = 0;
+ n = 1; /*H5T,H5I*/
+ }
}
-
- interface_initialize_g = status;
+ return n;
}
diff --git a/src/H5S.c b/src/H5S.c
index 0d82b83..ff0a31c 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -108,10 +108,11 @@ H5S_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void
-H5S_term_interface(intn status)
+intn
+H5S_term_interface(void)
{
size_t i;
+ intn n=0;
#ifdef H5S_DEBUG
int j, nprints=0;
@@ -119,99 +120,110 @@ H5S_term_interface(intn status)
char buf[256];
#endif
- if (interface_initialize_g>0) {
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_DATASPACE))) {
+ H5I_clear_group(H5I_DATASPACE);
+ } else {
#ifdef H5S_DEBUG
- /*
- * Print statistics about each conversion path.
- */
- if (H5DEBUG(S)) {
- for (i=0; i<H5S_nconv_g; i++) {
- path = H5S_conv_g[i];
- for (j=0; j<2; j++) {
- if (0==path->stats[j].gath_ncalls &&
- 0==path->stats[j].scat_ncalls &&
- 0==path->stats[j].bkg_ncalls) {
- continue;
- }
- if (0==nprints++) {
- fprintf(H5DEBUG(S), "H5S: data space conversion "
- "statistics:\n");
- fprintf(H5DEBUG(S),
- " %-16s %10s %10s %8s %8s %8s %10s\n",
- "Memory <> File", "Bytes", "Calls",
- "User", "System", "Elapsed", "Bandwidth");
- fprintf(H5DEBUG(S),
- " %-16s %10s %10s %8s %8s %8s %10s\n",
- "--------------", "-----", "-----",
- "----", "------", "-------", "---------");
- }
-
- /* Summary */
- sprintf(buf, "%s %c %s",
- path->m->name, 0==j?'>':'<', path->f->name);
- fprintf(H5DEBUG(S), " %-16s\n", buf);
-
- /* Gather */
- if (path->stats[j].gath_ncalls) {
- H5_bandwidth(buf, (double)(path->stats[j].gath_nbytes),
- path->stats[j].gath_timer.etime);
- HDfprintf(H5DEBUG(S),
- " %16s %10Hu %10Hu %8.2f %8.2f %8.2f "
- "%10s\n", "gather",
- path->stats[j].gath_nbytes,
- path->stats[j].gath_ncalls,
- path->stats[j].gath_timer.utime,
- path->stats[j].gath_timer.stime,
- path->stats[j].gath_timer.etime,
- buf);
- }
-
- /* Scatter */
- if (path->stats[j].scat_ncalls) {
- H5_bandwidth(buf, (double)(path->stats[j].scat_nbytes),
- path->stats[j].scat_timer.etime);
- HDfprintf(H5DEBUG(S),
- " %16s %10Hu %10Hu %8.2f %8.2f %8.2f "
- "%10s\n", "scatter",
- path->stats[j].scat_nbytes,
- path->stats[j].scat_ncalls,
- path->stats[j].scat_timer.utime,
- path->stats[j].scat_timer.stime,
- path->stats[j].scat_timer.etime,
- buf);
- }
-
- /* Background */
- if (path->stats[j].bkg_ncalls) {
- H5_bandwidth(buf, (double)(path->stats[j].bkg_nbytes),
- path->stats[j].bkg_timer.etime);
- HDfprintf(H5DEBUG(S),
- " %16s %10Hu %10Hu %8.2f %8.2f %8.2f "
- "%10s\n", "background",
- path->stats[j].bkg_nbytes,
- path->stats[j].bkg_ncalls,
- path->stats[j].bkg_timer.utime,
- path->stats[j].bkg_timer.stime,
- path->stats[j].bkg_timer.etime,
- buf);
+ /*
+ * Print statistics about each conversion path.
+ */
+ if (H5DEBUG(S)) {
+ for (i=0; i<H5S_nconv_g; i++) {
+ path = H5S_conv_g[i];
+ for (j=0; j<2; j++) {
+ if (0==path->stats[j].gath_ncalls &&
+ 0==path->stats[j].scat_ncalls &&
+ 0==path->stats[j].bkg_ncalls) {
+ continue;
+ }
+ if (0==nprints++) {
+ fprintf(H5DEBUG(S), "H5S: data space conversion "
+ "statistics:\n");
+ fprintf(H5DEBUG(S),
+ " %-16s %10s %10s %8s %8s %8s %10s\n",
+ "Memory <> File", "Bytes", "Calls",
+ "User", "System", "Elapsed", "Bandwidth");
+ fprintf(H5DEBUG(S),
+ " %-16s %10s %10s %8s %8s %8s %10s\n",
+ "--------------", "-----", "-----",
+ "----", "------", "-------", "---------");
+ }
+
+ /* Summary */
+ sprintf(buf, "%s %c %s",
+ path->m->name, 0==j?'>':'<', path->f->name);
+ fprintf(H5DEBUG(S), " %-16s\n", buf);
+
+ /* Gather */
+ if (path->stats[j].gath_ncalls) {
+ H5_bandwidth(buf,
+ (double)(path->stats[j].gath_nbytes),
+ path->stats[j].gath_timer.etime);
+ HDfprintf(H5DEBUG(S),
+ " %16s %10Hu %10Hu %8.2f %8.2f %8.2f "
+ "%10s\n", "gather",
+ path->stats[j].gath_nbytes,
+ path->stats[j].gath_ncalls,
+ path->stats[j].gath_timer.utime,
+ path->stats[j].gath_timer.stime,
+ path->stats[j].gath_timer.etime,
+ buf);
+ }
+
+ /* Scatter */
+ if (path->stats[j].scat_ncalls) {
+ H5_bandwidth(buf,
+ (double)(path->stats[j].scat_nbytes),
+ path->stats[j].scat_timer.etime);
+ HDfprintf(H5DEBUG(S),
+ " %16s %10Hu %10Hu %8.2f %8.2f %8.2f "
+ "%10s\n", "scatter",
+ path->stats[j].scat_nbytes,
+ path->stats[j].scat_ncalls,
+ path->stats[j].scat_timer.utime,
+ path->stats[j].scat_timer.stime,
+ path->stats[j].scat_timer.etime,
+ buf);
+ }
+
+ /* Background */
+ if (path->stats[j].bkg_ncalls) {
+ H5_bandwidth(buf,
+ (double)(path->stats[j].bkg_nbytes),
+ path->stats[j].bkg_timer.etime);
+ HDfprintf(H5DEBUG(S),
+ " %16s %10Hu %10Hu %8.2f %8.2f %8.2f "
+ "%10s\n", "background",
+ path->stats[j].bkg_nbytes,
+ path->stats[j].bkg_ncalls,
+ path->stats[j].bkg_timer.utime,
+ path->stats[j].bkg_timer.stime,
+ path->stats[j].bkg_timer.etime,
+ buf);
+ }
}
}
}
- }
#endif
- /* Free data types */
- H5I_destroy_group(H5I_DATASPACE);
+ /* Free data types */
+ H5I_destroy_group(H5I_DATASPACE);
- /* Clear/free conversion table */
- HDmemset(H5S_fconv_g, 0, sizeof(H5S_fconv_g));
- HDmemset(H5S_mconv_g, 0, sizeof(H5S_mconv_g));
- for (i=0; i<H5S_nconv_g; i++) H5MM_xfree(H5S_conv_g[i]);
- H5S_conv_g = H5MM_xfree(H5S_conv_g);
- H5S_nconv_g = H5S_aconv_g = 0;
+ /* Clear/free conversion table */
+ HDmemset(H5S_fconv_g, 0, sizeof(H5S_fconv_g));
+ HDmemset(H5S_mconv_g, 0, sizeof(H5S_mconv_g));
+ for (i=0; i<H5S_nconv_g; i++) H5MM_xfree(H5S_conv_g[i]);
+ H5S_conv_g = H5MM_xfree(H5S_conv_g);
+ H5S_nconv_g = H5S_aconv_g = 0;
+
+ /* Shut down interface */
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ }
}
- interface_initialize_g = status;
+ return n;
}
diff --git a/src/H5T.c b/src/H5T.c
index 28fe21c..e1d9dd1 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -192,7 +192,7 @@ H5T_init_interface(void)
* Initialize pre-defined native data types from code generated during
* the library configuration by H5detect.
*/
- if (H5T_native_open()<0) {
+ if (H5TN_init_interface()<0) {
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize interface");
}
@@ -1091,7 +1091,11 @@ H5T_unlock_cb (void *_dt, const void __unused__ *key)
*
* Purpose: Close this interface.
*
- * Return: void
+ * Return: Success: Positive if any action might have caused a
+ * change in some other interface; zero
+ * otherwise.
+ *
+ * Failure: Negative
*
* Programmer: Robb Matzke
* Friday, November 20, 1998
@@ -1102,53 +1106,59 @@ H5T_unlock_cb (void *_dt, const void __unused__ *key)
* called.
*-------------------------------------------------------------------------
*/
-void
-H5T_term_interface(intn status)
+intn
+H5T_term_interface(void)
{
- intn i, nprint=0;
+ intn i, nprint=0, n=0;
H5T_path_t *path = NULL;
- if (interface_initialize_g>0) {
-
- /* Unregister all conversion functions */
- for (i=0; i<H5T_g.npaths; i++) {
- path = H5T_g.path[i];
- assert (path);
-
- if (path->func) {
- H5T_print_stats(path, &nprint/*in,out*/);
- path->cdata.command = H5T_CONV_FREE;
- if ((path->func)(FAIL, FAIL, &(path->cdata),
- 0, NULL, NULL)<0) {
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_DATATYPE))) {
+ H5I_clear_group(H5I_DATATYPE);
+ } else {
+ /* Unregister all conversion functions */
+ for (i=0; i<H5T_g.npaths; i++) {
+ path = H5T_g.path[i];
+ assert (path);
+
+ if (path->func) {
+ H5T_print_stats(path, &nprint/*in,out*/);
+ path->cdata.command = H5T_CONV_FREE;
+ if ((path->func)(FAIL, FAIL, &(path->cdata),
+ 0, NULL, NULL)<0) {
#ifdef H5T_DEBUG
- if (H5DEBUG(T)) {
- fprintf (H5DEBUG(T), "H5T: conversion function "
- "0x%08lx failed to free private data for %s "
- "(ignored)\n",
- (unsigned long)(path->func), path->name);
- }
+ if (H5DEBUG(T)) {
+ fprintf (H5DEBUG(T), "H5T: conversion function "
+ "0x%08lx failed to free private data for "
+ "%s (ignored)\n",
+ (unsigned long)(path->func), path->name);
+ }
#endif
- H5E_clear(); /*ignore the error*/
+ H5E_clear(); /*ignore the error*/
+ }
}
+ H5T_close (path->src);
+ H5T_close (path->dst);
+ H5MM_xfree (path);
+ H5T_g.path[i] = NULL;
}
- H5T_close (path->src);
- H5T_close (path->dst);
- H5MM_xfree (path);
- H5T_g.path[i] = NULL;
- }
- /* Clear conversion tables */
- H5T_g.path = H5MM_xfree(H5T_g.path);
- H5T_g.npaths = H5T_g.apaths = 0;
- H5T_g.soft = H5MM_xfree(H5T_g.soft);
- H5T_g.nsoft = H5T_g.asoft = 0;
+ /* Clear conversion tables */
+ H5T_g.path = H5MM_xfree(H5T_g.path);
+ H5T_g.npaths = H5T_g.apaths = 0;
+ H5T_g.soft = H5MM_xfree(H5T_g.soft);
+ H5T_g.nsoft = H5T_g.asoft = 0;
- /* Unlock all datatypes, then free them */
- H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
- H5I_destroy_group(H5I_DATATYPE);
+ /* Unlock all datatypes, then free them */
+ H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
+ H5I_destroy_group(H5I_DATATYPE);
+
+ /* Mark interface as closed */
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ }
}
-
- interface_initialize_g = status;
+ return n;
}
diff --git a/src/H5TB.c b/src/H5TB.c
index 93b87d6..19d400e 100644
--- a/src/H5TB.c
+++ b/src/H5TB.c
@@ -108,33 +108,36 @@ H5TB_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void
-H5TB_term_interface(intn status)
+intn
+H5TB_term_interface(void)
{
H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */
*next; /* pointer to next temp. buffer */
-
- if (interface_initialize_g>0) {
- /* Destroy the atom group */
- H5I_destroy_group(H5I_TEMPBUF);
-
- /* Step through the list and free the buffers */
- while(curr!=NULL) {
- next=curr->next;
-
- if(curr->buf!=NULL)
- H5MM_xfree(curr->buf);
- H5MM_xfree(curr);
-
- curr=next;
- } /* end while */
-
- /* Reset head & tail pointers */
- H5TB_list_head=H5TB_list_tail=NULL;
+ intn n=0;
+
+ if (interface_initialize_g) {
+ if ((n=H5I_nmembers(H5I_TEMPBUF))) {
+ H5I_clear_group(H5I_TEMPBUF);
+ } else {
+ /* Free group and buffers */
+ H5I_destroy_group(H5I_TEMPBUF);
+ while(curr!=NULL) {
+ next=curr->next;
+
+ if(curr->buf!=NULL)
+ H5MM_xfree(curr->buf);
+ H5MM_xfree(curr);
+
+ curr=next;
+ }
+ H5TB_list_head=H5TB_list_tail=NULL;
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ }
}
-
- interface_initialize_g = status;
+ return n;
}
+
/*-------------------------------------------------------------------------
* Function: H5TB_close
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 8d59f40..f5aed63 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -61,7 +61,7 @@ typedef struct H5T_path_t {
#define H5T_IS_NOOP(P) ((P)->is_hard && 0==H5T_cmp((P)->src, (P)->dst))
/* Private functions */
-__DLL__ herr_t H5T_native_open(void);
+__DLL__ herr_t H5TN_init_interface(void);
__DLL__ herr_t H5T_init(void);
__DLL__ htri_t H5T_isa(H5G_entry_t *ent);
__DLL__ H5T_t *H5T_open(H5G_entry_t *loc, const char *name);
diff --git a/src/H5Z.c b/src/H5Z.c
index bb22f47..8a5b7b3 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -72,8 +72,8 @@ H5Z_init_interface (void)
*
*-------------------------------------------------------------------------
*/
-void
-H5Z_term_interface (intn status)
+intn
+H5Z_term_interface (void)
{
size_t i;
#ifdef H5Z_DEBUG
@@ -81,7 +81,7 @@ H5Z_term_interface (intn status)
char comment[16], bandwidth[32];
#endif
- if (interface_initialize_g>0) {
+ if (interface_initialize_g) {
#ifdef H5Z_DEBUG
if (H5DEBUG(Z)) {
for (i=0; i<H5Z_table_used_g; i++) {
@@ -103,7 +103,8 @@ H5Z_term_interface (intn status)
}
/* Truncate the comment to fit in the field */
- HDstrncpy(comment, H5Z_table_g[i].name, sizeof comment);
+ HDstrncpy(comment, H5Z_table_g[i].name,
+ sizeof comment);
comment[sizeof(comment)-1] = '\0';
/*
@@ -129,16 +130,15 @@ H5Z_term_interface (intn status)
}
}
#endif
-
/* Free the table */
for (i=0; i<H5Z_table_used_g; i++) {
H5MM_xfree(H5Z_table_g[i].name);
}
H5Z_table_g = H5MM_xfree(H5Z_table_g);
H5Z_table_used_g = H5Z_table_alloc_g = 0;
+ interface_initialize_g = 0;
}
-
- interface_initialize_g = status;
+ return 0;
}
diff --git a/src/H5detect.c b/src/H5detect.c
index 84b5401..558e02e 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -377,20 +377,21 @@ static intn interface_initialize_g = 0;\n\
/* The interface termination function */
printf("\n\
-void\n\
-H5T_native_close(intn status)\n\
+intn\n\
+H5TN_term_interface(void)\n\
{\n\
- interface_initialize_g = status;\n\
+ interface_initialize_g = 0;\n\
+ return 0;\n\
}\n");
/* The interface initialization function */
printf("\n\
herr_t\n\
-H5T_native_open (void)\n\
+H5TN_init_interface(void)\n\
{\n\
H5T_t *dt = NULL;\n\
\n\
- FUNC_ENTER (H5T_init, FAIL);\n");
+ FUNC_ENTER (H5TN_init_interface, FAIL);\n");
for (i = 0; i < nd; i++) {
diff --git a/src/H5private.h b/src/H5private.h
index 84f3b0f..651c93e 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -886,15 +886,12 @@ extern hbool_t H5_libinit_g; /*good thing C's lazy about extern! */
interface_initialize_g = 1; \
if (interface_init_func && \
((herr_t(*)(void))interface_init_func)()<0) { \
+ interface_initialize_g = 0; \
HRETURN_ERROR (H5E_FUNC, H5E_CANTINIT, err, \
"interface initialization failed"); \
} \
- } else if (interface_initialize_g<0) { \
- assert("interface is closing" && 0); \
- HRETURN_ERROR(H5E_FUNC, H5E_CANTINIT, err, \
- "interface is closing"); \
} \
- \
+ \
/* Clear thread error stack entering public functions */ \
if (H5E_clearable_g && H5_IS_API (FUNC)) { \
H5E_clear (); \
@@ -938,19 +935,19 @@ __DLL__ herr_t H5_init_library(void);
__DLL__ void H5_term_library(void);
/* Functions to terminate interfaces */
-__DLL__ void H5A_term_interface(intn status);
-__DLL__ void H5D_term_interface(intn status);
-__DLL__ void H5F_term_interface(intn status);
-__DLL__ void H5G_term_interface(intn status);
-__DLL__ void H5I_term_interface(intn status);
-__DLL__ void H5P_term_interface(intn status);
-__DLL__ void H5RA_term_interface(intn status);
-__DLL__ void H5R_term_interface(intn status);
-__DLL__ void H5S_term_interface(intn status);
-__DLL__ void H5TB_term_interface(intn status);
-__DLL__ void H5T_native_close(intn status);
-__DLL__ void H5T_term_interface(intn status);
-__DLL__ void H5Z_term_interface(intn status);
+__DLL__ intn H5A_term_interface(void);
+__DLL__ intn H5D_term_interface(void);
+__DLL__ intn H5F_term_interface(void);
+__DLL__ intn H5G_term_interface(void);
+__DLL__ intn H5I_term_interface(void);
+__DLL__ intn H5P_term_interface(void);
+__DLL__ intn H5RA_term_interface(void);
+__DLL__ intn H5R_term_interface(void);
+__DLL__ intn H5S_term_interface(void);
+__DLL__ intn H5TB_term_interface(void);
+__DLL__ intn H5TN_term_interface(void);
+__DLL__ intn H5T_term_interface(void);
+__DLL__ intn H5Z_term_interface(void);
#endif
diff --git a/tools/h5ls.c b/tools/h5ls.c
index d1c3552..45e0deb 100644
--- a/tools/h5ls.c
+++ b/tools/h5ls.c
@@ -641,6 +641,7 @@ display_cmpd_type(hid_t type, int indent)
char *name=NULL; /*member name */
int ndims; /*dimensionality */
size_t dims[8]; /*dimensions */
+ size_t size; /*total size of type in bytes */
int perm[8]; /*index permutation */
hid_t subtype; /*member data type */
int i, j, n; /*miscellaneous counters */
@@ -684,7 +685,9 @@ display_cmpd_type(hid_t type, int indent)
display_type(subtype, indent+4);
H5Tclose(subtype);
}
- printf("\n%*s}", indent, "");
+ size = H5Tget_size(type);
+ printf("\n%*s} %lu byte%s",
+ indent, "", (unsigned long)size, 1==size?"":"s");
return TRUE;
}
@@ -1036,28 +1039,36 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data)
printf(" Attribute: ");
n = display_string(stdout, attr_name, TRUE);
- printf("%*s", MAX(0, 10-n), "");
+ printf("%*s", MAX(0, 9-n), "");
if ((attr = H5Aopen_name(obj, attr_name))) {
space = H5Aget_space(attr);
type = H5Aget_type(attr);
/* Data space */
ndims = H5Sget_simple_extent_dims(space, size, NULL);
- printf(" {");
- for (i=0; i<ndims; i++) {
- HDfprintf(stdout, "%s%Hu", i?", ":"", size[i]);
- nelmts *= size[i];
+ if (0==ndims) {
+ puts(" scalar");
+ } else {
+ printf(" {");
+ for (i=0; i<ndims; i++) {
+ HDfprintf(stdout, "%s%Hu", i?", ":"", size[i]);
+ nelmts *= size[i];
+ }
+ puts("}");
}
- puts("}");
/* Data type */
- printf(" Type: ");
+ printf(" Type: ");
display_type(type, 15);
putchar('\n');
/* Data */
memset(&info, 0, sizeof info);
- info.idx_fmt = " (%s) ";
+ if (nelmts<5) {
+ info.idx_fmt = " Data: ";
+ } else {
+ info.idx_fmt = " (%s) ";
+ }
info.line_ncols = width_g;
if (label_g) info.cmpd_name = "%s=";
if (string_g && 1==H5Tget_size(type) &&
@@ -1322,9 +1333,11 @@ group_list2(hid_t grp, const char *name)
static herr_t
datatype_list2(hid_t type, const char __unused__ *name)
{
- printf(" %-10s ", "Type:");
- display_type(type, 15);
- printf("\n");
+ if (verbose_g>0) {
+ printf(" %-10s ", "Type:");
+ display_type(type, 15);
+ printf("\n");
+ }
return 0;
}