From f003dead4d1701aedd7833354ede73c6eb93a971 Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Tue, 30 Mar 1999 06:38:34 -0500 Subject: [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. --- config/conclude.in | 9 ++- src/H5.c | 87 +++++++++------------ src/H5A.c | 42 ++++++---- src/H5D.c | 27 +++++-- src/H5F.c | 65 +++++++--------- src/H5Flow.c | 68 ++++++++--------- src/H5Fprivate.h | 2 +- src/H5Fsec2.c | 63 +++++++-------- src/H5G.c | 38 +++++---- src/H5I.c | 220 +++++++++++++++++++++++++++++++++++++---------------- src/H5Iprivate.h | 2 + src/H5O.c | 17 +++-- src/H5Odtype.c | 2 + src/H5P.c | 26 +++++-- src/H5R.c | 19 +++-- src/H5RA.c | 28 ++++--- src/H5S.c | 184 +++++++++++++++++++++++--------------------- src/H5T.c | 88 +++++++++++---------- src/H5TB.c | 47 ++++++------ src/H5Tprivate.h | 2 +- src/H5Z.c | 14 ++-- src/H5detect.c | 11 +-- src/H5private.h | 33 ++++---- tools/h5ls.c | 37 ++++++--- 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+50) { - 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; i0) { - /* Empty the object type table */ - for (i=0; i0) { + if (interface_initialize_g) { + + /* How many groups are still being used? */ for (grp=(H5I_type_t)0; grpcount = 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; grpnext; - 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; ihash_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; ifree_func) { + for (i=0; ihash_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; ifree_func) { - for (i=0; ihash_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; i0) { - /* 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; istats[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; istats[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; i0) { - - /* Unregister all conversion functions */ - for (i=0; ifunc) { - 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; ifunc) { + 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; i0) { + printf(" %-10s ", "Type:"); + display_type(type, 15); + printf("\n"); + } return 0; } -- cgit v0.12