From 3e61010340b7b545f434e3b39dbb56337f8803b5 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 1 Dec 2020 13:20:05 -0600 Subject: Expand ID dec_ref and close callbacks to allow for asynchronous close operations (#135) * Expand ID dec_ref and close callbacks to allow for asynchronous close operations. * Fix typo * Rename token -> request, remove programmer name * H5E_ATOM to H5E_ID --- src/H5A.c | 10 ++-- src/H5Aint.c | 6 +-- src/H5Dint.c | 6 +-- src/H5E.c | 16 +++---- src/H5F.c | 4 +- src/H5FD.c | 4 +- src/H5Fint.c | 6 +-- src/H5Gint.c | 6 +-- src/H5Iint.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++-------- src/H5Ipublic.h | 2 +- src/H5M.c | 6 +-- src/H5Pint.c | 90 ++++++++++++++++++++++++++++++------ src/H5Ppkg.h | 2 +- src/H5Pprivate.h | 2 +- src/H5S.c | 48 +++++++++++++++---- src/H5Spkg.h | 3 ++ src/H5Sselect.c | 31 +++++++++++++ src/H5T.c | 6 +-- src/H5VLint.c | 4 +- test/tid.c | 4 +- 20 files changed, 313 insertions(+), 81 deletions(-) diff --git a/src/H5A.c b/src/H5A.c index ae54370..20d6107 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -1456,12 +1456,14 @@ H5Aclose(hid_t attr_id) H5TRACE1("e", "i", attr_id); /* Check arguments */ - if (NULL == H5I_object_verify(attr_id, H5I_ATTR)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") + if (H5I_ATTR != H5I_get_type(attr_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute ID") - /* Decrement references to that ID (and close it) */ + /* Decrement the counter on the attribute ID. It will be freed if the count + * reaches zero. + */ if (H5I_dec_app_ref(attr_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute") + HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Aint.c b/src/H5Aint.c index 5bc4a65..48e22ad 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -83,7 +83,7 @@ typedef struct { /* Local Prototypes */ /********************/ -static herr_t H5A__close_cb(H5VL_object_t *attr_vol_obj); +static herr_t H5A__close_cb(H5VL_object_t *attr_vol_obj, void **request); static herr_t H5A__compact_build_table_cb(H5O_t *oh, H5O_mesg_t *mesg /*in,out*/, unsigned sequence, unsigned *oh_flags_ptr, void *_udata /*in,out*/); static herr_t H5A__dense_build_table_cb(const H5A_t *attr, void *_udata); @@ -1293,7 +1293,7 @@ H5A__shared_free(H5A_t *attr) *------------------------------------------------------------------------- */ static herr_t -H5A__close_cb(H5VL_object_t *attr_vol_obj) +H5A__close_cb(H5VL_object_t *attr_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1303,7 +1303,7 @@ H5A__close_cb(H5VL_object_t *attr_vol_obj) HDassert(attr_vol_obj); /* Close the attribute */ - if ((ret_value = H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0) + if ((ret_value = H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, request)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "problem closing attribute") /* Free the VOL object */ diff --git a/src/H5Dint.c b/src/H5Dint.c index e7248eb..0da1e01 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -83,7 +83,7 @@ static herr_t H5D__build_file_prefix(const H5D_t *dset, H5F_prefix_open_t prefix static herr_t H5D__open_oid(H5D_t *dataset, hid_t dapl_id); static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[]); static herr_t H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id); -static herr_t H5D__close_cb(H5VL_object_t *dset_vol_obj); +static herr_t H5D__close_cb(H5VL_object_t *dset_vol_obj, void **request); static herr_t H5D__use_minimized_dset_headers(H5F_t *file, hbool_t *minimize); static herr_t H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc); static size_t H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr); @@ -330,7 +330,7 @@ H5D_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5D__close_cb(H5VL_object_t *dset_vol_obj) +H5D__close_cb(H5VL_object_t *dset_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -340,7 +340,7 @@ H5D__close_cb(H5VL_object_t *dset_vol_obj) HDassert(dset_vol_obj); /* Close the dataset */ - if (H5VL_dataset_close(dset_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_dataset_close(dset_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset"); done: diff --git a/src/H5E.c b/src/H5E.c index 6042048..2153549 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -76,14 +76,14 @@ /* Static function declarations */ static herr_t H5E__set_default_auto(H5E_t *stk); static H5E_cls_t *H5E__register_class(const char *cls_name, const char *lib_name, const char *version); -static herr_t H5E__unregister_class(H5E_cls_t *cls); +static herr_t H5E__unregister_class(H5E_cls_t *cls, void **request); static ssize_t H5E__get_class_name(const H5E_cls_t *cls, char *name, size_t size); static int H5E__close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata); -static herr_t H5E__close_msg(H5E_msg_t *err); +static herr_t H5E__close_msg(H5E_msg_t *err, void **request); static H5E_msg_t *H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg); static H5E_t * H5E__get_current_stack(void); static herr_t H5E__set_current_stack(H5E_t *estack); -static herr_t H5E__close_stack(H5E_t *err_stack); +static herr_t H5E__close_stack(H5E_t *err_stack, void **request); static ssize_t H5E__get_num(const H5E_t *err_stack); /*********************/ @@ -540,7 +540,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E__unregister_class(H5E_cls_t *cls) +H5E__unregister_class(H5E_cls_t *cls, void H5_ATTR_UNUSED **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -660,7 +660,7 @@ H5E__close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata) /* Close the message if it is in the class being closed */ if (err_msg->cls == cls) { - if (H5E__close_msg(err_msg) < 0) + if (H5E__close_msg(err_msg, NULL) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "unable to close error message") if (NULL == H5I_remove(obj_id)) HGOTO_ERROR(H5E_ERROR, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove error message") @@ -715,7 +715,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E__close_msg(H5E_msg_t *err) +H5E__close_msg(H5E_msg_t *err, void H5_ATTR_UNUSED **request) { FUNC_ENTER_STATIC_NOERR @@ -816,7 +816,7 @@ H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg_str) done: if (!ret_value) - if (msg && H5E__close_msg(msg) < 0) + if (msg && H5E__close_msg(msg, NULL) < 0) HDONE_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, NULL, "unable to close error message") FUNC_LEAVE_NOAPI(ret_value) @@ -1163,7 +1163,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E__close_stack(H5E_t *estack) +H5E__close_stack(H5E_t *estack, void H5_ATTR_UNUSED **request) { FUNC_ENTER_STATIC_NOERR diff --git a/src/H5F.c b/src/H5F.c index 26c8ecb..6705a3c 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -706,7 +706,9 @@ H5Fclose(hid_t file_id) if (H5I_FILE != H5I_get_type(file_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") - /* Close the file */ + /* Synchronously decrement reference count on ID. + * When it reaches zero the file will be closed. + */ if (H5I_dec_app_ref(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") diff --git a/src/H5FD.c b/src/H5FD.c index ab96691..d12bb57 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -54,7 +54,7 @@ /********************/ /* Local Prototypes */ /********************/ -static herr_t H5FD__free_cls(H5FD_class_t *cls); +static herr_t H5FD__free_cls(H5FD_class_t *cls, void **request); static herr_t H5FD__query(const H5FD_t *f, unsigned long *flags /*out*/); /*********************/ @@ -172,7 +172,7 @@ H5FD_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5FD__free_cls(H5FD_class_t *cls) +H5FD__free_cls(H5FD_class_t *cls, void H5_ATTR_UNUSED **request) { herr_t ret_value = SUCCEED; diff --git a/src/H5Fint.c b/src/H5Fint.c index 5e22ed8..92b70ce 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -72,7 +72,7 @@ typedef struct H5F_olist_t { /* Local Prototypes */ /********************/ -static herr_t H5F__close_cb(H5VL_object_t *file_vol_obj); +static herr_t H5F__close_cb(H5VL_object_t *file_vol_obj, void **request); static herr_t H5F__set_vol_conn(H5F_t *file); static herr_t H5F__get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr); @@ -234,7 +234,7 @@ H5F_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5F__close_cb(H5VL_object_t *file_vol_obj) +H5F__close_cb(H5VL_object_t *file_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -244,7 +244,7 @@ H5F__close_cb(H5VL_object_t *file_vol_obj) HDassert(file_vol_obj); /* Close the file */ - if (H5VL_file_close(file_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_file_close(file_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") /* Free the VOL object */ diff --git a/src/H5Gint.c b/src/H5Gint.c index 3741067..56c4751 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -84,7 +84,7 @@ typedef struct { static herr_t H5G__open_oid(H5G_t *grp); static herr_t H5G__visit_cb(const H5O_link_t *lnk, void *_udata); -static herr_t H5G__close_cb(H5VL_object_t *grp_vol_obj); +static herr_t H5G__close_cb(H5VL_object_t *grp_vol_obj, void **request); /*********************/ /* Package Variables */ @@ -263,7 +263,7 @@ H5G_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5G__close_cb(H5VL_object_t *grp_vol_obj) +H5G__close_cb(H5VL_object_t *grp_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -273,7 +273,7 @@ H5G__close_cb(H5VL_object_t *grp_vol_obj) HDassert(grp_vol_obj); /* Close the group */ - if (H5VL_group_close(grp_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_group_close(grp_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close group") /* Free the VOL object */ diff --git a/src/H5Iint.c b/src/H5Iint.c index 95baa28..b511cb5 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -77,6 +77,9 @@ typedef struct { static void * H5I__unwrap(void *object, H5I_type_t type); static htri_t H5I__clear_type_cb(void *_id, void *key, void *udata); static void * H5I__remove_common(H5I_type_info_t *type_info, hid_t id); +static int H5I__dec_ref(hid_t id, void **request); +static int H5I__dec_app_ref(hid_t id, void **request); +static int H5I__dec_app_ref_always_close(hid_t id, void **request); static int H5I__find_id_cb(void *_item, void *_key, void *_udata); /*********************/ @@ -367,7 +370,7 @@ H5I__clear_type_cb(void *_info, void H5_ATTR_UNUSED *key, void *_udata) /* Check for a 'free' function and call it, if it exists */ H5_GCC_DIAG_OFF("cast-qual") if (udata->type_info->cls->free_func && - (udata->type_info->cls->free_func)((void *)info->object) < 0) { /* (Casting away const OK -QAK) */ + (udata->type_info->cls->free_func)((void *)info->object, H5_REQUEST_NULL) < 0) { /* (Casting away const OK -QAK) */ if (udata->force) { #ifdef H5I_DEBUG if (H5DEBUG(I)) { @@ -887,7 +890,7 @@ done: } /* end H5I_remove() */ /*------------------------------------------------------------------------- - * Function: H5I_dec_ref + * Function: H5I__dec_ref * * Purpose: Decrements the number of references outstanding for an ID. * This will fail if the type is not a reference counted type. @@ -895,18 +898,21 @@ done: * if the reference count for the ID reaches 0 and a free * function has been defined at type creation time. * + * Note: Allows for asynchronous 'close' operation on object, with + * request != H5_REQUEST_NULL. + * * Return: Success: New reference count * Failure: -1 * *------------------------------------------------------------------------- */ -int -H5I_dec_ref(hid_t id) +static int +H5I__dec_ref(hid_t id, void **request) { H5I_id_info_t *info = NULL; /* Pointer to the ID */ int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI((-1)) + FUNC_ENTER_STATIC /* Sanity check */ HDassert(id >= 0); @@ -937,7 +943,7 @@ H5I_dec_ref(hid_t id) H5_GCC_DIAG_OFF("cast-qual") /* (Casting away const OK -QAK) */ - if (!type_info->cls->free_func || (type_info->cls->free_func)((void *)info->object) >= 0) { + if (!type_info->cls->free_func || (type_info->cls->free_func)((void *)info->object, request) >= 0) { /* Remove the node from the type */ if (NULL == H5I__remove_common(type_info, id)) HGOTO_ERROR(H5E_ID, H5E_CANTDELETE, (-1), "can't remove ID node") @@ -954,34 +960,62 @@ H5I_dec_ref(hid_t id) done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I__dec_ref */ + +/*------------------------------------------------------------------------- + * Function: H5I_dec_ref + * + * Purpose: Decrements the number of references outstanding for an ID. + * + * Return: Success: New reference count + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +int +H5I_dec_ref(hid_t id) +{ + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI((-1)) + + /* Sanity check */ + HDassert(id >= 0); + + /* Synchronously decrement refcount on ID */ + if ((ret_value = H5I__dec_ref(id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_dec_ref() */ /*------------------------------------------------------------------------- - * Function: H5I_dec_app_ref + * Function: H5I__dec_app_ref * * Purpose: Wrapper for case of modifying the application ref. * count for an ID as well as normal reference count. * + * Note: Allows for asynchronous 'close' operation on object, with + * request != H5_REQUEST_NULL. + * * Return: Success: New app. reference count * Failure: -1 * - * Programmer: Quincey Koziol - * Sept 16, 2010 - * *------------------------------------------------------------------------- */ -int -H5I_dec_app_ref(hid_t id) +static int +H5I__dec_app_ref(hid_t id, void **request) { int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI((-1)) + FUNC_ENTER_STATIC /* Sanity check */ HDassert(id >= 0); /* Call regular decrement reference count routine */ - if ((ret_value = H5I_dec_ref(id)) < 0) + if ((ret_value = H5I__dec_ref(id, request)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count") /* Check if the ID still exists */ @@ -1002,31 +1036,66 @@ H5I_dec_app_ref(hid_t id) done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I__dec_app_ref() */ + +/*------------------------------------------------------------------------- + * Function: H5I_dec_app_ref + * + * Purpose: Wrapper for case of modifying the application ref. count for + * an ID as well as normal reference count. + * + * Return: Success: New app. reference count + * Failure: -1 + * + * Programmer: Quincey Koziol + * Sept 16, 2010 + * + *------------------------------------------------------------------------- + */ +int +H5I_dec_app_ref(hid_t id) +{ + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI((-1)) + + /* Sanity check */ + HDassert(id >= 0); + + /* Synchronously decrement refcount on ID */ + if ((ret_value = H5I__dec_app_ref(id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_dec_app_ref() */ /*------------------------------------------------------------------------- - * Function: H5I_dec_app_ref_always_close + * Function: H5I__dec_app_ref_always_close * * Purpose: Wrapper for case of always closing the ID, even when the free * routine fails * + * Note: Allows for asynchronous 'close' operation on object, with + * request != H5_REQUEST_NULL. + * * Return: Success: New app. reference count * Failure: -1 * *------------------------------------------------------------------------- */ -int -H5I_dec_app_ref_always_close(hid_t id) +static int +H5I__dec_app_ref_always_close(hid_t id, void **request) { int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI((-1)) + FUNC_ENTER_STATIC /* Sanity check */ HDassert(id >= 0); /* Call application decrement reference count routine */ - ret_value = H5I_dec_app_ref(id); + ret_value = H5I__dec_app_ref(id, request); /* Check for failure */ if (ret_value < 0) { @@ -1039,7 +1108,36 @@ H5I_dec_app_ref_always_close(hid_t id) H5I_remove(id); HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count") - } + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I__dec_app_ref_always_close() */ + +/*------------------------------------------------------------------------- + * Function: H5I_dec_app_ref_always_close + * + * Purpose: Wrapper for case of always closing the ID, even when the free + * routine fails. + * + * Return: Success: New app. reference count + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +int +H5I_dec_app_ref_always_close(hid_t id) +{ + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI((-1)) + + /* Sanity check */ + HDassert(id >= 0); + + /* Synchronously decrement refcount on ID */ + if ((ret_value = H5I__dec_app_ref_always_close(id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index 9c5b5d4..3912252 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -80,7 +80,7 @@ typedef int64_t hid_t; * can be removed from the ID type. If the function returns negative * (failure) then the object will remain in the ID type. */ -typedef herr_t (*H5I_free_t)(void *); +typedef herr_t (*H5I_free_t)(void *, void **); /** * The type of a function to compare objects & keys diff --git a/src/H5M.c b/src/H5M.c index 4f9e9cb..4cb5d3a 100644 --- a/src/H5M.c +++ b/src/H5M.c @@ -38,7 +38,7 @@ /********************/ /* Local Prototypes */ /********************/ -static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj); +static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request); /*********************/ /* Package Variables */ @@ -195,7 +195,7 @@ H5M_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5M__close_cb(H5VL_object_t *map_vol_obj) +H5M__close_cb(H5VL_object_t *map_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -205,7 +205,7 @@ H5M__close_cb(H5VL_object_t *map_vol_obj) HDassert(map_vol_obj); /* Close the map */ - if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map"); /* Free the VOL object */ diff --git a/src/H5Pint.c b/src/H5Pint.c index df8516d..0d9fad7 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -95,6 +95,10 @@ typedef herr_t (*H5P_do_pclass_op_t)(H5P_genplist_t *plist, const char *name, H5 /* Local Prototypes */ /********************/ +/* Infrastructure routines */ +static herr_t H5P__close_class_cb(void *space, void **request); +static herr_t H5P__close_list_cb(void *space, void **request); + /* General helper routines */ static H5P_genplist_t *H5P__create(H5P_genclass_t *pclass); static H5P_genprop_t * H5P__create_prop(const char *name, size_t size, H5P_prop_within_t type, @@ -393,18 +397,18 @@ H5FL_DEFINE_STATIC(H5P_genplist_t); /* Generic Property Class ID class */ static const H5I_class_t H5I_GENPROPCLS_CLS[1] = {{ - H5I_GENPROP_CLS, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5P__close_class /* Callback routine for closing objects of this class */ + H5I_GENPROP_CLS, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5P__close_class_cb /* Callback routine for closing objects of this class */ }}; /* Generic Property List ID class */ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{ - H5I_GENPROP_LST, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5P_close /* Callback routine for closing objects of this class */ + H5I_GENPROP_LST, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5P__close_list_cb /* Callback routine for closing objects of this class */ }}; /*------------------------------------------------------------------------- @@ -621,6 +625,68 @@ H5P_term_package(void) FUNC_LEAVE_NOAPI(n) } /* end H5P_term_package() */ +/*------------------------------------------------------------------------- + * Function: H5P__close_class_cb + * + * Purpose: Called when the ref count reaches zero on a property class's ID + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__close_class_cb(void *_pclass, void H5_ATTR_UNUSED **request) +{ + H5P_genclass_t *pclass = (H5P_genclass_t *)_pclass; /* Property list class to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(pclass); + + /* Close the property list class object */ + if (H5P__close_class(pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list class"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__close_class_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5P__close_list_cb + * + * Purpose: Called when the ref count reaches zero on a property list's ID + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__close_list_cb(void *_plist, void H5_ATTR_UNUSED **request) +{ + H5P_genplist_t *plist = (H5P_genplist_t *)_plist; /* Property list to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(plist); + + /* Close the property list object */ + if (H5P_close(plist) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__close_list_cb() */ + /*-------------------------------------------------------------------------- NAME H5P__do_prop_cb1 @@ -5010,10 +5076,9 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P_close(void *_plist) +H5P_close(H5P_genplist_t *plist) { H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genplist_t *plist = (H5P_genplist_t *)_plist; H5SL_t * seen = NULL; /* Skip list to hold names of properties already seen */ size_t nseen; /* Number of items 'seen' */ hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ @@ -5393,10 +5458,9 @@ H5P__get_class_parent(const H5P_genclass_t *pclass) REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P__close_class(void *_pclass) +H5P__close_class(H5P_genclass_t *pclass) { - H5P_genclass_t *pclass = (H5P_genclass_t *)_pclass; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 075eae0..157e34a 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -165,7 +165,7 @@ H5_DLL herr_t H5P__unregister(H5P_genclass_t *pclass, const char *name); H5_DLL char * H5P__get_class_path(H5P_genclass_t *pclass); H5_DLL H5P_genclass_t *H5P__open_class_path(const char *path); H5_DLL H5P_genclass_t *H5P__get_class_parent(const H5P_genclass_t *pclass); -H5_DLL herr_t H5P__close_class(void *_pclass); +H5_DLL herr_t H5P__close_class(H5P_genclass_t *pclass); H5_DLL H5P_genprop_t *H5P__find_prop_plist(const H5P_genplist_t *plist, const char *name); H5_DLL hid_t H5P__new_plist_of_type(H5P_plist_type_t type); diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 926b5ca..ef9ad46 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -160,7 +160,7 @@ struct H5VL_connector_prop_t; H5_DLL herr_t H5P_init(void); /* Internal versions of API routines */ -H5_DLL herr_t H5P_close(void *_plist); +H5_DLL herr_t H5P_close(H5P_genplist_t *plist); H5_DLL hid_t H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref); H5_DLL hid_t H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref); H5_DLL herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value); diff --git a/src/H5S.c b/src/H5S.c index a9a0119..a03b58a 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -44,6 +44,7 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5S__close_cb(void *space, void **request); static htri_t H5S__is_simple(const H5S_t *sdim); /*****************************/ @@ -81,18 +82,18 @@ H5FL_ARR_DEFINE(hsize_t, H5S_MAX_RANK); /* Dataspace ID class */ static const H5I_class_t H5I_DATASPACE_CLS[1] = {{ - H5I_DATASPACE, /* ID class value */ - 0, /* Class flags */ - 2, /* # of reserved IDs for class */ - (H5I_free_t)H5S_close /* Callback routine for closing objects of this class */ + H5I_DATASPACE, /* ID class value */ + 0, /* Class flags */ + 2, /* # of reserved IDs for class */ + (H5I_free_t)H5S__close_cb /* Callback routine for closing objects of this class */ }}; /* Dataspace selection iterator ID class */ static const H5I_class_t H5I_SPACE_SEL_ITER_CLS[1] = {{ - H5I_SPACE_SEL_ITER, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5S_sel_iter_close /* Callback routine for closing objects of this class */ + H5I_SPACE_SEL_ITER, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5S__sel_iter_close_cb /* Callback routine for closing objects of this class */ }}; /* Flag indicating "top" of interface has been initialized */ @@ -222,6 +223,37 @@ H5S_term_package(void) FUNC_LEAVE_NOAPI(n) } /* end H5S_term_package() */ +/*------------------------------------------------------------------------- + * Function: H5S__close_cb + * + * Purpose: Called when the ref count reaches zero on a dataspace's ID + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__close_cb(void *_space, void H5_ATTR_UNUSED **request) +{ + H5S_t *space = (H5S_t *)_space; /* The dataspace to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(space); + + /* Close the dataspace object */ + if (H5S_close(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CLOSEERROR, FAIL, "unable to close dataspace"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__close_cb() */ + /*-------------------------------------------------------------------------- NAME H5S_get_validiated_dataspace diff --git a/src/H5Spkg.h b/src/H5Spkg.h index adb528e..b744a6a 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -392,6 +392,9 @@ H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space, const H5 const H5S_t *src_intersect_space, H5S_t *proj_space, hbool_t share_space); +/* Operations on selection iterators */ +H5_DLL herr_t H5S__sel_iter_close_cb(H5S_sel_iter_t *_sel_iter, void **request); + /* Testing functions */ #ifdef H5S_TESTING H5_DLL herr_t H5S__get_rebuild_status_test(hid_t space_id, H5S_diminfo_valid_t *status1, diff --git a/src/H5Sselect.c b/src/H5Sselect.c index f1a6fc1..b3f63b0 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -3140,6 +3140,37 @@ done: } /* end H5Ssel_iter_reset() */ /*------------------------------------------------------------------------- + * Function: H5S__sel_iter_close_cb + * + * Purpose: Called when the ref count reaches zero on a selection iterator's ID + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5S__sel_iter_close_cb(H5S_sel_iter_t *_sel_iter, void H5_ATTR_UNUSED **request) +{ + H5S_sel_iter_t *sel_iter = (H5S_sel_iter_t *)_sel_iter; /* The selection iterator to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(sel_iter); + + /* Close the selection iterator object */ + if (H5S_sel_iter_close(sel_iter) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CLOSEERROR, FAIL, "unable to close selection iterator"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__sel_iter_close_cb() */ + +/*------------------------------------------------------------------------- * Function: H5S_sel_iter_close * * Purpose: Releases a dataspace selection iterator and its memory. diff --git a/src/H5T.c b/src/H5T.c index 2528760..7a81542 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -346,7 +346,7 @@ static herr_t H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t static herr_t H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_conv_t func); static htri_t H5T__compiler_conv(H5T_t *src, H5T_t *dst); static herr_t H5T__set_size(H5T_t *dt, size_t size); -static herr_t H5T__close_cb(H5T_t *dt); +static herr_t H5T__close_cb(H5T_t *dt, void **request); static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv); static hbool_t H5T__detect_vlen_ref(const H5T_t *dt); @@ -1775,7 +1775,7 @@ H5T_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5T__close_cb(H5T_t *dt) +H5T__close_cb(H5T_t *dt, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1790,7 +1790,7 @@ H5T__close_cb(H5T_t *dt) */ if (NULL != dt->vol_obj) { /* Close the connector-managed datatype data */ - if (H5VL_datatype_close(dt->vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_datatype_close(dt->vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close datatype") /* Free the VOL object */ diff --git a/src/H5VLint.c b/src/H5VLint.c index b92c16a..10df59a 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -86,7 +86,7 @@ typedef struct { /********************/ /* Local Prototypes */ /********************/ -static herr_t H5VL__free_cls(H5VL_class_t *cls); +static herr_t H5VL__free_cls(H5VL_class_t *cls, void **request); static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); static herr_t H5VL__set_def_conn(void); static void * H5VL__wrap_obj(void *obj, H5I_type_t obj_type); @@ -289,7 +289,7 @@ H5VL_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5VL__free_cls(H5VL_class_t *cls) +H5VL__free_cls(H5VL_class_t *cls, void H5_ATTR_UNUSED **request) { herr_t ret_value = SUCCEED; diff --git a/test/tid.c b/test/tid.c index fe458dd..b3bef52 100644 --- a/test/tid.c +++ b/test/tid.c @@ -20,7 +20,7 @@ #include "H5Ipkg.h" static herr_t -free_wrapper(void *p) +free_wrapper(void *p, void **_ctx) { HDfree(p); return SUCCEED; @@ -615,7 +615,7 @@ typedef struct rct_obj_t { * master list of objects. */ static herr_t -rct_free_cb(void *_obj) +rct_free_cb(void *_obj, void **_ctx) { rct_obj_t * obj = (rct_obj_t *)_obj; long remove_nth; -- cgit v0.12