summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c523
1 files changed, 336 insertions, 187 deletions
diff --git a/src/H5O.c b/src/H5O.c
index debf294..0c12032 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -84,6 +84,7 @@ static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type);
static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id,
hid_t dxpl_id);
+static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr);
/*********************/
@@ -124,21 +125,10 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = {
H5O_MSG_DRVINFO, /*0x0014 Driver info settings */
H5O_MSG_AINFO, /*0x0015 Attribute information */
H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */
+ H5O_MSG_FSINFO, /*0x0018 Free-space manager info message */
H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */
};
-/* Header object ID to class mapping */
-/*
- * Initialize the object class info table. Begin with the most general types
- * and end with the most specific. For instance, any object that has a
- * datatype message is a datatype but only some of them are datasets.
- */
-const H5O_obj_class_t *const H5O_obj_class_g[] = {
- H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */
- H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */
- H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */
-};
-
/* Declare a free list to manage the H5O_t struct */
H5FL_DEFINE(H5O_t);
@@ -167,6 +157,18 @@ H5FL_EXTERN(H5_obj_t);
/* Local Variables */
/*******************/
+/* Header object ID to class mapping */
+/*
+ * Initialize the object class info table. Begin with the most general types
+ * and end with the most specific. For instance, any object that has a
+ * datatype message is a datatype but only some of them are datasets.
+ */
+static const H5O_obj_class_t *const H5O_obj_class_g[] = {
+ H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */
+ H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */
+ H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */
+};
+
/*-------------------------------------------------------------------------
@@ -238,7 +240,7 @@ H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
/* Open the object */
- if((ret_value = H5O_open_name(&loc, name, lapl_id)) < 0)
+ if((ret_value = H5O_open_name(&loc, name, lapl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -309,7 +311,7 @@ H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
loc_found = TRUE;
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -342,7 +344,7 @@ done:
* H5Odecr_refcount() should be used when the object is
* no longer being referenced by address (e.g. when the UD link
* is deleted).
- *
+ *
* The address of the HDF5 file on disk has no effect on
* H5Oopen_by_addr(), nor does the use of any unusual file
* drivers. The "address" is really the offset within the
@@ -365,6 +367,7 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr)
H5G_name_t obj_path; /* Opened object group hier. path */
H5O_loc_t obj_oloc; /* Opened object object location */
hbool_t loc_found = FALSE; /* Location at 'name' found */
+ hid_t lapl_id = H5P_LINK_ACCESS_DEFAULT; /* lapl to use to open this object */
hid_t ret_value = FAIL;
FUNC_ENTER_API(H5Oopen_by_addr, FAIL)
@@ -385,7 +388,7 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr)
H5G_name_reset(obj_loc.path); /* objects opened through this routine don't have a path name */
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -438,8 +441,11 @@ H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!new_name || !*new_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+/* Avoid compiler warning on 32-bit machines */
+#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T
if(HDstrlen(new_name) > H5L_MAX_LINK_NAME_LEN)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "name too long")
+#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
@@ -1012,7 +1018,7 @@ H5Oclose(hid_t object_id)
case(H5I_DATASET):
if(H5I_object(object_id) == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object")
- if(H5I_dec_ref(object_id) < 0)
+ if(H5I_dec_ref(object_id, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
break;
@@ -1062,14 +1068,16 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
/* check args */
HDassert(f);
+ HDassert(f->intent & H5F_ACC_RDWR);
HDassert(loc);
HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE));
+
/* Make certain we allocate at least a reasonable size for the object header */
size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint));
/* Get the property list */
- if(NULL == (oc_plist = H5I_object(ocpl_id)))
+ if(NULL == (oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list")
/* Get any object header status flags set by properties */
@@ -1125,9 +1133,13 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
oh->flags |= H5O_HDR_ATTR_STORE_PHASE_CHANGE;
/* Determine correct value for chunk #0 size bits */
+/* Avoid compiler warning on 32-bit machines */
+#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T
if(size_hint > 4294967295)
oh->flags |= H5O_HDR_CHUNK0_8;
- else if(size_hint > 65535)
+ else
+#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */
+ if(size_hint > 65535)
oh->flags |= H5O_HDR_CHUNK0_4;
else if(size_hint > 255)
oh->flags |= H5O_HDR_CHUNK0_2;
@@ -1163,7 +1175,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
/* Put magic # for object header in first chunk */
if(oh->version > H5O_VERSION_1)
- HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5O_SIZEOF_MAGIC);
+ HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
/* Create the message list */
oh->nmesgs = 1;
@@ -1215,7 +1227,7 @@ done:
* Modification:
* Raymond Lu
* 5 November 2007
- * Turn off the holding file variable if it's on. When it's
+ * Turn off the holding file variable if it's on. When it's
* needed, the caller will turn it on again.
*-------------------------------------------------------------------------
*/
@@ -1260,7 +1272,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id)
+H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id, hbool_t app_ref)
{
H5G_loc_t obj_loc; /* Location used to open group */
H5G_name_t obj_path; /* Opened object group hier. path */
@@ -1285,7 +1297,7 @@ H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id)
loc_found = TRUE;
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_ind_dxpl_id, app_ref)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -1311,7 +1323,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t dxpl_id)
+H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref)
{
const H5O_obj_class_t *obj_class; /* Class of object for location */
hid_t ret_value; /* Return value */
@@ -1326,7 +1338,7 @@ H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t dxpl_id)
/* Call the object class's 'open' routine */
HDassert(obj_class->open);
- if((ret_value = obj_class->open(obj_loc, dxpl_id)) < 0)
+ if((ret_value = obj_class->open(obj_loc, lapl_id, dxpl_id, app_ref)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -1391,9 +1403,9 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_link
+ * Function: H5O_link_oh
*
- * Purpose: Adjust the link count for an object header by adding
+ * Purpose: Adjust the link count for an open object header by adding
* ADJUST to the link count.
*
* Return: Success: New link count
@@ -1407,24 +1419,12 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
+H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags)
{
- H5O_t *oh = NULL; /* Object header to query/modify */
- H5AC_protect_t oh_acc; /* Access mode for protecting object header */
- unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Whether the object was deleted */
+ haddr_t addr = H5O_OH_GET_ADDR(oh); /* Object header address */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_link, FAIL)
-
- /* check args */
- HDassert(loc);
- HDassert(loc->file);
- HDassert(H5F_addr_defined(loc->addr));
-
- /* Get header */
- oh_acc = adjust ? H5AC_WRITE : H5AC_READ;
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, oh_acc)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+ FUNC_ENTER_NOAPI(H5O_link_oh, FAIL)
/* Check for adjusting link count */
if(adjust) {
@@ -1437,32 +1437,33 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
oh->nlink += adjust;
/* Mark object header as dirty in cache */
- oh_flags |= H5AC__DIRTIED_FLAG;
+ *oh_flags |= H5AC__DIRTIED_FLAG;
/* Check if the object should be deleted */
if(oh->nlink == 0) {
/* Check if the object is still open by the user */
- if(H5FO_opened(loc->file, loc->addr) != NULL) {
+ if(H5FO_opened(f, addr) != NULL) {
/* Flag the object to be deleted when it's closed */
- if(H5FO_mark(loc->file, loc->addr, TRUE) < 0)
+ if(H5FO_mark(f, addr, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
else {
/* Delete object right now */
- if(H5O_delete_oh(loc->file, dxpl_id, oh) < 0)
+ if(H5O_delete_oh(f, dxpl_id, oh) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
/* Mark the object header for deletion */
- oh_flags = H5C__DELETED_FLAG;
+ *oh_flags = H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
} /* end else */
} /* end if */
- } else {
+ } /* end if */
+ else {
/* A new object, or one that will be deleted */
- if(oh->nlink == 0) {
- /* Check if the object is current open, but marked for deletion */
- if(H5FO_marked(loc->file, loc->addr) > 0) {
+ if(0 == oh->nlink) {
+ /* Check if the object is currently open, but marked for deletion */
+ if(H5FO_marked(f, addr)) {
/* Remove "delete me" flag on the object */
- if(H5FO_mark(loc->file, loc->addr, FALSE) < 0)
+ if(H5FO_mark(f, addr, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
} /* end if */
@@ -1471,7 +1472,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
oh->nlink += adjust;
/* Mark object header as dirty in cache */
- oh_flags |= H5AC__DIRTIED_FLAG;
+ *oh_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
/* Check for operations on refcount message */
@@ -1480,7 +1481,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
if(oh->has_refcount_msg) {
/* Check for removing refcount message */
if(oh->nlink <= 1) {
- if(H5O_msg_remove_real(loc->file, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0)
+ if(H5O_msg_remove_real(f, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete refcount message")
oh->has_refcount_msg = FALSE;
} /* end if */
@@ -1488,7 +1489,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
else {
H5O_refcount_t refcount = oh->nlink;
- if(H5O_msg_write_real(loc->file, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
+ if(H5O_msg_write_real(f, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update refcount message")
} /* end else */
} /* end if */
@@ -1497,7 +1498,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
if(oh->nlink > 1) {
H5O_refcount_t refcount = oh->nlink;
- if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
+ if(H5O_msg_append_real(f, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new refcount message")
oh->has_refcount_msg = TRUE;
} /* end if */
@@ -1506,7 +1507,52 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
} /* end if */
/* Set return value */
- ret_value = oh->nlink;
+ ret_value = (int)oh->nlink;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_link_oh() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link
+ *
+ * Purpose: Adjust the link count for an object header by adding
+ * ADJUST to the link count.
+ *
+ * Return: Success: New link count
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
+{
+ H5O_t *oh = NULL;
+ H5AC_protect_t oh_acc; /* Access mode for protecting object header */
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Whether the object was deleted */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_link, FAIL)
+
+ /* check args */
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+
+ /* Get header */
+ oh_acc = adjust ? H5AC_WRITE : H5AC_READ;
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, oh_acc)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
+
+ /* Call the "real" link routine */
+ if((ret_value = H5O_link_oh(loc->file, adjust, dxpl_id, oh, &oh_flags)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust object link count")
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
@@ -1517,15 +1563,14 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_protect
+ * Function: H5O_pin
*
- * Purpose: Wrapper around H5AC_protect for use during a H5O_protect->
- * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls
- * during an object's creation.
+ * Purpose: Pin an object header down for use during a sequence of message
+ * operations, which prevents the object header from being
+ * evicted from the cache.
*
* Return: Success: Pointer to the object header structure for the
* object.
- *
* Failure: NULL
*
* Programmer: Quincey Koziol
@@ -1535,11 +1580,12 @@ done:
*-------------------------------------------------------------------------
*/
H5O_t *
-H5O_protect(H5O_loc_t *loc, hid_t dxpl_id)
+H5O_pin(H5O_loc_t *loc, hid_t dxpl_id)
{
- H5O_t *ret_value; /* Return value */
+ H5O_t *oh = NULL; /* Object header */
+ H5O_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_protect, NULL)
+ FUNC_ENTER_NOAPI(H5O_pin, NULL)
/* check args */
HDassert(loc);
@@ -1551,31 +1597,36 @@ H5O_protect(H5O_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "no write intent on file")
/* Lock the object header into the cache */
- if(NULL == (ret_value = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header")
- /* Mark object header as un-evictable */
- if(H5AC_pin_protected_entry(loc->file, ret_value) < 0) {
- if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header")
-
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header")
+ /* Check if the object header needs to be pinned */
+ if(0 == oh->npins) {
+ /* Mark object header as un-evictable */
+ if(H5AC_pin_protected_entry(loc->file, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header")
} /* end if */
- /* Release the object header from the cache */
- if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header")
+ /* Increment the pin count */
+ oh->npins++;
+
+ /* Set the return value */
+ ret_value = oh;
+
done:
+ /* Release the object header from the cache */
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_protect() */
+} /* end H5O_pin() */
/*-------------------------------------------------------------------------
- * Function: H5O_unprotect
+ * Function: H5O_unpin
*
- * Purpose: Wrapper around H5AC_unprotect for use during a H5O_protect->
- * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls
- * during an object's creation.
+ * Purpose: Unpin an object header, allowing it to be evicted from the
+ * metadata cache.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -1587,11 +1638,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_unprotect(H5O_loc_t *loc, H5O_t *oh)
+H5O_unpin(H5O_loc_t *loc, H5O_t *oh)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_unprotect, FAIL)
+ FUNC_ENTER_NOAPI(H5O_unpin, FAIL)
/* check args */
HDassert(loc);
@@ -1599,13 +1650,19 @@ H5O_unprotect(H5O_loc_t *loc, H5O_t *oh)
HDassert(H5F_addr_defined(loc->addr));
HDassert(oh);
- /* Mark object header as evictable again */
- if(H5AC_unpin_entry(loc->file, oh) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header")
+ /* Check if this is the last unpin operation */
+ if(1 == oh->npins) {
+ /* Mark object header as evictable again */
+ if(H5AC_unpin_entry(loc->file, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header")
+ } /* end if */
+
+ /* Decrement the pin count */
+ oh->npins--;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_unprotect() */
+} /* end H5O_unpin() */
/*-------------------------------------------------------------------------
@@ -1656,11 +1713,11 @@ H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force)
HGOTO_DONE(SUCCEED); /*nothing to do*/
/* Allocate space for the modification time message */
- if((idx = H5O_msg_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, &mesg_flags, &now)) == UFAIL)
+ if(UFAIL == (idx = H5O_msg_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, &mesg_flags, &now)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message")
/* Set the message's flags if appropriate */
- oh->mesg[idx].flags = mesg_flags;
+ oh->mesg[idx].flags = (uint8_t)mesg_flags;
} /* end if */
/* Allocate 'native' space, if necessary */
@@ -1723,7 +1780,7 @@ H5O_touch(const H5O_loc_t *loc, hbool_t force, hid_t dxpl_id)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Create/Update the modification time message */
@@ -1832,7 +1889,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HDassert(H5F_addr_defined(addr));
/* Get the object header information */
- if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Delete object */
@@ -1840,7 +1897,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
done:
- if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0)
+ if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1886,10 +1943,6 @@ H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
} /* end for */
- /* Free main (first) object header "chunk" */
- if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, oh->chunk[0].addr, (hsize_t)oh->chunk[0].size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_oh() */
@@ -1900,8 +1953,8 @@ done:
*
* Purpose: Retrieves the type of object pointed to by `loc'.
*
- * Return: Success: An object type defined in H5Gpublic.h
- * Failure: H5G_UNKNOWN
+ * Return: Success: Non-negative
+ * Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, November 4, 1998
@@ -1917,7 +1970,7 @@ H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id)
FUNC_ENTER_NOAPI(H5O_obj_type, FAIL)
/* Load the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Retrieve the type of the object */
@@ -1937,8 +1990,8 @@ done:
*
* Purpose: Returns the type of object pointed to by `oh'.
*
- * Return: Success: An object type defined in H5Opublic.h
- * Failure: H5G_UNKNOWN
+ * Return: Success: Non-negative
+ * Failure: Negative
*
* Programmer: Quincey Koziol
* Monday, November 21, 2005
@@ -1995,7 +2048,7 @@ H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id)
FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class)
/* Load the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header")
/* Test whether entry qualifies as a particular type of object */
@@ -2253,6 +2306,131 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_get_hdr_info
+ *
+ * Purpose: Retrieve the object header information for an object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * September 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_get_hdr_info, FAIL)
+
+ /* Check args */
+ HDassert(oloc);
+ HDassert(hdr);
+
+ /* Reset the object header info structure */
+ HDmemset(hdr, 0, sizeof(*hdr));
+
+ /* Get the object header */
+ if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* Get the information for the object header */
+ if(H5O_get_hdr_info_real(oh, hdr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info")
+
+done:
+ if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_get_hdr_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_hdr_info_real
+ *
+ * Purpose: Internal routine to retrieve the object header information for an object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * September 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr)
+{
+ const H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
+ const H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */
+ unsigned u; /* Local index variable */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_get_hdr_info_real)
+
+ /* Check args */
+ HDassert(oh);
+ HDassert(hdr);
+
+ /* Set the version for the object header */
+ hdr->version = oh->version;
+
+ /* Set the number of messages & chunks */
+ hdr->nmesgs = oh->nmesgs;
+ hdr->nchunks = oh->nchunks;
+
+ /* Set the status flags */
+ hdr->flags = oh->flags;
+
+ /* Iterate over all the messages, accumulating message size & type information */
+ hdr->space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
+ hdr->space.mesg = 0;
+ hdr->space.free = 0;
+ hdr->mesg.present = 0;
+ hdr->mesg.shared = 0;
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ uint64_t type_flag; /* Flag for message type */
+
+ /* Accumulate space usage information, based on the type of message */
+ if(H5O_NULL_ID == curr_msg->type->id)
+ hdr->space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ else if(H5O_CONT_ID == curr_msg->type->id)
+ hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ else {
+ hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh);
+ hdr->space.mesg += curr_msg->raw_size;
+ } /* end else */
+
+ /* Set flag to indicate presence of message type */
+ type_flag = ((uint64_t)1) << curr_msg->type->id;
+ hdr->mesg.present |= type_flag;
+
+ /* Set flag if the message is shared in some way */
+ if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \
+ hdr->mesg.shared |= type_flag;
+ } /* end for */
+
+ /* Iterate over all the chunks, adding any gaps to the free space */
+ hdr->space.total = 0;
+ for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) {
+ /* Accumulate the size of the header on disk */
+ hdr->space.total += curr_chunk->size;
+
+ /* If the chunk has a gap, add it to the free space */
+ hdr->space.free += curr_chunk->gap;
+ } /* end for */
+
+ /* Sanity check that all the bytes are accounted for */
+ HDassert(hdr->space.total == (hdr->space.free + hdr->space.meta + hdr->space.mesg));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_get_hdr_info_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_get_info
*
* Purpose: Retrieve the information for an object
@@ -2266,12 +2444,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo)
+H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info,
+ H5O_info_t *oinfo)
{
+ const H5O_obj_class_t *obj_class; /* Class of object for header */
H5O_t *oh = NULL; /* Object header */
- H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */
- H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_get_info, FAIL)
@@ -2281,7 +2458,7 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
HDassert(oinfo);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Reset the object info structure */
@@ -2293,20 +2470,12 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
/* Set the object's address */
oinfo->addr = loc->addr;
- /* Retrieve the type of the object */
- if(H5O_obj_type_real(oh, &oinfo->type) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
+ /* Get class for object */
+ if(NULL == (obj_class = H5O_obj_class_real(oh)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class")
- /* Retrieve btree and heap storage info, if requested */
- if(want_ih_info) {
- if(oinfo->type == H5O_TYPE_GROUP) {
- if(H5O_group_bh_info(loc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve group btree & heap info")
- } else if(oinfo->type == H5O_TYPE_DATASET) {
- if(H5O_dset_bh_info(loc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve chunked dataset btree info")
- }
- } /* end if */
+ /* Retrieve the type of the object */
+ oinfo->type = obj_class->type;
/* Set the object's reference count */
oinfo->rc = oh->nlink;
@@ -2319,6 +2488,8 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
oinfo->btime = oh->btime;
} /* end if */
else {
+ htri_t exists; /* Flag if header message of interest exists */
+
/* No information for access & modification fields */
/* (we stopped updating the "modification time" header message for
* raw data changes, so the "modification time" header message
@@ -2329,74 +2500,50 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
oinfo->btime = 0;
/* Might be information for modification time */
- if(NULL == H5O_msg_read_real(loc->file, dxpl_id, oh, H5O_MTIME_ID, &oinfo->ctime)) {
- H5E_clear_stack(NULL);
- if(NULL == H5O_msg_read_real(loc->file, dxpl_id, oh, H5O_MTIME_NEW_ID, &oinfo->ctime)) {
- H5E_clear_stack(NULL);
- oinfo->ctime = 0;
- } /* end if */
+ if((exists = H5O_msg_exists_oh(oh, H5O_MTIME_ID)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for MTIME message")
+ if(exists > 0) {
+ /* Get "old style" modification time info */
+ if(NULL == H5O_msg_read_oh(loc->file, dxpl_id, oh, H5O_MTIME_ID, &oinfo->ctime))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read MTIME message")
} /* end if */
- } /* end else */
-
- /* Set the version for the object header */
- oinfo->hdr.version = oh->version;
-
- /* Set the number of messages & chunks */
- oinfo->hdr.nmesgs = oh->nmesgs;
- oinfo->hdr.nchunks = oh->nchunks;
-
- /* Set the status flags */
- oinfo->hdr.flags = oh->flags;
-
- /* Iterate over all the messages, accumulating message size & type information */
- oinfo->hdr.space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
- oinfo->hdr.space.mesg = 0;
- oinfo->hdr.space.free = 0;
- oinfo->hdr.mesg.present = 0;
- oinfo->hdr.mesg.shared = 0;
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- uint64_t type_flag; /* Flag for message type */
-
- /* Accumulate space usage information, based on the type of message */
- if(H5O_NULL_ID == curr_msg->type->id)
- oinfo->hdr.space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
- else if(H5O_CONT_ID == curr_msg->type->id)
- oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
else {
- oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh);
- oinfo->hdr.space.mesg += curr_msg->raw_size;
+ /* Check for "new style" modification time info */
+ if((exists = H5O_msg_exists_oh(oh, H5O_MTIME_NEW_ID)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for MTIME_NEW message")
+ if(exists > 0) {
+ /* Get "new style" modification time info */
+ if(NULL == H5O_msg_read_oh(loc->file, dxpl_id, oh, H5O_MTIME_NEW_ID, &oinfo->ctime))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read MTIME_NEW message")
+ } /* end if */
+ else
+ oinfo->ctime = 0;
} /* end else */
+ } /* end else */
- /* Set flag to indicate presence of message type */
- type_flag = ((uint64_t)1) << curr_msg->type->id;
- oinfo->hdr.mesg.present |= type_flag;
-
- /* Set flag if the message is shared in some way */
- if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \
- oinfo->hdr.mesg.shared |= type_flag;
- } /* end for */
+ /* Get the information for the object header */
+ if(H5O_get_hdr_info_real(oh, &oinfo->hdr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info")
/* Retrieve # of attributes */
- oinfo->num_attrs = H5O_attr_count_real(loc->file, dxpl_id, oh);
+ if(H5O_attr_count_real(loc->file, dxpl_id, oh, &oinfo->num_attrs) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute count")
/* Get B-tree & heap metadata storage size, if requested */
if(want_ih_info) {
- if((oinfo->num_attrs > 0) && (H5O_attr_bh_info(loc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info")
- } /* end if */
-
- /* Iterate over all the chunks, adding any gaps to the free space */
- oinfo->hdr.space.total = 0;
- for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) {
- /* Accumulate the size of the header on disk */
- oinfo->hdr.space.total += curr_chunk->size;
-
- /* If the chunk has a gap, add it to the free space */
- oinfo->hdr.space.free += curr_chunk->gap;
- } /* end for */
+ /* Check for 'bh_info' callback for this type of object */
+ if(obj_class->bh_info) {
+ /* Call the object's class 'bh_info' routine */
+ if((obj_class->bh_info)(loc->file, dxpl_id, oh, &oinfo->meta_size.obj) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object's btree & heap info")
+ } /* end if */
- /* Sanity check that all the bytes are accounted for */
- HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg));
+ /* Get B-tree & heap info for any attributes */
+ if(oinfo->num_attrs > 0) {
+ if(H5O_attr_bh_info(loc->file, dxpl_id, oh, &oinfo->meta_size.attr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info")
+ } /* end if */
+ } /* end if */
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
@@ -2432,7 +2579,7 @@ H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, H5P_genplist_t *oc_pli
HDassert(oc_plist);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Set property values, if they were used for the object */
@@ -2487,7 +2634,7 @@ H5O_get_nlinks(const H5O_loc_t *loc, hid_t dxpl_id, hsize_t *nlinks)
HDassert(nlinks);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Retrieve the # of link messages seen when the object header was loaded */
@@ -2606,7 +2753,7 @@ H5O_get_rc_and_type(const H5O_loc_t *loc, hid_t dxpl_id, unsigned *rc, H5O_type_
HDassert(otype);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Set the object's reference count */
@@ -2641,7 +2788,7 @@ H5O_free_visit_visited(void *item, void UNUSED *key, void UNUSED *operator_data/
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_visit_visited)
- H5FL_FREE(H5_obj_t, item);
+ (void)H5FL_FREE(H5_obj_t, item);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_free_visit_visited() */
@@ -2811,13 +2958,17 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
/* Open the object */
/* (Takes ownership of the obj_loc information) */
- if((obj_id = H5O_open_by_loc(&obj_loc, dxpl_id)) < 0)
+ if((obj_id = H5O_open_by_loc(&obj_loc, lapl_id, dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
/* Make callback for starting object */
if((ret_value = op(obj_id, ".", &oinfo, op_data)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "can't visit objects")
+ /* Check return value of first callback */
+ if(ret_value != H5_ITER_CONT)
+ HGOTO_DONE(ret_value);
+
/* Check for object being a group */
if(oinfo.type == H5O_TYPE_GROUP) {
H5G_loc_t start_loc; /* Location of starting group */
@@ -2833,9 +2984,9 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
udata.dxpl_id = dxpl_id;
udata.op = op;
udata.op_data = op_data;
-
+
/* Create skip list to store visited object information */
- if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, 0.5, (size_t)16)) == NULL)
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
/* If its ref count is > 1, we add it to the list of visited objects */
@@ -2863,7 +3014,7 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
done:
if(obj_id > 0) {
- if(H5I_dec_ref(obj_id) < 0)
+ if(H5I_dec_ref(obj_id, TRUE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
} /* end if */
else if(loc_found && H5G_loc_free(&obj_loc) < 0)
@@ -2873,5 +3024,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_visit() */
-
-