From fe76fb1b580aa99fa26ccb26da88ce7e16b35a84 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 8 Jul 2004 21:06:29 -0500 Subject: [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) --- MANIFEST | 2 + src/H5B.c | 10 ++++- src/H5Bpkg.h | 2 + src/H5Distore.c | 44 +++++++++++++++++-- src/H5F.c | 12 ++--- src/H5Fpkg.h | 3 +- src/H5Fprivate.h | 7 +-- src/H5G.c | 5 +++ src/H5Gnode.c | 46 ++++++++++++++++--- src/H5Oprivate.h | 3 +- src/H5RC.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5RCprivate.h | 62 ++++++++++++++++++++++++++ src/Makefile.in | 8 ++-- test/tid.c | 1 + 14 files changed, 306 insertions(+), 28 deletions(-) create mode 100644 src/H5RC.c create mode 100644 src/H5RCprivate.h diff --git a/MANIFEST b/MANIFEST index d83ae6e..23113e3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -893,6 +893,8 @@ ./src/H5R.c ./src/H5Rprivate.h ./src/H5Rpublic.h +./src/H5RC.c +./src/H5RCprivate.h ./src/H5RS.c ./src/H5RSprivate.h ./src/H5S.c diff --git a/src/H5B.c b/src/H5B.c index 0da67bb..5529aea 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -241,8 +241,9 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, bt->left = HADDR_UNDEF; bt->right = HADDR_UNDEF; bt->nchildren = 0; - if((bt->raw_page=(type->get_page)(f, udata))==NULL) + if((bt->rc_page=(type->get_page)(f, udata))==NULL) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer") + bt->raw_page=H5RC_GET_OBJ(bt->rc_page); if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_native_keysize)) || NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type)))) || NULL==(bt->nkey=H5FL_SEQ_MALLOC(voidp,(size_t)(2*H5F_KVALUE(f,type)+1)))) @@ -340,8 +341,9 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type))))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - if((bt->raw_page=(type->get_page)(f, udata))==NULL) + if((bt->rc_page=(type->get_page)(f, udata))==NULL) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer") + bt->raw_page=H5RC_GET_OBJ(bt->rc_page); if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, bt->raw_page)<0) HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node") @@ -574,6 +576,7 @@ H5B_dest(H5F_t UNUSED *f, H5B_t *bt) H5FL_SEQ_FREE(haddr_t,bt->child); H5FL_SEQ_FREE(voidp,bt->nkey); H5FL_BLK_FREE(native_block,bt->native); + H5RC_DEC(bt->rc_page); H5FL_FREE(H5B_t,bt); FUNC_LEAVE_NOAPI(SUCCEED) @@ -2203,6 +2206,9 @@ H5B_copy(const H5F_t *f, const H5B_t *old_bt) new_node->nkey[u] = NULL; } + /* Increment the ref-count on the raw page */ + H5RC_INC(new_node->rc_page); + /* Set return value */ ret_value=new_node; diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h index 67b49db..67135cf 100644 --- a/src/H5Bpkg.h +++ b/src/H5Bpkg.h @@ -31,6 +31,7 @@ #include "H5Bprivate.h" /* Other private headers needed by this file */ +#include "H5RCprivate.h" /* Reference counted object functions */ /**************************/ /* Package Private Macros */ @@ -54,6 +55,7 @@ struct H5B_t { haddr_t left; /*address of left sibling */ haddr_t right; /*address of right sibling */ unsigned nchildren; /*number of child pointers */ + H5RC_t *rc_page; /*ref-counted disk page */ uint8_t *raw_page; /*disk page (shared) */ uint8_t *native; /*array of keys in native format */ void **nkey; /*2k+1 key entries */ diff --git a/src/H5Distore.c b/src/H5Distore.c index 0bab89d..09c025c 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -146,6 +146,7 @@ static haddr_t H5D_istore_get_addr(H5F_t *f, hid_t dxpl_id, const H5O_layout_t * const hssize_t offset[], H5D_istore_ud1_t *_udata); static void *H5D_istore_chunk_alloc(size_t size, const H5O_pline_t *pline); static void *H5D_istore_chunk_xfree(void *chk, const H5O_pline_t *pline); +static herr_t H5D_istore_page_free (void *page); /* B-tree iterator callbacks */ static int H5D_istore_iter_allocated(H5F_t *f, hid_t dxpl_id, void *left_key, haddr_t addr, @@ -278,9 +279,13 @@ H5D_istore_get_page(H5F_t UNUSED *f, const void *_udata) assert(udata); assert(udata->mesg); - assert(udata->mesg->u.chunk.raw_page); + assert(udata->mesg->u.chunk.rc_page); - FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.raw_page); + /* Increment reference count on B-tree node */ + H5RC_INC(udata->mesg->u.chunk.rc_page); + + /* Get the pointer to the ref-count object */ + FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.rc_page); } /* end H5D_istore_get_page() */ @@ -898,6 +903,7 @@ H5D_istore_init (H5F_t *f, H5D_t *dset) size_t sizeof_rkey; /* Single raw key size */ size_t size; /* Raw B-tree node size */ H5D_rdcc_t *rdcc = &(dset->cache.chunk); + void *page; /* Buffer for raw B-tree node */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_istore_init, FAIL); @@ -919,9 +925,13 @@ H5D_istore_init (H5F_t *f, H5D_t *dset) assert(sizeof_rkey); size = H5B_nodesize(f, H5B_ISTORE, NULL, sizeof_rkey); assert(size); - if(NULL==(dset->layout.u.chunk.raw_page=H5FL_BLK_MALLOC(chunk_page,size))) + if(NULL==(page=H5FL_BLK_MALLOC(chunk_page,size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") + /* Make page buffer reference counted */ + if(NULL==(dset->layout.u.chunk.rc_page=H5RC_create(page,H5D_istore_page_free))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for page") + done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5D_istore_init() */ @@ -1217,7 +1227,8 @@ H5D_istore_dest (H5F_t *f, hid_t dxpl_id, H5D_t *dset) HDmemset (rdcc, 0, sizeof(H5D_rdcc_t)); /* Free the raw B-tree node buffer */ - H5FL_BLK_FREE(chunk_page,dset->layout.u.chunk.raw_page); + if(H5RC_DEC(dset->layout.u.chunk.rc_page)<0) + HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -1225,6 +1236,31 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_istore_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 +H5D_istore_page_free (void *page) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_page_free) + + H5FL_BLK_FREE(chunk_page,page); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D_istore_page_free() */ + + +/*------------------------------------------------------------------------- * Function: H5D_istore_prune * * Purpose: Prune the cache by preempting some things until the cache has diff --git a/src/H5F.c b/src/H5F.c index 86f9019..de16b40 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1490,10 +1490,6 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id) /* Create the file's "open object" information */ if(H5FO_create(f)<0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object TBBT") - - /* Create information needed for group nodes */ - if(H5G_node_init(f)<0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create group node info") } /* end else */ f->shared->nrefs++; @@ -4472,7 +4468,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_raw_page + * Function: H5F_rc_page * * Purpose: Replaced a macro to retrieve the raw B-tree page value * now that the generic properties are being used to store @@ -4491,15 +4487,15 @@ done: * *------------------------------------------------------------------------- */ -void *H5F_raw_page(const H5F_t *f) +H5RC_t *H5F_rc_page(const H5F_t *f) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_raw_page) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rc_page) assert(f); assert(f->shared); - FUNC_LEAVE_NOAPI(f->shared->raw_page) + FUNC_LEAVE_NOAPI(f->shared->rc_page) } /* end H5F_raw_page() */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 567ea39..318a8f1 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -37,6 +37,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5FOprivate.h" /* File objects */ #include "H5Gprivate.h" /* Groups */ +#include "H5RCprivate.h" /* Reference counted object functions */ /* * Feature: Define this constant to be non-zero if you want to enable code @@ -126,7 +127,7 @@ typedef struct H5F_file_t { struct H5HG_heap_t **cwfs; /* Global heap cache */ H5FO_t *open_objs; /* Open objects in file */ H5F_close_degree_t fc_degree; /* File close behavior degree */ - void *raw_page; /* Pointer to raw B-tree node buffer */ + H5RC_t *rc_page; /* Pointer to ref-counted raw B-tree node buffer */ } H5F_file_t; /* A record of the mount table */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index aace023..452b160 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -211,7 +211,7 @@ typedef struct H5F_t H5F_t; /* Check for file driver feature enabled */ #define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags&(FL)) /* B-tree node raw page */ -#define H5F_RAW_PAGE(F) ((F)->shared->raw_page) +#define H5F_RC_PAGE(F) ((F)->shared->rc_page) #else /* H5F_PACKAGE */ #define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F)) #define H5F_SIZEOF_SIZE(F) (H5F_sizeof_size(F)) @@ -221,7 +221,7 @@ typedef struct H5F_t H5F_t; #define H5F_RDCC_NBYTES(F) (H5F_rdcc_nbytes(F)) #define H5F_RDCC_W0(F) (H5F_rdcc_w0(F)) #define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL)) -#define H5F_RAW_PAGE(F) (H5F_raw_page(F)) +#define H5F_RC_PAGE(F) (H5F_rc_page(F)) #endif /* H5F_PACKAGE */ @@ -387,6 +387,7 @@ typedef struct H5F_t H5F_t; /* Forward declarations for prototype arguments */ struct H5B_class_t; +struct H5RC_t; /* Private functions, not part of the publicly documented API */ H5_DLL herr_t H5F_init(void); @@ -417,7 +418,7 @@ H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature); H5_DLL size_t H5F_rdcc_nbytes(const H5F_t *f); H5_DLL size_t H5F_rdcc_nelmts(const H5F_t *f); H5_DLL double H5F_rdcc_w0(const H5F_t *f); -H5_DLL void *H5F_raw_page(const H5F_t *f); +H5_DLL struct H5RC_t *H5F_rc_page(const H5F_t *f); /* Functions that operate on blocks of bytes wrt super block */ H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, diff --git a/src/H5G.c b/src/H5G.c index ee3d5a4..27f43e8 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -1524,6 +1524,7 @@ done: /* If we started with a NULL grp_ent and we copied something into it, free the entry information */ if(null_grp && group_copy) H5G_free_ent_name(grp_ent); + FUNC_LEAVE_NOAPI(ret_value); } @@ -1661,6 +1662,10 @@ H5G_mkroot (H5F_t *f, hid_t dxpl_id, H5G_entry_t *ent) if (f->shared->root_grp) HGOTO_DONE(SUCCEED); + /* Create information needed for group nodes */ + if(H5G_node_init(f)<0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info") + /* * If there is no root object then create one. The root group always has * a hard link count of one since it's pointed to by the boot block. 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 diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index b7d9b46..26bf5d8 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -37,6 +37,7 @@ /* Private headers needed by this file */ #include "H5private.h" /* Generic functions */ #include "H5HGprivate.h" /* Global heap functions */ +#include "H5RCprivate.h" /* Reference counted object functions */ #include "H5Tprivate.h" /* Datatype functions */ #include "H5Zprivate.h" /* I/O pipeline filters */ @@ -133,7 +134,7 @@ typedef struct H5O_layout_chunk_t { unsigned ndims; /* Num dimensions in chunk */ size_t dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in elements */ size_t size; /* Size of chunk in bytes */ - void *raw_page; /* Buffer for raw B-tree page */ + H5RC_t *rc_page; /* Ref-counted buffer for raw B-tree page */ } H5O_layout_chunk_t; typedef struct H5O_layout_compact_t { diff --git a/src/H5RC.c b/src/H5RC.c new file mode 100644 index 0000000..8ab1818 --- /dev/null +++ b/src/H5RC.c @@ -0,0 +1,129 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Reference counting buffer algorithms. + * + * These are used for various internal buffers which are shared. + * + */ + +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5RC_mask + +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5RCprivate.h" /* Reference-counted buffers */ + +/* Private typedefs & structs */ + +/* Declare a free list to manage the H5RC_t struct */ +H5FL_DEFINE_STATIC(H5RC_t); + + +/*-------------------------------------------------------------------------- + NAME + H5RC_create + PURPOSE + Create a reference counted object + USAGE + H5RC_t *H5RC_create(o,free) + const void *o; IN: Object to initialize ref-counted object with + H5RC_free_func_t free; IN: Function to call when ref-count drop to zero + + RETURNS + Returns a pointer to a new ref-counted object on success, NULL on failure. + DESCRIPTION + Create a reference counted object. The object is not duplicated, it is + assumed to be owned by the reference counted object now and will be freed + with the 'free' function when the reference count drops to zero. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5RC_t * +H5RC_create(void *o, H5RC_free_func_t free_func) +{ + H5RC_t *ret_value=NULL; /* Return value */ + + FUNC_ENTER_NOAPI(H5RC_create,NULL); + + /* Sanity check */ + HDassert(o); + HDassert(free_func); + + /* Allocate ref-counted string structure */ + if((ret_value=H5FL_MALLOC(H5RC_t))==NULL) + HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed"); + + /* Set the internal fields */ + ret_value->o=o; + ret_value->n=1; + ret_value->free_func=free_func; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5RC_create() */ + + +/*-------------------------------------------------------------------------- + NAME + H5RC_decr + PURPOSE + Decrement the reference count for a ref-counted object + USAGE + herr_t H5RC_decr(rc) + H5RC_t *rc; IN: Ref-counted object to decrement count for + + RETURNS + SUCCEED/FAIL + DESCRIPTION + Decrements the reference count for a ref-counted object, calling the + object's free function if ref-count drops to zero. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5RC_decr(H5RC_t *rc) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5RC_decr,FAIL); + + /* Sanity check */ + HDassert(rc); + HDassert(rc->o); + HDassert(rc->n>0); + HDassert(rc->free_func); + + /* Decrement reference count */ + rc->n--; + + /* Check if we should delete this object now */ + if(rc->n==0) { + if((rc->free_func)(rc->o)<0) { + H5FL_FREE(H5RC_t,rc); + HGOTO_ERROR(H5E_RS,H5E_CANTFREE,FAIL,"memory release failed"); + } /* end if */ + H5FL_FREE(H5RC_t,rc); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5RC_decr() */ + diff --git a/src/H5RCprivate.h b/src/H5RCprivate.h new file mode 100644 index 0000000..7f1dc3a --- /dev/null +++ b/src/H5RCprivate.h @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains private information about the H5RC module + */ +#ifndef _H5RCprivate_H +#define _H5RCprivate_H + +/**************************************/ +/* Public headers needed by this file */ +/**************************************/ +#ifdef LATER +#include "H5RCpublic.h" +#endif /* LATER */ + +/***************************************/ +/* Private headers needed by this file */ +/***************************************/ +#include "H5private.h" + +/************/ +/* Typedefs */ +/************/ + +/* Typedef for function to release object when reference count drops to zero */ +typedef herr_t (*H5RC_free_func_t)(void *o); + +/* Typedef for reference counted objects */ +typedef struct H5RC_t { + void *o; /* Object to be reference counted */ + size_t n; /* Reference count of number of pointers sharing object */ + H5RC_free_func_t free_func; /* Function to free object */ +} H5RC_t; + +/**********/ +/* Macros */ +/**********/ +#define H5RC_INC(rc) ((rc)->n++) +#define H5RC_DEC(rc) (H5RC_decr(rc)) +#define H5RC_GET_OBJ(rc) ((rc)->o) + +/********************/ +/* Private routines */ +/********************/ +H5_DLL H5RC_t *H5RC_create(void *s, H5RC_free_func_t free_func); +H5_DLL herr_t H5RC_decr(H5RC_t *rc); + +#endif /* _H5RSprivate_H */ + + diff --git a/src/Makefile.in b/src/Makefile.in index dc59c33..4c05597 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -40,7 +40,7 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dcontig.c H5Dcompact.c H5Dio.c \ H5Obogus.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c \ H5Omtime.c H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c \ H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Ptest.c \ - H5R.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c \ + H5R.c H5RC.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c \ H5Spoint.c H5Sselect.c H5Stest.c H5ST.c H5T.c H5Tarray.c H5Tbit.c \ H5Tcommit.c H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c \ H5Tfixed.c H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c \ @@ -70,9 +70,9 @@ PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ H5FSprivate.h H5Gprivate.h H5Gpkg.h H5HGprivate.h H5HGpkg.h \ H5HLprivate.h H5HLpkg.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \ H5MMprivate.h H5Oprivate.h H5Opkg.h H5Pprivate.h H5Ppkg.h \ - H5Rprivate.h H5RSprivate.h H5Sprivate.h H5STprivate.h H5Tprivate.h \ - H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h H5Zprivate.h \ - H5Zpkg.h H5config.h + H5Rprivate.h H5RCprivate.h H5RSprivate.h H5Sprivate.h H5STprivate.h \ + H5Tprivate.h H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h \ + H5Zprivate.h H5Zpkg.h H5config.h ## Error header generation ## diff --git a/test/tid.c b/test/tid.c index d84f7b4..15438e8 100644 --- a/test/tid.c +++ b/test/tid.c @@ -263,6 +263,7 @@ int id_predefined_test() H5Tclose(typeID); + free(testObj); return 0; out: -- cgit v0.12