diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2005-07-01 05:35:29 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2005-07-01 05:35:29 (GMT) |
commit | 5e98cfee43a6755c258d0e7b9a3babea73c0534f (patch) | |
tree | c15e9463dba9a700e6542e6556eaee71564c1a3e /src/H5F.c | |
parent | 43f091f462202a84a863f000582e75fd6c04e6f4 (diff) | |
download | hdf5-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/H5F.c')
-rw-r--r-- | src/H5F.c | 53 |
1 files changed, 52 insertions, 1 deletions
@@ -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; |