diff options
author | Dana Robinson <43805+derobins@users.noreply.github.com> | 2021-05-28 14:10:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-28 14:10:51 (GMT) |
commit | 2ddf5fbd92ebdb0d59e208d88f159eec8a1ffbf8 (patch) | |
tree | 40975e0846d101360a838d42e16f4687fed77f4a /src/H5A.c | |
parent | e22687912dbc6fcf4fff57e86e2cd5d75c81f81e (diff) | |
download | hdf5-2ddf5fbd92ebdb0d59e208d88f159eec8a1ffbf8.zip hdf5-2ddf5fbd92ebdb0d59e208d88f159eec8a1ffbf8.tar.gz hdf5-2ddf5fbd92ebdb0d59e208d88f159eec8a1ffbf8.tar.bz2 |
Much normalization with develop (#701)
* Brings CMake updates from develop
* Brings reduction in pedantic casts from develop
* Purges UFAIL from the library (#637)
* Committing clang-format changes
* Purges UFAIL from the library
* H5HL_insert change requested in PR
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
* Removes gratuitous (double)x.yF casts (#632)
* Committing clang-format changes
* Removes gratuitous (double)x.yF casts
* Committing clang-format changes
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
* Committing clang-format changes
* Cleans up a const warning left over from previous constification (#633)
* Committing clang-format changes
* Adds consts to a few global variables
* Cleans up a const warning left over from previous constification
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
* Formatted source
* Bring over some VOL registration changes
* VOL cleanup
* H5VL_request_status_t substitutions
* H5F.c cleanup
* Minor API tweaks from develop
* Moves H5G package init/teardown to H5Gint.c
* H5G cleanup
* H5M cleanup
* H5SM cleanup
* H5T cleanup
* H5R cleanup
* H5Lpublic.h cleanup
* H5L cleanup
* H5O cleanup
* H5A, H5CS, and H5AC cleanup
* Moved H5A init/teardown code to H5Aint.c
* Moves H5D I/O functions to H5D.c
* H5D cleanup
* Misc minor cleanup
* H5P close cleanup
* H5Tpublic.h cleanup
* Fixes err_compat test
* H5PLpublic.h cleanup
* Updates H5Ppublic.h
* H5Fpublic.h updates
* H5A.c cleanup
* Brings over H5Aexists and related changes
* Brings CMake shell testing changes from develop
* Close callback changes
* H5R and H5Tcommit normalization
* err_compat test works now
* H5O tweaks
* Updates VOL registration code
* Brings over H5VL_create_object
* H5Tconv.c reformatting
* H5T.c tweaks
* Brings datatype and reference updates from develop
* Brings VOL plugin loading changes from develop
* Brings event sets from develop
* Brings async functions over
* Tools changes
* Brings over many tools changes from develop
* Brings VOL flags from develop
* Fixes h5dump double/float tests
* Updates h5repack tests
* Brings h5diff test changes from develop
* Last h5dump changes
* Brings test changes from develop
* Committing clang-format changes
* Tidied h5_testing()
* Brings chunk iteration code + misc from develop
* Updates vds test
* Enables external link parallel test
* Brings updated property lists from develop
* H5G changes from develop
* H5MF cleanup
* Brings vfd_swmr test back into CMake
* Updates threadsafe test
* Updates plist test
* Brings recent changes from develop
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Diffstat (limited to 'src/H5A.c')
-rw-r--r-- | src/H5A.c | 1663 |
1 files changed, 1211 insertions, 452 deletions
@@ -25,6 +25,7 @@ #include "H5Apkg.h" /* Attributes */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ @@ -40,13 +41,6 @@ /* Local Typedefs */ /******************/ -/* Object header iterator callbacks */ -/* Data structure for callback for locating the index by name */ -typedef struct H5A_iter_cb1 { - const char *name; - int idx; -} H5A_iter_cb1; - /********************/ /* Package Typedefs */ /********************/ @@ -55,13 +49,49 @@ typedef struct H5A_iter_cb1 { /* Local Prototypes */ /********************/ +/* Helper routines for sync/async API calls */ +static hid_t H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, + void **token_ptr); +static hid_t H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, + hid_t acpl_id, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t aapl_id, void **token_ptr); +static hid_t H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, + hid_t aapl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name, + const char *new_name, void **token_ptr); +static herr_t H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_attr_name, + const char *new_attr_name, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hbool_t *attr_exists, void **token_ptr); +static herr_t H5A__exists_api_common(hid_t obj_id, const char *attr_name, hbool_t *attr_exists, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__exists_by_name_api_common(hid_t obj_id, const char *obj_name, const char *attr_name, + hbool_t *attr_exists, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); + /*********************/ /* Package Variables */ /*********************/ -/* Package initialization variable */ -hbool_t H5_PKG_INIT_VAR = FALSE; - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -70,159 +100,94 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Local Variables */ /*******************/ -/* Declare the free lists of H5A_t */ -H5FL_DEFINE(H5A_t); - -/* Declare the free lists for H5A_shared_t's */ -H5FL_DEFINE(H5A_shared_t); - -/* Declare a free list to manage blocks of type conversion data */ -H5FL_BLK_DEFINE(attr_buf); - -/* Attribute ID class */ -static const H5I_class_t H5I_ATTR_CLS[1] = {{ - H5I_ATTR, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5A__close_cb /* Callback routine for closing objects of this class */ -}}; - -/* Flag indicating "top" of interface has been initialized */ -static hbool_t H5A_top_package_initialize_s = FALSE; - -/*------------------------------------------------------------------------- - * Function: H5A_init +/*-------------------------------------------------------------------------- + * Function: H5A__create_common * - * Purpose: Initialize the interface from some other layer. + * Purpose: This is the common function for creating HDF5 datasets. * - * Return: Success: non-negative + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID * - * Failure: negative *------------------------------------------------------------------------- */ -herr_t -H5A_init(void) +static hid_t +H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, void **token_ptr) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - /* FUNC_ENTER() does all the work */ + void *attr = NULL; /* Attribute created */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_init() */ + FUNC_ENTER_STATIC -/*-------------------------------------------------------------------------- -NAME - H5A__init_package -- Initialize interface-specific information -USAGE - herr_t H5A__init_package() + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + HDassert(attr_name); -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. - ---------------------------------------------------------------------------*/ -herr_t -H5A__init_package(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - /* - * Create attribute ID type. - */ - if (H5I_register_type(H5I_ATTR_CLS) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize interface") + /* Create the attribute */ + if (NULL == (attr = H5VL_attr_create(vol_obj, loc_params, attr_name, type_id, space_id, acpl_id, aapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute") - /* Mark "top" of interface as initialized, too */ - H5A_top_package_initialize_s = TRUE; + /* Register the new attribute and get an ID for it */ + if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID") done: + /* Cleanup on failure */ + if (H5I_INVALID_HID == ret_value) + if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A__init_package() */ +} /* H5A__create_common() */ /*-------------------------------------------------------------------------- - NAME - H5A_top_term_package - PURPOSE - Terminate various H5A objects - USAGE - void H5A_top_term_package() - RETURNS - DESCRIPTION - Release IDs for the atom group, deferring full interface shutdown - until later (in H5A_term_package). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Can't report errors... - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -int -H5A_top_term_package(void) + * Function: H5A__create_api_common + * + * Purpose: This is the common function for creating HDF5 attributes + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, + hid_t aapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - int n = 0; - - FUNC_ENTER_NOAPI_NOINIT_NOERR + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - if (H5A_top_package_initialize_s) { - if (H5I_nmembers(H5I_ATTR) > 0) { - (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE); - n++; /*H5I*/ - } /* end if */ + FUNC_ENTER_STATIC - /* Mark closed */ - if (0 == n) - H5A_top_package_initialize_s = FALSE; - } /* end if */ - - FUNC_LEAVE_NOAPI(n) -} /* H5A_top_term_package() */ - -/*-------------------------------------------------------------------------- - NAME - H5A_term_package - PURPOSE - Terminate various H5A objects - USAGE - void H5A_term_package() - RETURNS - DESCRIPTION - Release any other resources allocated. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Can't report errors... - - Finishes shutting down the interface, after H5A_top_term_package() - is called - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -int -H5A_term_package(void) -{ - int n = 0; - - FUNC_ENTER_NOAPI_NOINIT_NOERR + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") + if (!attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be NULL") + if (!*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string") - if (H5_PKG_INIT_VAR) { - /* Sanity checks */ - HDassert(0 == H5I_nmembers(H5I_ATTR)); - HDassert(FALSE == H5A_top_package_initialize_s); + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, TRUE, &aapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") - /* Destroy the attribute object id group */ - n += (H5I_dec_type_ref(H5I_ATTR) > 0); + /* Get correct property list */ + if (H5P_DEFAULT == acpl_id) + acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; - /* Mark closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; - } /* end if */ + /* Create the attribute */ + if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id, + aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute") - FUNC_LEAVE_NOAPI(n) -} /* H5A_term_package() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__create_api_common() */ /*-------------------------------------------------------------------------- * Function: H5Acreate2 @@ -260,14 +225,91 @@ H5A_term_package(void) hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id) { - void * attr = NULL; /* Attribute created */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id); + /* Create the attribute synchronously */ + if ((ret_value = + H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate2() */ + +/*-------------------------------------------------------------------------- + * Function: H5Acreate_sync + * + * Purpose: Asynchronous version of H5Acreate + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Acreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE10("i", "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name, type_id, space_id, + acpl_id, aapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the attribute asynchronously */ + if ((ret_value = H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, token_ptr, + &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_async() */ + +/*-------------------------------------------------------------------------- + * Function: H5A__create_by_name_api_common + * + * Purpose: This is the common function for creating HDF5 attributes by name + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, + hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") @@ -276,39 +318,27 @@ H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, h if (!*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string") - /* Get correct property list */ - if (H5P_DEFAULT == acpl_id) - acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* Get correct property list */ + if (H5P_DEFAULT == acpl_id) + acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; /* Create the attribute */ - if (NULL == (attr = H5VL_attr_create(vol_obj, &loc_params, attr_name, type_id, space_id, acpl_id, aapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute") - - /* Register the new attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id, + aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute") done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* H5Acreate2() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__create_by_name_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -344,50 +374,99 @@ hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id) { - void * attr = NULL; /* attr object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE8("i", "i*s*siiiii", loc_id, obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id); - /* Check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name") - if (!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name") + /* Create the attribute synchronously */ + if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id, + aapl_id, lapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute") - /* Get correct property list */ - if (H5P_DEFAULT == acpl_id) - acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_by_name() */ - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info") +/*-------------------------------------------------------------------------- + * Function: H5Acreate_by_name_async + * + * Purpose: Asynchronous version of H5Acreate_by_name + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Acreate_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id, + hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - /* Set up location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.obj_type = H5I_get_type(loc_id); - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE12("i", "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id, obj_name, attr_name, type_id, + space_id, acpl_id, aapl_id, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the attribute asynchronously */ + if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id, + aapl_id, lapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE12(FUNC, "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id, obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_by_name_async() */ - /* Create the attribute */ - if (NULL == (attr = H5VL_attr_create(vol_obj, &loc_params, attr_name, type_id, space_id, acpl_id, aapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute") +/*------------------------------------------------------------------------- + * Function: H5A__open_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id, + void **token_ptr) +{ + void *attr = NULL; /* attr object from VOL connector */ + hid_t ret_value = H5I_INVALID_HID; - /* Register the new attribute and get an ID for it */ + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + + /* Open the attribute */ + if (NULL == + (attr = H5VL_attr_open(vol_obj, loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name) + + /* Register the attribute and get an ID for it */ if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID") done: /* Cleanup on failure */ @@ -395,8 +474,50 @@ done: if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - FUNC_LEAVE_API(ret_value) -} /* H5Acreate_by_name() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_common() */ + +/*------------------------------------------------------------------------- + * Function: H5A__open_api_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") + if (!attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") + if (!*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") + + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, FALSE, &aapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + + /* Open the attribute */ + if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -420,51 +541,109 @@ done: hid_t H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id) { - void * attr = NULL; /* attr object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "i*si", loc_id, attr_name, aapl_id); + /* Open the attribute synchronously */ + if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aopen() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Aopen_async + * PURPOSE + * Asynchronous version of H5Aopen + * + * RETURNS + * ID of attribute on success, H5I_INVALID_HID on failure + * + *--------------------------------------------------------------------------*/ +hid_t +H5Aopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *attr_name, hid_t aapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name, aapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute asynchronously */ + if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name, aapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aopen_async() */ + +/*------------------------------------------------------------------------- + * Function: H5A__open_by_name_api_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_STATIC + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") - if (!attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") - if (!*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") + if (!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name") - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Verify access property list and set up collective metadata if appropriate */ + if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") /* Open the attribute */ - if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name) - /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") - done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* H5Aopen() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_by_name_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -490,55 +669,116 @@ done: hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id) { - void * attr = NULL; /* attr object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE5("i", "i*s*sii", loc_id, obj_name, attr_name, aapl_id, lapl_id); + /* Open the attribute by name asynchronously */ + if ((ret_value = + H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aopen_by_name() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Aopen_by_name_async + * PURPOSE + * Asynchronous version of H5Aopen_by_name + * + * RETURNS + * ID of attribute on success, H5I_INVALID_HID on failure + * + *--------------------------------------------------------------------------*/ +hid_t +H5Aopen_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE9("i", "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name, attr_name, aapl_id, + lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute by name asynchronously */ + if ((ret_value = H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, token_ptr, + &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name, attr_name, aapl_id, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aopen_by_name_async() */ + +/*------------------------------------------------------------------------- + * Function: H5A__open_by_idx_api_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t aapl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_STATIC + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") if (!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name") - if (!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name") + if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified") + if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") + + /* Set up object access arguments */ + if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, + &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info") - - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Open the attribute */ - if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "can't open attribute") - - /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, NULL, aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute") done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* end H5Aopen_by_name() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_by_idx_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -568,60 +808,104 @@ hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id) { - void * attr = NULL; /* Attribute opened */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE7("i", "i*sIiIohii", loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id); - /* Check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name") - if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified") - if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") + /* Open the attribute by idx synchronously */ + if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, NULL, + NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info") +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aopen_by_idx() */ - /* Fill in location struct parameters */ - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +/*-------------------------------------------------------------------------- + * NAME + * H5Aopen_by_idx_async + * PURPOSE + * Asynchronous version of H5Aopen_by_idx + * + * RETURNS + * ID of attribute on success, H5I_INVALID_HID on failure + * + *--------------------------------------------------------------------------*/ +hid_t +H5Aopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + hid_t aapl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE11("i", "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id, obj_name, idx_type, order, n, + aapl_id, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute by idx asynchronously */ + if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE11(FUNC, "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ - /* Open the attribute */ - if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, NULL, aapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aopen_by_idx_async() */ - /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") +/*-------------------------------------------------------------------------- + NAME + H5A__write_api_common + PURPOSE + Common helper routine for sync/async dataset write operations. + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ -done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_ENTER_STATIC - FUNC_LEAVE_API(ret_value) -} /* H5Aopen_by_idx() */ + /* Check arguments */ + if (H5I_DATATYPE != H5I_get_type(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if (NULL == buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL") + + /* Get attribute pointer */ + if (H5VL_setup_args(attr_id, H5I_ATTR, vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute") + + /* Write the attribute data */ + if (H5VL_attr_write(*vol_obj_ptr, type_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__write_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -642,31 +926,94 @@ done: herr_t H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf) { - H5VL_object_t *vol_obj; /* Attribute object for ID */ - herr_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ii*x", attr_id, dtype_id, buf); + /* Synchronously write the data */ + if (H5A__write_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't synchronously write data") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Awrite() */ + +/*-------------------------------------------------------------------------- + NAME + H5Awrite_async + PURPOSE + Asynchronous version of H5Awrite + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +herr_t +H5Awrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id, + const void *buf, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for attr_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously write the data */ + if (H5A__write_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't asynchronously write data") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Awrite_async() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__read_api_common + * PURPOSE + * Common helper routine for sync/async attribute read operations. + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") if (H5I_DATATYPE != H5I_get_type(dtype_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if (NULL == buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(attr_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read") + /* Get attribute object pointer */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - /* Write the attribute data */ - if ((ret_value = H5VL_attr_write(vol_obj, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute") + /* Read the attribute data */ + if (H5VL_attr_read(*vol_obj_ptr, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute") done: - FUNC_LEAVE_API(ret_value) -} /* H5Awrite() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__read_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -685,31 +1032,62 @@ done: This function reads a complete attribute from disk. --------------------------------------------------------------------------*/ herr_t -H5Aread(hid_t attr_id, hid_t dtype_id, void *buf) +H5Aread(hid_t attr_id, hid_t dtype_id, void *buf /*out*/) { - H5VL_object_t *vol_obj; /* Attribute object for ID */ - herr_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("e", "ii*x", attr_id, dtype_id, buf); - - /* Check arguments */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - if (H5I_DATATYPE != H5I_get_type(dtype_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - if (NULL == buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL") + H5TRACE3("e", "iix", attr_id, dtype_id, buf); - /* Read the attribute data */ - if ((ret_value = H5VL_attr_read(vol_obj, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute") + /* Synchronously read the data */ + if (H5A__read_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't synchronously read data") done: FUNC_LEAVE_API(ret_value) } /* H5Aread() */ /*-------------------------------------------------------------------------- + * NAME + * H5Aread_async + * PURPOSE + * Asynchronous version of H5Aread + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id, + void *buf, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for attr_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously read the data */ + if (H5A__read_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't asynchronously read data") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aread_async() */ + +/*-------------------------------------------------------------------------- NAME H5Aget_space PURPOSE @@ -849,14 +1227,14 @@ done: properly terminate the string. --------------------------------------------------------------------------*/ ssize_t -H5Aget_name(hid_t attr_id, size_t buf_size, char *buf) +H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/) { H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ H5VL_loc_params_t loc_params; ssize_t ret_value = -1; FUNC_ENTER_API((-1)) - H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf); + H5TRACE3("Zs", "izx", attr_id, buf_size, buf); /* check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) @@ -995,16 +1373,16 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Aget_info(hid_t attr_id, H5A_info_t *ainfo) +H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/) { H5VL_object_t * vol_obj; H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*Ai", attr_id, ainfo); + H5TRACE2("e", "ix", attr_id, ainfo); - /* Check arguments */ + /* Check args */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") if (!ainfo) @@ -1036,7 +1414,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo, +H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo /*out*/, hid_t lapl_id) { H5VL_object_t * vol_obj; @@ -1044,7 +1422,7 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "i*s*s*Aii", loc_id, obj_name, attr_name, ainfo, lapl_id); + H5TRACE5("e", "i*s*sxi", loc_id, obj_name, attr_name, ainfo, lapl_id); /* Check args */ if (H5I_ATTR == H5I_get_type(loc_id)) @@ -1094,14 +1472,14 @@ done: */ herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - H5A_info_t *ainfo, hid_t lapl_id) + H5A_info_t *ainfo /*out*/, hid_t lapl_id) { H5VL_object_t * vol_obj; H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE7("e", "i*sIiIoh*Aii", loc_id, obj_name, idx_type, order, n, ainfo, lapl_id); + H5TRACE7("e", "i*sIiIohxi", loc_id, obj_name, idx_type, order, n, ainfo, lapl_id); /* Check args */ if (H5I_ATTR == H5I_get_type(loc_id)) @@ -1140,12 +1518,91 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_info_by_idx() */ +/*-------------------------------------------------------------------------- + NAME + H5A__rename_common + PURPOSE + Common helper routine for sync/async attribute rename operations + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name, + const char *new_name, void **token_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + HDassert(old_name); + HDassert(new_name); + + /* Avoid thrashing things if the names are the same */ + if (HDstrcmp(old_name, new_name) != 0) + /* Rename the attribute */ + if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, token_ptr, + old_name, new_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute from '%s' to '%s'", old_name, + new_name) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__rename_common() */ + +/*-------------------------------------------------------------------------- + NAME + H5A__rename_api_common + PURPOSE + Common helper routine for sync/async attribute rename operations + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if (!old_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL") + if (!*old_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be an empty string") + if (!new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be NULL") + if (!*new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string") + + /* Set up object access arguments */ + if (H5VL_setup_loc_args(loc_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Rename the attribute */ + if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__rename_api_common() */ + /*------------------------------------------------------------------------- * Function: H5Arename * * Purpose: Rename an attribute * - * Return: SUCCEED/FAIL + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Raymond Lu * October 23, 2002 @@ -1160,9 +1617,78 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name) FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*s*s", loc_id, old_name, new_name); - /* check arguments */ + /* Synchronously rename the attribute */ + if (H5A__rename_api_common(loc_id, old_name, new_name, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Arename() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Arename_async + * PURPOSE + * Asynchronous version of H5Arename + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Arename_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *old_name, const char *new_name, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name, new_name, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously rename the attribute */ + if (H5A__rename_api_common(loc_id, old_name, new_name, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name, new_name, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Arename_async() */ + +/*-------------------------------------------------------------------------- + NAME + H5A__rename_by_name_api_common + PURPOSE + Common helper routine for sync/async attribute rename operations + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_name, const char *new_name, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if (!old_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL") if (!*old_name) @@ -1172,38 +1698,26 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name) if (!*new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string") - /* Avoid thrashing things if the names are the same */ - if (HDstrcmp(old_name, new_name)) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read") - - /* Rename the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, old_name, new_name) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") - } /* end if */ + /* Rename the attribute */ + if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") done: - FUNC_LEAVE_API(ret_value) -} /* H5Arename() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__rename_by_name_api_common() */ /*------------------------------------------------------------------------- * Function: H5Arename_by_name * * Purpose: Rename an attribute * - * Return: SUCCEED/FAIL + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Quincey Koziol * February 20, 2007 @@ -1219,43 +1733,57 @@ H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*s*si", loc_id, obj_name, old_attr_name, new_attr_name, lapl_id); - /* check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") - if (!old_attr_name || !*old_attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no old attribute name") - if (!new_attr_name || !*new_attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new attribute name") - - /* Avoid thrashing things if the names are the same */ - if (HDstrcmp(old_attr_name, new_attr_name)) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Synchronously rename the attribute */ + if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, NULL, NULL) < + 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +done: + FUNC_LEAVE_API(ret_value) +} /* H5Arename_by_name() */ - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") +/*-------------------------------------------------------------------------- + * NAME + * H5Arename_by_name_async + * PURPOSE + * Asynchronous version of H5Arename_by_name + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Arename_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *old_attr_name, const char *new_attr_name, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Rename the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, old_attr_name, new_attr_name) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") - } /* end if */ + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name, old_attr_name, + new_attr_name, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously rename the attribute */ + if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* H5Arename_by_name() */ +} /* H5Arename_by_name_async() */ /*-------------------------------------------------------------------------- NAME @@ -1299,8 +1827,8 @@ done: attribute. --------------------------------------------------------------------------*/ herr_t -H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, - void *op_data) +H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, + H5A_operator2_t op, void *op_data) { H5VL_object_t * vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; @@ -1378,16 +1906,16 @@ done: --------------------------------------------------------------------------*/ herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t *idx, H5A_operator2_t op, void *op_data, hid_t lapl_id) + hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_object_t * vol_obj = NULL; /* Object location */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hAO*xi", loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id); - /* check arguments */ + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") if (!obj_name || !*obj_name) @@ -1590,7 +2118,7 @@ H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_ite if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Delete the attribute through the VOL */ + /* Delete the attribute */ if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") @@ -1619,18 +2147,154 @@ 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 atom (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) } /* H5Aclose() */ /*------------------------------------------------------------------------- + * Function: H5Aclose_async + * + * Purpose: Asynchronous version of H5Aclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Aclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + H5VL_t * connector = NULL; /* VOL connector */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, attr_id, es_id); + + /* Check arguments */ + if (H5I_ATTR != H5I_get_type(attr_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a attribute ID") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Get attribute object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(attr_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute") + + /* Increase connector's refcount, so it doesn't get closed if closing + * the attribute closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Decrement the counter on the attribute ID. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref_async(attr_id, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, attr_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* H5Aclose_async() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__exists_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hbool_t *attr_exists, void **token_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + + /* Check arguments */ + if (!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + + /* Check if the attribute exists */ + if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, + attr_name, attr_exists) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__exists_common() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__exists_api_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__exists_api_common(hid_t obj_id, const char *attr_name, hbool_t *attr_exists, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(obj_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if (!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + if (NULL == attr_exists) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence") + + /* Set up object access arguments */ + if (H5VL_setup_self_args(obj_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Check if the attribute exists */ + if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__exists_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Aexists * * Purpose: Checks if an attribute with a given name exists on an opened @@ -1647,34 +2311,105 @@ done: htri_t H5Aexists(hid_t obj_id, const char *attr_name) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - htri_t ret_value; /* Return value */ + hbool_t exists; /* Flag for attribute existance */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("t", "i*s", obj_id, attr_name); + /* Synchronously check if an attribute exists */ + exists = FALSE; + if (H5A__exists_api_common(obj_id, attr_name, &exists, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") + + /* Set return value */ + ret_value = (htri_t)exists; + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Aexists_async + * PURPOSE + * Asynchronous version of H5Aexists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Aexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, + const char *attr_name, hbool_t *attr_exists, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name, attr_exists, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously check if an attribute exists */ + if (H5A__exists_api_common(obj_id, attr_name, attr_exists, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously check if attribute exists") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name, attr_exists, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists_async() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__exists_by_name_api_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__exists_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, + hbool_t *attr_exists, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ - if (H5I_ATTR == H5I_get_type(obj_id)) + if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") if (!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + if (NULL == attr_exists) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence") - /* get the object */ - if (NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(obj_id); + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Check if the attribute exists */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - attr_name, &ret_value) < 0) + if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") done: - FUNC_LEAVE_API(ret_value) -} /* H5Aexists() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__exists_by_name_api_common() */ /*------------------------------------------------------------------------- * Function: H5Aexists_by_name @@ -1682,7 +2417,7 @@ done: * Purpose: Checks if an attribute with a given name exists on an object. * * Return: Success: TRUE/FALSE - * Failure: Negative + * Failure: Negative * * Programmer: Quincey Koziol * Thursday, November 1, 2007 @@ -1692,39 +2427,63 @@ done: htri_t H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - htri_t ret_value; /* Return value */ + hbool_t exists; /* Flag for attribute existance */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("t", "i*s*si", loc_id, obj_name, attr_name, lapl_id); - /* check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") - if (!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + /* Synchronously check if an attribute exists */ + exists = FALSE; + if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, &exists, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set return value */ + ret_value = (htri_t)exists; - /* get the object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists_by_name() */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +/*-------------------------------------------------------------------------- + * NAME + * H5Aexists_by_name_async + * PURPOSE + * Asynchronous version of H5Aexists_by_name + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Aexists_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *attr_name, hbool_t *attr_exists, hid_t lapl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Check existence of attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - attr_name, &ret_value) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name, attr_name, attr_exists, + lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously check if an attribute exists */ + if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, attr_exists, lapl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name, attr_name, attr_exists, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* H5Aexists_by_name() */ +} /* H5Aexists_by_name_async() */ |