summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-11-16 04:17:45 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-11-16 04:17:45 (GMT)
commit4fe33eda1c243a0e6410e57c151b93e1950cf192 (patch)
tree857b21defd5b7804fd8edd0e3429a57213b849cc /src
parent6d5d4ed1d10498bf776b5a4d41cf2384b4d8fe28 (diff)
downloadhdf5-4fe33eda1c243a0e6410e57c151b93e1950cf192.zip
hdf5-4fe33eda1c243a0e6410e57c151b93e1950cf192.tar.gz
hdf5-4fe33eda1c243a0e6410e57c151b93e1950cf192.tar.bz2
[svn-r17895] Description:
Correct & simplify client callback context for extensible and fixed array data structures. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.6.2 (amazon) in debug mode Mac OS X/32 10.6.2 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'src')
-rw-r--r--src/H5.c4
-rw-r--r--src/H5EA.c66
-rw-r--r--src/H5EAcache.c14
-rw-r--r--src/H5EAhdr.c28
-rw-r--r--src/H5EApkg.h8
-rw-r--r--src/H5EAprivate.h6
-rw-r--r--src/H5FA.c64
-rw-r--r--src/H5FAcache.c21
-rw-r--r--src/H5FAhdr.c64
-rw-r--r--src/H5FApkg.h6
-rw-r--r--src/H5FAprivate.h11
11 files changed, 201 insertions, 91 deletions
diff --git a/src/H5.c b/src/H5.c
index f4125e3..6bd96cb 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -61,6 +61,10 @@ static void H5_debug_mask(const char*);
/* Library Private Variables */
/*****************************/
+/* HDF5 API Entered variable */
+/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */
+hbool_t H5_api_entered_g = FALSE;
+
/* statically initialize block for pthread_once call used in initializing */
/* the first global mutex */
#ifdef H5_HAVE_THREADSAFE
diff --git a/src/H5EA.c b/src/H5EA.c
index ea21b15..169c93f 100644
--- a/src/H5EA.c
+++ b/src/H5EA.c
@@ -79,9 +79,16 @@ typedef herr_t (*H5EA__unprotect_func_t)(void *thing, hid_t dxpl_id,
/* Package Variables */
/*********************/
-/* HDF5 API Entered variable */
-/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */
-hbool_t H5_api_entered_g = FALSE;
+/* Extensible array client ID to class mapping */
+
+/* Remember to add client ID to H5EA_cls_id_t in H5EAprivate.h when adding a new
+ * client class..
+ */
+extern const H5EA_class_t H5EA_CLS_TEST[1];
+
+const H5EA_class_t *const H5EA_client_class_g[] = {
+ H5EA_CLS_TEST, /* 0 - H5EA_TEST_ID */
+};
/*****************************/
@@ -131,6 +138,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
HDassert(f);
HDassert(cparam);
+ /* H5EA interface sanity check */
+ HDcompile_assert(H5EA_NUM_CLS_ID == NELMTS(H5EA_client_class_g));
+
/* Create extensible array header */
if(HADDR_UNDEF == (ea_addr = H5EA__hdr_create(f, dxpl_id, cparam, ctx_udata)))
H5E_THROW(H5E_CANTINIT, "can't create extensible array header")
@@ -140,7 +150,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info")
/* Lock the array header into memory */
- if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cparam->cls, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_WRITE)))
H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
/* Point extensible array wrapper at header and bump it's ref count */
@@ -185,8 +195,7 @@ END_FUNC(PRIV) /* end H5EA_create() */
*/
BEGIN_FUNC(PRIV, ERR,
H5EA_t *, NULL, NULL,
-H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls,
- void *ctx_udata))
+H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata))
/* Local variables */
H5EA_t *ea = NULL; /* Pointer to new extensible array wrapper */
@@ -197,13 +206,12 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls,
*/
HDassert(f);
HDassert(H5F_addr_defined(ea_addr));
- HDassert(cls);
/* Load the array header into memory */
#ifdef QAK
HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr);
#endif /* QAK */
- if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cls, ctx_udata, H5AC_READ)))
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_READ)))
H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long long)ea_addr)
/* Check for pending array deletion */
@@ -1031,28 +1039,52 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
} /* end if */
} /* end if */
- /* Decrement the reference count on the array header */
- /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted
- * immediately -QAK)
- */
- if(H5EA__hdr_decr(ea->hdr) < 0)
- H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
-
/* Check for pending array deletion */
if(pending_delete) {
H5EA_hdr_t *hdr; /* Another pointer to extensible array header */
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Header's status in the metadata cache */
+
+ /* Check the header's status in the metadata cache */
+ if(H5AC_get_entry_status(ea->f, ea_addr, &hdr_status) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for extensible array header")
+
+ /* Sanity checks on header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PINNED);
+ HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED));
+}
+#endif /* NDEBUG */
+
/* Lock the array header into memory */
+ /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */
if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(ea->f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE)))
H5E_THROW(H5E_CANTLOAD, "unable to load extensible array header")
/* Set the shared array header's file context for this operation */
hdr->f = ea->f;
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5EA__hdr_decr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+
/* Delete array, starting with header (unprotects header) */
if(H5EA__hdr_delete(hdr, dxpl_id) < 0)
H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array")
} /* end if */
+ else {
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5EA__hdr_decr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+ } /* end else */
/* Release the extensible array wrapper */
ea = (H5EA_t *)H5FL_FREE(H5EA_t, ea);
@@ -1077,7 +1109,7 @@ END_FUNC(PRIV) /* end H5EA_close() */
*/
BEGIN_FUNC(PRIV, ERR,
herr_t, SUCCEED, FAIL,
-H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr))
+H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata))
/* Local variables */
H5EA_hdr_t *hdr = NULL; /* The fractal heap header information */
@@ -1092,7 +1124,7 @@ H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr))
#ifdef QAK
HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr);
#endif /* QAK */
- if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_WRITE)))
H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array header, address = %llu", (unsigned long long)ea_addr)
/* Check for files using shared array header */
diff --git a/src/H5EAcache.c b/src/H5EAcache.c
index 00d3089..5138ae4 100644
--- a/src/H5EAcache.c
+++ b/src/H5EAcache.c
@@ -198,11 +198,11 @@ const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1] = {{
*/
BEGIN_FUNC(STATIC, ERR,
H5EA_hdr_t *, NULL, NULL,
-H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
+H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
void *ctx_udata))
/* Local variables */
- const H5EA_class_t *cls = (const H5EA_class_t *)_cls; /* Extensible array class */
+ H5EA_cls_id_t id; /* ID of extensible array class, as found in file */
H5EA_hdr_t *hdr = NULL; /* Extensible array info */
size_t size; /* Header size */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
@@ -217,7 +217,7 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
HDassert(H5F_addr_defined(addr));
/* Allocate space for the extensible array data structure */
- if(NULL == (hdr = H5EA__hdr_alloc(f, cls, ctx_udata)))
+ if(NULL == (hdr = H5EA__hdr_alloc(f)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header")
/* Set the extensible array header's address */
@@ -250,9 +250,11 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
if(*p++ != H5EA_HDR_VERSION)
H5E_THROW(H5E_VERSION, "wrong extensible array header version")
- /* Extensible array type */
- if(*p++ != (uint8_t)cls->id)
+ /* Extensible array class */
+ id = *p++;
+ if(id >= H5EA_NUM_CLS_ID)
H5E_THROW(H5E_BADTYPE, "incorrect extensible array class")
+ hdr->cparam.cls = H5EA_client_class_g[id];
/* General array creation/configuration information */
hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */
@@ -314,7 +316,7 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array header")
/* Finish initializing extensible array header */
- if(H5EA__hdr_init(hdr) < 0)
+ if(H5EA__hdr_init(hdr, ctx_udata) < 0)
H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header")
HDassert(hdr->size == size);
diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c
index f821476..b8d3334 100644
--- a/src/H5EAhdr.c
+++ b/src/H5EAhdr.c
@@ -118,14 +118,13 @@ H5FL_SEQ_DEFINE_STATIC(H5EA_sblk_info_t);
*/
BEGIN_FUNC(PKG, ERR,
H5EA_hdr_t *, NULL, NULL,
-H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, void *udata))
+H5EA__hdr_alloc(H5F_t *f))
/* Local variables */
H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
/* Check arguments */
HDassert(f);
- HDassert(cls);
/* Allocate space for the shared information */
if(NULL == (hdr = H5FL_CALLOC(H5EA_hdr_t)))
@@ -139,13 +138,6 @@ H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, void *udata))
hdr->sizeof_addr = H5F_SIZEOF_ADDR(f);
hdr->sizeof_size = H5F_SIZEOF_SIZE(f);
- /* Set the class of the array */
- hdr->cparam.cls = cls;
-
- /* Create the callback context */
- if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata)))
- H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context")
-
/* Set the return value */
ret_value = hdr;
@@ -195,7 +187,7 @@ END_FUNC(PKG) /* end H5EA__hdr_alloc() */
*/
BEGIN_FUNC(PKG, ERR,
herr_t, SUCCEED, FAIL,
-H5EA__hdr_init(H5EA_hdr_t *hdr))
+H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata))
/* Local variables */
hsize_t start_idx; /* First element index for each super block */
@@ -240,6 +232,12 @@ HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Zu, %Zu, %Hu, %Hu}\n", FUNC, u, h
/* Set size of header on disk (locally and in statistics) */
hdr->stats.computed.hdr_size = hdr->size = H5EA_HEADER_SIZE(hdr);
+ /* Create the callback context, if there's one */
+ if(hdr->cparam.cls->crt_context) {
+ if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata)))
+ H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context")
+ } /* end if */
+
CATCH
END_FUNC(PKG) /* end H5EA__hdr_init() */
@@ -419,7 +417,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* NDEBUG */
/* Allocate space for the shared information */
- if(NULL == (hdr = H5EA__hdr_alloc(f, cparam->cls, ctx_udata)))
+ if(NULL == (hdr = H5EA__hdr_alloc(f)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header")
/* Set the internal parameters for the array */
@@ -429,7 +427,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam));
/* Finish initializing extensible array header */
- if(H5EA__hdr_init(hdr) < 0)
+ if(H5EA__hdr_init(hdr, ctx_udata) < 0)
H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header")
/* Allocate space for the header on disk */
@@ -694,8 +692,10 @@ H5EA__hdr_dest(H5EA_hdr_t *hdr))
HDassert(hdr->rc == 0);
/* Destroy the callback context */
- if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0)
- H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context")
+ if(hdr->cb_ctx) {
+ if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context")
+ } /* end if */
hdr->cb_ctx = NULL;
/* Check for data block element buffer factory info to free */
diff --git a/src/H5EApkg.h b/src/H5EApkg.h
index 01090ea..6e86a34 100644
--- a/src/H5EApkg.h
+++ b/src/H5EApkg.h
@@ -353,6 +353,9 @@ H5_DLLVAR const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1];
H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1];
#endif /* H5EA_TESTING */
+/* Array of extensible array client ID -> client class mappings */
+extern const H5EA_class_t *const H5EA_client_class_g[];
+
/******************************/
/* Package Private Prototypes */
@@ -365,9 +368,8 @@ H5_DLL herr_t H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_en
H5AC_info_t *child_entry);
/* Header routines */
-H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls,
- void *ctx_udata);
-H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr);
+H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f);
+H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata);
H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam,
void *ctx_udata);
H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts);
diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h
index a132006..db61dee 100644
--- a/src/H5EAprivate.h
+++ b/src/H5EAprivate.h
@@ -50,6 +50,7 @@
/* Extensible array class IDs */
typedef enum H5EA_cls_id_t {
/* Start real class IDs at 0 -QAK */
+ /* (keep these last) */
H5EA_CLS_TEST_ID, /* Extensible array is for testing (do not use for actual data) */
H5EA_NUM_CLS_ID /* Number of Extensible Array class IDs (must be last) */
} H5EA_cls_id_t;
@@ -121,8 +122,7 @@ typedef struct H5EA_t H5EA_t;
/* General routines */
H5_DLL H5EA_t *H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam,
void *ctx_udata);
-H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr,
- const H5EA_class_t *cls, void *ctx_udata);
+H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
H5_DLL herr_t H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts);
H5_DLL herr_t H5EA_get_addr(const H5EA_t *ea, haddr_t *addr);
H5_DLL herr_t H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt);
@@ -134,7 +134,7 @@ H5_DLL herr_t H5EA_support(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx,
H5_DLL herr_t H5EA_unsupport(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx,
H5AC_info_t *child_entry);
H5_DLL herr_t H5EA_close(H5EA_t *ea, hid_t dxpl_id);
-H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr);
+H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
/* Statistics routines */
H5_DLL herr_t H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats);
diff --git a/src/H5FA.c b/src/H5FA.c
index 7d6a136..20a63af 100644
--- a/src/H5FA.c
+++ b/src/H5FA.c
@@ -70,6 +70,17 @@
/* Package Variables */
/*********************/
+/* Fixed array client ID to class mapping */
+
+/* Remember to add client ID to H5FA_cls_id_t in H5FAprivate.h when adding a new
+ * client class..
+ */
+extern const H5FA_class_t H5FA_CLS_TEST[1];
+
+const H5FA_class_t *const H5FA_client_class_g[] = {
+ H5FA_CLS_TEST, /* 0 - H5FA_TEST_ID */
+};
+
/*****************************/
/* Library Private Variables */
@@ -120,6 +131,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
HDassert(f);
HDassert(cparam);
+ /* H5FA interface sanity check */
+ HDcompile_assert(H5FA_NUM_CLS_ID == NELMTS(H5FA_client_class_g));
+
/* Create fixed array header */
if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata)))
H5E_THROW(H5E_CANTINIT, "can't create fixed array header")
@@ -129,7 +143,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info")
/* Lock the array header into memory */
- if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cparam->cls, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE)))
H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header")
/* Point fixed array wrapper at header and bump it's ref count */
@@ -173,8 +187,7 @@ END_FUNC(PRIV) /* end H5FA_create() */
*/
BEGIN_FUNC(PRIV, ERR,
H5FA_t *, NULL, NULL,
-H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls,
- void *ctx_udata))
+H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata))
/* Local variables */
H5FA_t *fa = NULL; /* Pointer to new fixed array wrapper */
@@ -185,13 +198,12 @@ H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls,
*/
HDassert(f);
HDassert(H5F_addr_defined(fa_addr));
- HDassert(cls);
/* Load the array header into memory */
#ifdef H5FA_DEBUG
HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr);
#endif /* H5FA_DEBUG */
- if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cls, ctx_udata, H5AC_READ)))
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_READ)))
H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header, address = %llu", (unsigned long long)fa_addr)
/* Check for pending array deletion */
@@ -561,28 +573,52 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
} /* end if */
} /* end if */
- /* Decrement the reference count on the array header */
- /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted
- * immediately -QAK)
- */
- if(H5FA__hdr_decr(fa->hdr) < 0)
- H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
-
/* Check for pending array deletion */
if(pending_delete) {
H5FA_hdr_t *hdr; /* Another pointer to fixed array header */
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Header's status in the metadata cache */
+
+ /* Check the header's status in the metadata cache */
+ if(H5AC_get_entry_status(fa->f, fa_addr, &hdr_status) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for fixed array header")
+
+ /* Sanity checks on header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PINNED);
+ HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED));
+}
+#endif /* NDEBUG */
+
/* Lock the array header into memory */
+ /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */
if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(fa->f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE)))
H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header")
/* Set the shared array header's file context for this operation */
hdr->f = fa->f;
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5FA__hdr_decr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+
/* Delete array, starting with header (unprotects header) */
if(H5FA__hdr_delete(hdr, dxpl_id) < 0)
H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array")
} /* end if */
+ else {
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5FA__hdr_decr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+ } /* end else */
/* Release the fixed array wrapper */
fa = H5FL_FREE(H5FA_t, fa);
@@ -606,7 +642,7 @@ END_FUNC(PRIV) /* end H5FA_close() */
*/
BEGIN_FUNC(PRIV, ERR,
herr_t, SUCCEED, FAIL,
-H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr))
+H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata))
/* Local variables */
H5FA_hdr_t *hdr = NULL; /* The fixed array header information */
@@ -621,7 +657,7 @@ H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr))
#ifdef H5FA_DEBUG
HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr);
#endif /* H5FA_DEBUG */
- if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE)))
H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array header, address = %llu", (unsigned long long)fa_addr)
/* Check for files using shared array header */
diff --git a/src/H5FAcache.c b/src/H5FAcache.c
index 59a81e2..3488531 100644
--- a/src/H5FAcache.c
+++ b/src/H5FAcache.c
@@ -158,11 +158,11 @@ const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1] = {{
*/
BEGIN_FUNC(STATIC, ERR,
H5FA_hdr_t *, NULL, NULL,
-H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
+H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
void *ctx_udata))
/* Local variables */
- const H5FA_class_t *cls = (const H5FA_class_t *)_cls; /* Fixed array class */
+ H5FA_cls_id_t id; /* ID of fixed array class, as found in file */
H5FA_hdr_t *hdr = NULL; /* Fixed array info */
size_t size; /* Header size */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
@@ -177,7 +177,7 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
HDassert(H5F_addr_defined(addr));
/* Allocate space for the fixed array data structure */
- if(NULL == (hdr = H5FA__hdr_alloc(f, cls, ctx_udata)))
+ if(NULL == (hdr = H5FA__hdr_alloc(f)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array shared header")
/* Set the fixed array header's address */
@@ -210,9 +210,11 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
if(*p++ != H5FA_HDR_VERSION)
H5E_THROW(H5E_VERSION, "wrong fixed array header version")
- /* Fixed array type */
- if(*p++ != (uint8_t)cls->id)
+ /* Fixed array class */
+ id = *p++;
+ if(id >= H5FA_NUM_CLS_ID)
H5E_THROW(H5E_BADTYPE, "incorrect fixed array class")
+ hdr->cparam.cls = H5FA_client_class_g[id];
/* General array creation/configuration information */
hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */
@@ -226,10 +228,6 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
/* Internal information */
H5F_addr_decode(f, &p, &hdr->dblk_addr); /* Address of index block */
- /* Initializations of header info */
- hdr->stats.nelmts = hdr->cparam.nelmts;
- hdr->stats.hdr_size = hdr->size = size; /* Size of header in file */
-
/* Check for data block */
if(H5F_addr_defined(hdr->dblk_addr)) {
H5FA_dblock_t dblock; /* Fake data block for computing size */
@@ -267,6 +265,11 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header")
+ /* Finish initializing fixed array header */
+ if(H5FA__hdr_init(hdr, ctx_udata) < 0)
+ H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header")
+ HDassert(hdr->size == size);
+
/* Set return value */
ret_value = hdr;
diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c
index e6231d4..94fb7b2 100644
--- a/src/H5FAhdr.c
+++ b/src/H5FAhdr.c
@@ -95,14 +95,13 @@ H5FL_DEFINE_STATIC(H5FA_hdr_t);
*/
BEGIN_FUNC(PKG, ERR,
H5FA_hdr_t *, NULL, NULL,
-H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata))
+H5FA__hdr_alloc(H5F_t *f))
/* Local variables */
H5FA_hdr_t *hdr = NULL; /* Shared Fixed Array header */
/* Check arguments */
HDassert(f);
- HDassert(cls);
/* Allocate space for the shared information */
if(NULL == (hdr = H5FL_CALLOC(H5FA_hdr_t)))
@@ -116,13 +115,6 @@ H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata))
hdr->sizeof_addr = H5F_SIZEOF_ADDR(f);
hdr->sizeof_size = H5F_SIZEOF_SIZE(f);
- /* Set the class of the array */
- hdr->cparam.cls = cls;
-
- /* Create the callback context */
- if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata)))
- H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context")
-
/* Set the return value */
ret_value = hdr;
@@ -135,6 +127,44 @@ END_FUNC(PKG) /* end H5FA__hdr_alloc() */
/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_init
+ *
+ * Purpose: Initialize shared fixed array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, November 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata))
+
+ /* Local variables */
+
+ /* Check arguments */
+ HDassert(hdr);
+
+ /* Set size of header on disk (locally and in statistics) */
+ hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr);
+
+ /* Set number of elements for Fixed Array in statistics */
+ hdr->stats.nelmts = hdr->cparam.nelmts;
+
+ /* Create the callback context, if there's one */
+ if(hdr->cparam.cls->crt_context) {
+ if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata)))
+ H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context")
+ } /* end if */
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__hdr_init() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FA__hdr_create
*
* Purpose: Creates a new Fixed Array header in the file
@@ -175,7 +205,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* NDEBUG */
/* Allocate space for the shared information */
- if(NULL == (hdr = H5FA__hdr_alloc(f, cparam->cls, ctx_udata)))
+ if(NULL == (hdr = H5FA__hdr_alloc(f)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header")
hdr->dblk_addr = HADDR_UNDEF;
@@ -183,11 +213,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
/* Set the creation parameters for the array */
HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam));
- /* Set size of header on disk (locally and in statistics) */
- hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr);
-
- /* Set number of elements for Fixed Array in statistics */
- hdr->stats.nelmts = hdr->cparam.nelmts;
+ /* Finish initializing fixed array header */
+ if(H5FA__hdr_init(hdr, ctx_udata) < 0)
+ H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header")
/* Allocate space for the header on disk */
if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_FARRAY_HDR, dxpl_id, (hsize_t)hdr->size)))
@@ -445,8 +473,10 @@ H5FA__hdr_dest(H5FA_hdr_t *hdr))
HDassert(hdr->rc == 0);
/* Destroy the callback context */
- if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0)
- H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context")
+ if(hdr->cb_ctx) {
+ if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context")
+ } /* end if */
hdr->cb_ctx = NULL;
/* Free the shared info itself */
diff --git a/src/H5FApkg.h b/src/H5FApkg.h
index 1ba8f84..c817b1a 100644
--- a/src/H5FApkg.h
+++ b/src/H5FApkg.h
@@ -228,13 +228,17 @@ H5_DLLVAR const H5FA_class_t H5FA_CLS_FILT_CHUNK[1];
H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1];
#endif /* H5FA_TESTING */
+/* Array of fixed array client ID -> client class mappings */
+extern const H5FA_class_t *const H5FA_client_class_g[];
+
/******************************/
/* Package Private Prototypes */
/******************************/
/* Header routines */
-H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *ctx_udata);
+H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f);
+H5_DLL herr_t H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata);
H5_DLL haddr_t H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata);
H5_DLL void *H5FA__hdr_alloc_elmts(H5FA_hdr_t *hdr, size_t nelmts);
H5_DLL herr_t H5FA__hdr_free_elmts(H5FA_hdr_t *hdr, size_t nelmts, void *elmts);
diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h
index 16397fd..1a5a6a0 100644
--- a/src/H5FAprivate.h
+++ b/src/H5FAprivate.h
@@ -46,9 +46,7 @@
/* Fixed Array class IDs */
typedef enum H5FA_cls_id_t {
- H5FA_CLS_CHUNK_ID = 0, /* Fixed array is for indexing dataset chunks w/o filters */
- H5FA_CLS_FILT_CHUNK_ID, /* Fixed array is for indexing dataset chunks w/filters */
-
+ /* Start real class IDs at 0 -QAK */
/* (keep these last) */
H5FA_CLS_TEST_ID, /* Fixed array is for testing (do not use for actual data) */
H5FA_NUM_CLS_ID /* Number of Fixed Array class IDs (must be last) */
@@ -113,15 +111,14 @@ typedef int (*H5FA_operator_t)(hsize_t idx, const void *_elmt, void *_udata);
/* General routines */
H5_DLL H5FA_t *H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam,
void *ctx_udata);
-H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5FA_class_t *cls,
- void *ctx_udata);
+H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
H5_DLL herr_t H5FA_get_nelmts(const H5FA_t *ea, hsize_t *nelmts);
H5_DLL herr_t H5FA_get_addr(const H5FA_t *ea, haddr_t *addr);
H5_DLL herr_t H5FA_set(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt);
H5_DLL herr_t H5FA_get(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt);
-H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id);
-H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr);
H5_DLL herr_t H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata);
+H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id);
+H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
/* Statistics routines */
H5_DLL herr_t H5FA_get_stats(const H5FA_t *ea, H5FA_stat_t *stats);