summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-10-02 09:57:26 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-10-02 09:57:26 (GMT)
commit9bc29ea538b9ce2013a8cde5be230c18cf052009 (patch)
tree0cafa58d457568fe89a36243caef60da30571af6
parenta03647db10e8f80b9ff132b8e43a795547ffad42 (diff)
downloadhdf5-9bc29ea538b9ce2013a8cde5be230c18cf052009.zip
hdf5-9bc29ea538b9ce2013a8cde5be230c18cf052009.tar.gz
hdf5-9bc29ea538b9ce2013a8cde5be230c18cf052009.tar.bz2
[svn-r12699] Description:
Fix problems with opening a fractal heap multiple times, from different file handles. Tested on: FreeBSD/32 4.11 (sleipnir) w/threadsafe Linux/32 2.4 (heping) w/FORTRAN & C++ Linux/64 2.4 (mir) w/enable-v1.6 Mac OS/32 10.4.8 (amazon)
-rw-r--r--src/H5HF.c116
-rw-r--r--src/H5HFhdr.c65
-rw-r--r--src/H5HFpkg.h7
3 files changed, 122 insertions, 66 deletions
diff --git a/src/H5HF.c b/src/H5HF.c
index 338512ae..29b2e4d 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -126,7 +126,7 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
{
H5HF_t *fh = NULL; /* Pointer to new fractal heap */
H5HF_hdr_t *hdr = NULL; /* The fractal heap header information */
- haddr_t hdr_addr; /* Heap header address */
+ haddr_t fh_addr; /* Heap header address */
H5HF_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5HF_create, NULL)
@@ -138,7 +138,7 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
HDassert(cparam);
/* Create shared fractal heap header */
- if(HADDR_UNDEF == (hdr_addr = H5HF_hdr_create(f, dxpl_id, cparam)))
+ if(HADDR_UNDEF == (fh_addr = H5HF_hdr_create(f, dxpl_id, cparam)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't create fractal heap header")
/* Allocate fractal heap wrapper */
@@ -146,7 +146,7 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
/* Lock the heap header into memory */
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to load fractal heap header")
/* Point fractal heap wrapper at header and bump it's ref count */
@@ -154,22 +154,19 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
if(H5HF_hdr_incr(fh->hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header")
- /* Unlock heap header, now pinned */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header")
- hdr = NULL;
-
- /* Add heap to list of open objects in file */
- if(H5FO_insert(f, fh->hdr->heap_addr, fh, FALSE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert heap into list of open objects")
+ /* Increment # of files using this heap header */
+ if(H5HF_hdr_fuse_incr(fh->hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment file reference count on shared heap header")
- /* Set open object count */
- fh->fo_count = 1;
+ /* Set file pointer for this heap open context */
+ fh->f = f;
/* Set the return value */
ret_value = fh;
done:
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header")
if(!ret_value) {
if(fh)
(void)H5HF_close(fh, dxpl_id);
@@ -208,42 +205,31 @@ H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
HDassert(f);
HDassert(H5F_addr_defined(fh_addr));
- /* Check if group was already open */
- if((fh = H5FO_opened(f, fh_addr)) == NULL) {
-
- /* Clear any errors from H5FO_opened() */
- H5E_clear_stack(NULL);
-
- /* Load the heap header into memory */
+ /* Load the heap header into memory */
#ifdef QAK
HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
#endif /* QAK */
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load fractal heap header")
+ if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load fractal heap header")
#ifdef QAK
HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fspace);
#endif /* QAK */
- /* Create fractal heap info */
- if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
+ /* Create fractal heap info */
+ if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
- /* Point fractal heap wrapper at header */
- fh->hdr = hdr;
- if(H5HF_hdr_incr(fh->hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header")
+ /* Point fractal heap wrapper at header */
+ fh->hdr = hdr;
+ if(H5HF_hdr_incr(fh->hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header")
- /* Add heap to list of open objects in file */
- if(H5FO_insert(f, fh->hdr->heap_addr, fh, FALSE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert heap into list of open objects")
+ /* Increment # of files using this heap header */
+ if(H5HF_hdr_fuse_incr(fh->hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment file reference count on shared heap header")
- /* Set open object count */
- fh->fo_count = 1;
- } /* end if */
- else {
- /* Increment shared reference count */
- fh->fo_count++;
- } /* end else */
+ /* Set file pointer for this heap open context */
+ fh->f = f;
/* Set the return value */
ret_value = fh;
@@ -357,6 +343,9 @@ HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size);
if(size == 0)
HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "can't insert 0-sized objects")
+ /* Set the shared heap header's file context for this operation */
+ fh->hdr->f = fh->f;
+
/* Get the fractal heap header */
hdr = fh->hdr;
@@ -429,6 +418,9 @@ H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *_id, size_t *obj_len_p)
if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR)
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "incorrect heap ID version")
+ /* Set the shared heap header's file context for this operation */
+ fh->hdr->f = fh->f;
+
/* Check type of object in heap */
if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) {
/* Skip over the flag byte */
@@ -494,6 +486,9 @@ H5HF_read(H5HF_t *fh, hid_t dxpl_id, const void *_id, void *obj/*out*/)
if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR)
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "incorrect heap ID version")
+ /* Set the shared heap header's file context for this operation */
+ fh->hdr->f = fh->f;
+
/* Check type of object in heap */
if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) {
/* Read object from managed heap blocks */
@@ -557,6 +552,9 @@ H5HF_op(H5HF_t *fh, hid_t dxpl_id, const void *_id, H5HF_operator_t op,
if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR)
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "incorrect heap ID version")
+ /* Set the shared heap header's file context for this operation */
+ fh->hdr->f = fh->f;
+
/* Check type of object in heap */
if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) {
/* Operate on object from managed heap blocks */
@@ -619,6 +617,9 @@ H5HF_remove(H5HF_t *fh, hid_t dxpl_id, const void *_id)
if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR)
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "incorrect heap ID version")
+ /* Set the shared heap header's file context for this operation */
+ fh->hdr->f = fh->f;
+
/* Check type of object in heap */
if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) {
/* Remove object from managed heap blocks */
@@ -670,14 +671,10 @@ H5HF_close(H5HF_t *fh, hid_t dxpl_id)
*/
HDassert(fh);
- /* Decrement shared object count */
- --fh->fo_count;
-
- /* Check if this is the last reference to the shared heap wrapper */
- if(0 == fh->fo_count) {
- /* Remove the heap from the list of opened objects in the file */
- if(H5FO_delete(fh->hdr->f, H5AC_dxpl_id, fh->hdr->heap_addr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects")
+ /* Decrement file reference & check if this is the last open fractal heap using the shared heap header */
+ if(0 == H5HF_hdr_fuse_decr(fh->hdr)) {
+ /* Set the shared heap header's file context for this operation */
+ fh->hdr->f = fh->f;
/* Close the free space information */
/* (Can't put this in header "destroy" routine, because it has
@@ -713,14 +710,14 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr-
*/
if(H5HF_huge_term(fh->hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release 'huge' object info")
+ } /* end if */
- /* Decrement the reference count on the heap header */
- if(H5HF_hdr_decr(fh->hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
+ /* Decrement the reference count on the heap header */
+ if(H5HF_hdr_decr(fh->hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
- /* Release the fractal heap wrapper */
- H5FL_FREE(H5HF_t, fh);
- } /* end if */
+ /* Release the fractal heap wrapper */
+ H5FL_FREE(H5HF_t, fh);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -754,20 +751,17 @@ H5HF_delete(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
HDassert(f);
HDassert(H5F_addr_defined(fh_addr));
- /* Check if group was already open */
- if(H5FO_opened(f, fh_addr) != NULL)
- HGOTO_ERROR(H5E_HEAP, H5E_OBJOPEN, FAIL, "heap still open")
-
- /* Clear any errors from H5FO_opened() */
- H5E_clear_stack(NULL);
-
- /* Load the heap header into memory */
+ /* Lock the heap header into memory */
#ifdef QAK
HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
#endif /* QAK */
if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
+ /* Check for files using shared heap header */
+ if(hdr->file_rc)
+ HGOTO_ERROR(H5E_HEAP, H5E_OBJOPEN, FAIL, "heap still open")
+
/* Check for free space manager for heap */
/* (must occur before attempting to delete the heap, so indirect blocks
* will get unpinned)
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c
index 5b9022c..adc1859 100644
--- a/src/H5HFhdr.c
+++ b/src/H5HFhdr.c
@@ -512,7 +512,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_hdr_incr
*
- * Purpose: Increment reference count on shared heap header
+ * Purpose: Increment component reference count on shared heap header
*
* Return: Non-negative on success/Negative on failure
*
@@ -548,7 +548,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_hdr_decr
*
- * Purpose: Decrement reference count on shared heap header
+ * Purpose: Decrement component reference count on shared heap header
*
* Return: Non-negative on success/Negative on failure
*
@@ -573,9 +573,11 @@ H5HF_hdr_decr(H5HF_hdr_t *hdr)
hdr->rc--;
/* Mark header as evictable again when no child blocks depend on it */
- if(hdr->rc == 0)
+ if(hdr->rc == 0) {
+ HDassert(hdr->file_rc == 0);
if(H5AC_unpin_entry(hdr->f, hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap header")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -583,6 +585,63 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_fuse_incr
+ *
+ * Purpose: Increment file reference count on shared heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 1 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_hdr_fuse_incr(H5HF_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_fuse_incr)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Increment file reference count on shared header */
+ hdr->file_rc++;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_hdr_fuse_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_fuse_decr
+ *
+ * Purpose: Decrement file reference count on shared heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 1 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5HF_hdr_fuse_decr(H5HF_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_fuse_decr)
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->file_rc);
+
+ /* Decrement file reference count on shared header */
+ hdr->file_rc--;
+
+ FUNC_LEAVE_NOAPI(hdr->file_rc)
+} /* end H5HF_hdr_fuse_decr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_hdr_dirty
*
* Purpose: Mark heap header as dirty
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 75e23d0..0b9c74d 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -342,12 +342,13 @@ typedef struct H5HF_hdr_t {
hsize_t tiny_nobjs; /* Number of 'tiny' objects in heap */
/* Cached/computed values (not stored in header) */
- size_t rc; /* Reference count of objects using heap header */
+ size_t rc; /* Reference count of heap's components using heap header */
hbool_t dirty; /* Shared info is modified */
haddr_t heap_addr; /* Address of heap header in the file */
size_t heap_size; /* Size of heap header in the file */
H5AC_protect_t mode; /* Access mode for heap */
H5F_t *f; /* Pointer to file for heap */
+ size_t file_rc; /* Reference count of files using heap header */
size_t sizeof_size; /* Size of file sizes */
size_t sizeof_addr; /* Size of file addresses */
struct H5HF_indirect_t *root_iblock; /* Pointer to pinned root indirect block */
@@ -419,7 +420,7 @@ typedef struct H5HF_direct_t {
/* Fractal heap */
struct H5HF_t {
H5HF_hdr_t *hdr; /* Pointer to internal fractal heap header info */
- unsigned fo_count; /* Open object count for file */
+ H5F_t *f; /* Pointer to file for heap */
};
/* Fractal heap "parent info" (for loading a block) */
@@ -554,6 +555,8 @@ H5_DLL herr_t H5HF_hdr_finish_init_phase2(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_finish_init(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_incr(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_decr(H5HF_hdr_t *hdr);
+H5_DLL herr_t H5HF_hdr_fuse_incr(H5HF_hdr_t *hdr);
+H5_DLL size_t H5HF_hdr_fuse_decr(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_dirty(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_adj_free(H5HF_hdr_t *hdr, ssize_t amt);
H5_DLL herr_t H5HF_hdr_adjust_heap(H5HF_hdr_t *hdr, hsize_t new_size, hssize_t extra_free);