summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2010-09-15 15:29:38 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2010-09-15 15:29:38 (GMT)
commitcb9a804f82bfe32451b4033d8a421efc60e5521e (patch)
tree333cc7049904dbf78df9d1c9ec146022f4e32eb3
parent96c26d2b17f28af6a25a7cd61449b1bac06b996d (diff)
downloadhdf5-cb9a804f82bfe32451b4033d8a421efc60e5521e.zip
hdf5-cb9a804f82bfe32451b4033d8a421efc60e5521e.tar.gz
hdf5-cb9a804f82bfe32451b4033d8a421efc60e5521e.tar.bz2
[svn-r19386] Purpose: Fix assertion failure caused by fractal heap header file pointer
Description: The fractal heap header structure keeps a pointer to the file associated with it. However, it is possible for that file pointer to be closed while the header is still in cache (through the shared file pointer). Previously, the header's file pointer was not updated and subsequently pointed to an invalid file structure. Modified fractal heap code to update the file pointer every time the header is accessed. Tested: jam, linew, amani (h5committest)
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5HF.c6
-rw-r--r--src/H5HFhdr.c3
-rw-r--r--test/fheap.c142
4 files changed, 147 insertions, 7 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index ef5ad26..87f6e40 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -244,6 +244,9 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Fixed a bug that could occur when getting information for a new-style
+ group that was previously opened through a file handle that was
+ later closed. (NAF - 2010/09/15)
- Added define check in H5public.h if stdint.h is supported by the C++
compiler. This define is only available on Windows with VS2010 and
using CMake to build the library. (ADB - 2010/09/13 - Bug 1938)
diff --git a/src/H5HF.c b/src/H5HF.c
index cc38f2a..23e15c2 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -859,9 +859,6 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr-
if(NULL == (hdr = H5HF_hdr_protect(fh->f, dxpl_id, heap_addr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
- /* Set the shared heap header's file context for this operation */
- hdr->f = fh->f;
-
/* Delete heap, starting with header (unprotects header) */
if(H5HF_hdr_delete(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to delete fractal heap")
@@ -913,9 +910,6 @@ HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
if(hdr->file_rc)
hdr->pending_delete = TRUE;
else {
- /* Set the shared heap header's file context for this operation */
- hdr->f = f;
-
/* Delete heap now, starting with header (unprotects header) */
if(H5HF_hdr_delete(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to delete fractal heap")
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c
index e678d74..684c171 100644
--- a/src/H5HFhdr.c
+++ b/src/H5HFhdr.c
@@ -552,6 +552,9 @@ H5HF_hdr_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5AC_protect_t rw)
/* Set the header's address */
hdr->heap_addr = addr;
+ /* Update header's file pointer */
+ hdr->f = f;
+
/* Set the return value */
ret_value = hdr;
diff --git a/test/fheap.c b/test/fheap.c
index f983184..e38302c 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -2975,7 +2975,7 @@ test_size(hid_t fapl, H5HF_create_t *cparam)
FAIL_STACK_ERROR
/* Re-open the heap */
- if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
+ if(NULL == (fh = H5HF_open(f, dxpl, fh_addr)))
FAIL_STACK_ERROR
/* Check the heap's size */
@@ -3019,6 +3019,145 @@ error:
return(1);
} /* test_size() */
+
+/*-------------------------------------------------------------------------
+ * Function: test_reopen_hdr
+ *
+ * Purpose: Test opening a header through one file handle, closing
+ * that file handle, then reopening through a different file
+ * handle that was open the whole time. The header should
+ * stay in cache between the two opens.
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, September 14, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned
+test_reopen_hdr(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file1 = -1; /* File ID */
+ hid_t file2 = -2; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_t *fh = NULL; /* Fractal heap wrapper */
+ haddr_t fh_addr; /* Address of fractal heap */
+ hsize_t heap_size; /* Total size of heap on disk */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file1 = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = (H5F_t *)H5I_object(file1)))
+ FAIL_STACK_ERROR
+
+ /* Ignore metadata tags in the file's cache */
+ if (H5AC_ignore_tags(f) < 0)
+ FAIL_STACK_ERROR
+
+ /* Display testing message */
+ TESTING("reopening header through different file")
+
+
+ /* Create absolute heap */
+ if(NULL == (fh = H5HF_create(f, dxpl, cparam)))
+ FAIL_STACK_ERROR
+
+ /* Get heap's address */
+ if(H5HF_get_heap_addr(fh, &fh_addr) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ TEST_ERROR
+
+ /* Insert an object */
+ if(add_obj(fh, dxpl, (size_t)0, (size_t)10, NULL, NULL) < 0)
+ TEST_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file */
+ if(H5Fclose(file1) < 0)
+ FAIL_STACK_ERROR
+
+
+ /* Re-open the file */
+ if((file1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Re-open the file again */
+ if((file2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object (file1) */
+ if(NULL == (f = (H5F_t *)H5I_object(file1)))
+ FAIL_STACK_ERROR
+
+ /* Ignore metadata tags in the file's cache */
+ if (H5AC_ignore_tags(f) < 0)
+ FAIL_STACK_ERROR
+
+ /* Open the heap */
+ if(NULL == (fh = H5HF_open(f, dxpl, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Close the heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file (file1) */
+ if(H5Fclose(file1) < 0)
+ FAIL_STACK_ERROR
+
+
+ /* Get a pointer to the internal file object (file2) */
+ if(NULL == (f = (H5F_t *)H5I_object(file2)))
+ FAIL_STACK_ERROR
+
+ /* Reopen the heap */
+ if(NULL == (fh = H5HF_open(f, dxpl, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Check the heap's size */
+ heap_size = 0;
+ if(H5HF_size(fh, dxpl, &heap_size) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+
+
+ /* Close the file (file2) */
+ if(H5Fclose(file2) < 0)
+ FAIL_STACK_ERROR
+
+ /* All tests passed */
+ PASSED()
+
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ if(fh)
+ H5HF_close(fh, dxpl);
+ H5Fclose(file1);
+ H5Fclose(file2);
+ } H5E_END_TRY;
+ return(1);
+} /* test_reopen_hdr() */
+
#ifndef QAK2
/*-------------------------------------------------------------------------
@@ -16159,6 +16298,7 @@ curr_test = FHEAP_TEST_NORMAL;
nerrors += test_id_limits(fapl, &small_cparam);
nerrors += test_filtered_create(fapl, &small_cparam);
nerrors += test_size(fapl, &small_cparam);
+ nerrors += test_reopen_hdr(fapl, &small_cparam);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */