diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2004-07-09 02:06:29 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2004-07-09 02:06:29 (GMT) |
commit | fe76fb1b580aa99fa26ccb26da88ce7e16b35a84 (patch) | |
tree | b90b9832ec612a2d7efead8c6bea6c767edc5b15 /src/H5Gnode.c | |
parent | d5c705a642a1ed06fa8dcaa25b61aa75687799d2 (diff) | |
download | hdf5-fe76fb1b580aa99fa26ccb26da88ce7e16b35a84.zip hdf5-fe76fb1b580aa99fa26ccb26da88ce7e16b35a84.tar.gz hdf5-fe76fb1b580aa99fa26ccb26da88ce7e16b35a84.tar.bz2 |
[svn-r8844] Purpose:
Bug fix
Description:
The "shared" raw B-tree node can get freed before all the B-tree nodes
had been flushed out to disk and released by the cache.
Solution:
Implement a simple reference counting wrapper for objects in the library
and use it to hold the shared raw B-tree nodes so they aren't freed before all
references to them in memory are released.
Platforms tested:
Solaris 2.7 (arabica)
FreeBSD 4.10 (sleipnir)
IRIX64 6.5 (modei4)
Diffstat (limited to 'src/H5Gnode.c')
-rw-r--r-- | src/H5Gnode.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 1925ee5..1710270 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -64,6 +64,7 @@ typedef struct H5G_node_key_t { /* PRIVATE PROTOTYPES */ static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf); static size_t H5G_node_size(H5F_t *f); +static herr_t H5G_node_page_free (void *page); /* Metadata cache callbacks */ static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1, @@ -196,7 +197,11 @@ H5G_node_get_page(H5F_t *f, const void UNUSED *_udata) assert(f); - FUNC_LEAVE_NOAPI(H5F_RAW_PAGE(f)); + /* Increment reference count on B-tree node */ + H5RC_INC(H5F_RC_PAGE(f)); + + /* Get the pointer to the ref-count object */ + FUNC_LEAVE_NOAPI(H5F_RC_PAGE(f)); } /* end H5G_node_get_page() */ @@ -1722,8 +1727,9 @@ done: herr_t H5G_node_init(H5F_t *f) { - size_t sizeof_rkey; /* Single raw key size */ - size_t size; /* Raw B-tree node size */ + size_t sizeof_rkey; /* Single raw key size */ + size_t size; /* Raw B-tree node size */ + void *page; /* Buffer for raw B-tree node */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_node_init, FAIL); @@ -1736,9 +1742,13 @@ H5G_node_init(H5F_t *f) assert(sizeof_rkey); size = H5B_nodesize(f, H5B_SNODE, NULL, sizeof_rkey); assert(size); - if(NULL==(f->shared->raw_page=H5FL_BLK_MALLOC(grp_page,size))) + if(NULL==(page=H5FL_BLK_MALLOC(grp_page,size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") + /* Make page buffer reference counted */ + if(NULL==(f->shared->rc_page=H5RC_create(page,H5G_node_page_free))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for page") + done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5G_node_init() */ @@ -1768,13 +1778,39 @@ H5G_node_close(const H5F_t *f) assert(f); /* Free the raw B-tree node buffer */ - H5FL_BLK_FREE(grp_page,f->shared->raw_page); + H5RC_DEC(f->shared->rc_page); FUNC_LEAVE_NOAPI(SUCCEED); } /* end H5G_node_close */ /*------------------------------------------------------------------------- + * Function: H5G_node_page_free + * + * Purpose: Free a B-tree node + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, July 8, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_node_page_free (void *page) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_page_free) + + /* Free the raw B-tree node buffer */ + H5FL_BLK_FREE(grp_page,page); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_node_page_free() */ + + +/*------------------------------------------------------------------------- * Function: H5G_node_debug * * Purpose: Prints debugging information about a symbol table node |