summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-07-01 05:35:29 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-07-01 05:35:29 (GMT)
commit5e98cfee43a6755c258d0e7b9a3babea73c0534f (patch)
treec15e9463dba9a700e6542e6556eaee71564c1a3e /src
parent43f091f462202a84a863f000582e75fd6c04e6f4 (diff)
downloadhdf5-5e98cfee43a6755c258d0e7b9a3babea73c0534f.zip
hdf5-5e98cfee43a6755c258d0e7b9a3babea73c0534f.tar.gz
hdf5-5e98cfee43a6755c258d0e7b9a3babea73c0534f.tar.bz2
[svn-r11009] Purpose:
Bug fix Description: When a series of files is mounted on one another and one of those files is not unmounted, the library gets confused at shutdown and goes into an infinite loop in the file interface. Solution: If there are still files left in the "closing" state when shutting down the file API, iterate over those file IDs and unmount any child files that we find mounted on those files. Platforms tested: FreeBSD 4.11 (sleipnir) Too minor to require h5committest
Diffstat (limited to 'src')
-rw-r--r--src/H5F.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 63e108b..8c73e86 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -415,6 +415,53 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5F_term_unmount_cb
+ *
+ * Purpose: H5F_term_interface' callback function. This routine
+ * unmounts child files from files that are in the "closing"
+ * state.
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, Jun 30, 2005
+ *
+ * Modification:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void UNUSED *key)
+{
+ H5F_t *f = (H5F_t *)obj_ptr; /* Alias for search info */
+ unsigned u; /* Local index */
+ int ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_term_unmount_cb)
+
+ assert(f);
+
+ if(f->mtab.nmounts) {
+ /* Unmount all child files */
+ for (u=0; u<f->mtab.nmounts; u++) {
+ f->mtab.child[u].file->mtab.parent = NULL;
+ if(H5G_close(f->mtab.child[u].group)<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close child group")
+ if(H5F_close(f->mtab.child[u].file)<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file")
+ } /* end if */
+ f->mtab.nmounts = 0;
+
+ /* Decrement reference count for file */
+ H5I_dec_ref(obj_id);
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "no files to unmount")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5F_term_unmount_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_term_interface
*
* Purpose: Terminate this interface: free all memory and reset global
@@ -444,7 +491,11 @@ H5F_term_interface(void)
if (H5_interface_initialize_g) {
if ((n=H5I_nmembers(H5I_FILE))!=0) {
H5I_clear_type(H5I_FILE, FALSE);
- } else if (0==(n=H5I_nmembers(H5I_FILE_CLOSING))) {
+ } else if ((n=H5I_nmembers(H5I_FILE_CLOSING))!=0) {
+ /* Attempt to unmount any child files from files that are closing */
+ (void)H5I_search(H5I_FILE_CLOSING, H5F_term_unmount_cb, NULL);
+ }
+ else {
H5I_dec_type_ref(H5I_FILE);
H5I_dec_type_ref(H5I_FILE_CLOSING);
H5_interface_initialize_g = 0;